Krita Source Code Documentation
Loading...
Searching...
No Matches
KisPopupButton Class Reference

#include <KisPopupButton.h>

+ Inheritance diagram for KisPopupButton:

Classes

struct  Private
 

Public Slots

void hidePopupWidget ()
 
void setPopupWidgetDetached (bool detach)
 
void setPopupWidgetVisible (bool visible)
 
void showPopupWidget ()
 

Signals

void sigPopupWidgetShown ()
 

Public Member Functions

void adjustPosition ()
 adjustPosition adjusts the position of the popup widget based on the position of this button and the size of the widget
 
bool isPopupWidgetVisible ()
 
 KisPopupButton (QWidget *parent)
 
void setArrowVisible (bool v)
 
void setPopupWidget (QWidget *widget)
 
void setPopupWidgetWidth (int w)
 
 ~KisPopupButton () override
 

Protected Member Functions

void paintEvent (QPaintEvent *event) override
 
void paintPopupArrow ()
 

Private Slots

void slotMenuAboutToHide ()
 

Private Attributes

Private *const m_d
 

Detailed Description

This class is a convenience class for a button that when clicked displays a popup widget.

Definition at line 18 of file KisPopupButton.h.

Constructor & Destructor Documentation

◆ KisPopupButton()

KisPopupButton::KisPopupButton ( QWidget * parent)

Definition at line 106 of file KisPopupButton.cpp.

107 : QToolButton(parent)
108 , m_d(new Private)
109{
110 setObjectName("KisPopupButton");
111 connect(this, SIGNAL(released()), SLOT(showPopupWidget()));
112}
Private *const m_d

References showPopupWidget().

◆ ~KisPopupButton()

KisPopupButton::~KisPopupButton ( )
override

Definition at line 114 of file KisPopupButton.cpp.

115{
116 delete m_d->frame;
117 delete m_d;
118}
QPointer< KisPopupButtonFrame > frame

References KisPopupButton::Private::frame, and m_d.

Member Function Documentation

◆ adjustPosition()

void KisPopupButton::adjustPosition ( )

adjustPosition adjusts the position of the popup widget based on the position of this button and the size of the widget

Definition at line 231 of file KisPopupButton.cpp.

232{
233 QScreen *currentScreen = nullptr;
234 auto getCurrentScreen = [this, &currentScreen] {
235 if (!currentScreen) {
236 QWindow *mainWinHandle = window()->windowHandle();
237 if (mainWinHandle) {
238 currentScreen = mainWinHandle->screen();
239 } else {
240 currentScreen = QApplication::primaryScreen();
241 }
242 }
243 return currentScreen;
244 };
245
246 // If popup is not detached, or if its detached geometry hasn't been set,
247 // we first move the popup to the "current" screen.
249 QWindow *winHandle = m_d->frame->windowHandle();
250 if (winHandle) {
251 winHandle->setScreen(getCurrentScreen());
252 }
253 }
254
255 // Attach to the button if it's visible, else attach to the cursor.
256 QPoint pos = this->isVisible() ? this->mapToGlobal(QPoint(0, this->size().height())) : QCursor().pos();
257 QSize popSize = m_d->popupWidget->size();
258 QRect popupRect(pos, popSize);
259
260 // Get the available geometry of the screen which contains the popup.
261 QScreen *screen = [this, &getCurrentScreen]() {
262 QWindow *winHandle = m_d->frame->windowHandle();
263 if (winHandle && winHandle->screen()) {
264 return winHandle->screen();
265 }
266 return getCurrentScreen();
267 }();
268 QRect screenRect = screen->availableGeometry();
269 if (m_d->isPopupDetached) {
271 popupRect.moveTo(m_d->frame->geometry().topLeft());
272 } else {
273 popupRect.moveTo(this->window()->geometry().center() - QRect(QPoint(0, 0), popSize).center());
275 }
276 }
277 popupRect = kisEnsureInRect(popupRect, screenRect);
278
279 m_d->frame->setGeometry(popupRect);
280}
QRect kisEnsureInRect(QRect rc, const QRect &bounds)
Definition kis_global.h:291
int size(const Forest< T > &forest)
Definition KisForest.h:1232
QPointer< QWidget > popupWidget

References KisPopupButton::Private::frame, KisPopupButton::Private::isDetachedGeometrySet, KisPopupButton::Private::isPopupDetached, kisEnsureInRect(), m_d, and KisPopupButton::Private::popupWidget.

◆ hidePopupWidget

void KisPopupButton::hidePopupWidget ( )
slot

Definition at line 180 of file KisPopupButton.cpp.

181{
183}
void setPopupWidgetVisible(bool visible)

References setPopupWidgetVisible().

◆ isPopupWidgetVisible()

bool KisPopupButton::isPopupWidgetVisible ( )

Definition at line 205 of file KisPopupButton.cpp.

206{
207 return m_d->popupWidget && m_d->frame->isVisible();
208}

References KisPopupButton::Private::frame, m_d, and KisPopupButton::Private::popupWidget.

◆ paintEvent()

void KisPopupButton::paintEvent ( QPaintEvent * event)
overrideprotected

Definition at line 210 of file KisPopupButton.cpp.

211{
212 QToolButton::paintEvent(event);
213 if (m_d->arrowVisible) {
215 }
216}

References KisPopupButton::Private::arrowVisible, m_d, and paintPopupArrow().

◆ paintPopupArrow()

void KisPopupButton::paintPopupArrow ( )
protected

Definition at line 218 of file KisPopupButton.cpp.

219{
220 QStylePainter p(this);
221 QStyleOption option;
222 option.rect = QRect(rect().right() - 15, rect().bottom() - 15, 14, 14);
223 option.palette = palette();
224 option.palette.setBrush(QPalette::ButtonText, Qt::black); // Force color to black
225 option.state = QStyle::State_Enabled;
226 p.setBrush(Qt::black); // work around some theme that don't use QPalette::ButtonText like they should, but instead the QPainter brushes and pen
227 p.setPen(Qt::black);
228 p.drawPrimitive(QStyle::PE_IndicatorArrowDown, option);
229}
const Params2D p
rgba palette[MAX_PALETTE]
Definition palette.c:35

References p, and palette.

◆ setArrowVisible()

void KisPopupButton::setArrowVisible ( bool v)

This function allows to show or hide the arrow.

Parameters
vset to true to draw the arrow, else set to false

Definition at line 282 of file KisPopupButton.cpp.

283{
284 if (v) {
285 m_d->arrowVisible = true;
286 } else {
287 m_d->arrowVisible = false;
288 }
289}
qreal v

References KisPopupButton::Private::arrowVisible, m_d, and v.

◆ setPopupWidget()

void KisPopupButton::setPopupWidget ( QWidget * widget)

Set the popup widget, the KisPopupButton becomes the owner and parent of the widget.

Definition at line 137 of file KisPopupButton.cpp.

138{
139 if (widget) {
140 delete m_d->frame;
141
142 // Bit wonky to assign a popup menu to a popup widget, so they need
143 // extra coddling to make them work properly.
144 QMenu *menu = qobject_cast<QMenu *>(widget);
145 m_d->frame = new KisPopupButtonFrame(this->window(), m_d->isPopupDetached, menu);
146 m_d->frame->setWindowTitle(widget->windowTitle());
147
148 m_d->popupWidget = widget;
149
150 m_d->frame->layout()->addWidget(m_d->popupWidget);
151
152 if (menu) {
153 // The menu may decide to hide itself in response to user input.
154 // Compensate for that by catching the situation where we'd hide
155 // the menu while the frame is still up and show it again.
156 connect(menu, &QMenu::aboutToHide, this, &KisPopupButton::slotMenuAboutToHide);
157 // If the menu still hides itself somehow, make it show up again.
158 connect(this, &KisPopupButton::sigPopupWidgetShown, menu, &QMenu::show);
159 }
160 }
161}
void sigPopupWidgetShown()

References KisPopupButton::Private::frame, KisPopupButton::Private::isPopupDetached, m_d, KisPopupButton::Private::popupWidget, sigPopupWidgetShown(), and slotMenuAboutToHide().

◆ setPopupWidgetDetached

void KisPopupButton::setPopupWidgetDetached ( bool detach)
slot

Set whether the popup is detached as a dialog.

Parameters
vset to true to cause the popup to be detached

Definition at line 120 of file KisPopupButton.cpp.

121{
122 m_d->isPopupDetached = detach;
123 if (m_d->frame) {
124 bool wasVisible = isPopupWidgetVisible();
125 m_d->frame->setDetached(detach, qobject_cast<QMenu *>(m_d->popupWidget));
126 if (wasVisible) {
127 // Setting the window flags closes the widget, so make it visible again.
129 if (detach) {
131 }
133 }
134 }
135}
void adjustPosition()
adjustPosition adjusts the position of the popup widget based on the position of this button and the ...

References adjustPosition(), KisPopupButton::Private::frame, KisPopupButton::Private::isDetachedGeometrySet, KisPopupButton::Private::isPopupDetached, isPopupWidgetVisible(), m_d, KisPopupButton::Private::popupWidget, and setPopupWidgetVisible().

◆ setPopupWidgetVisible

void KisPopupButton::setPopupWidgetVisible ( bool visible)
slot

Definition at line 185 of file KisPopupButton.cpp.

186{
187 if (m_d->popupWidget) {
188 if (visible) {
189 if (m_d->isPopupDetached) {
190 // Force layout sizing before positioning
191 m_d->popupWidget->adjustSize();
192 m_d->frame->adjustSize();
194 }
195 m_d->frame->raise();
196 m_d->frame->show();
197 m_d->frame->activateWindow();
198 Q_EMIT sigPopupWidgetShown();
199 } else {
200 m_d->frame->setVisible(false);
201 }
202 }
203}

References adjustPosition(), KisPopupButton::Private::frame, KisPopupButton::Private::isPopupDetached, m_d, KisPopupButton::Private::popupWidget, and sigPopupWidgetShown().

◆ setPopupWidgetWidth()

void KisPopupButton::setPopupWidgetWidth ( int w)

Set the width of the popup widget.

Returns
new width of the popup widget

Definition at line 163 of file KisPopupButton.cpp.

164{
165 m_d->frame->resize(w, m_d->frame->height());
166}

References KisPopupButton::Private::frame, and m_d.

◆ showPopupWidget

void KisPopupButton::showPopupWidget ( )
slot

◆ sigPopupWidgetShown

void KisPopupButton::sigPopupWidgetShown ( )
signal

◆ slotMenuAboutToHide

void KisPopupButton::slotMenuAboutToHide ( )
privateslot

Definition at line 291 of file KisPopupButton.cpp.

292{
293 // Menus will hide themselves when clicking on one of their separators,
294 // which just ends up with a blank popup frame. Fight back against this by
295 // showing the menu again if the frame is still up when the menu disappears.
296 if (m_d->popupWidget && m_d->frame->isVisible()) {
297 m_d->popupWidget->show();
298 }
299}

References KisPopupButton::Private::frame, m_d, and KisPopupButton::Private::popupWidget.

Member Data Documentation

◆ m_d

Private* const KisPopupButton::m_d
private

Definition at line 82 of file KisPopupButton.h.


The documentation for this class was generated from the following files: