diff --git a/src/mode/katemodemenulist.h b/src/mode/katemodemenulist.h --- a/src/mode/katemodemenulist.h +++ b/src/mode/katemodemenulist.h @@ -72,14 +72,26 @@ public: /** - * Alignment with respect to the trigger button. - * "Default" is the normal alignment (left alignment in Left-to-right layouts). - * "Inverse" uses right alignment in Left-to-right layouts and left - * alignment in Right-to-left layouts (used in some languages). - * "Left" and "Right" forces the alignment. + * Horizontal Alignment with respect to the trigger button. + * "AlignHDefault" is the normal alignment. + * "AlignHInverse" uses right alignment in Left-to-right layouts and + * left alignmentnin Right-to-left layouts (used in some languages). + * "AlignLeft" and "AlignRight" forces the alignment, regardless of the layout direction. * @see setButton(), QWidget::layoutDirection(), Qt::LayoutDirection */ - enum AlignmentButton { Default, Inverse, Left, Right }; + enum AlignmentHButton { AlignHDefault, AlignHInverse, AlignLeft, AlignRight }; + /** + * Vertical Alignment with respect to the trigger button. + * "AlignVDefault" uses normal alignment (below the button) and "AlignTop" + * forces the alignment above the trigger button. + * @see setButton(), KateStatusBarOpenUpMenu::setVisible() + */ + enum AlignmentVButton { AlignVDefault, AlignTop }; + /** + * Define if the trigger button label must be updated when selecting an item. + * @see setButton() + */ + enum class AutoUpdateTextButton : bool; /** * Search bar position, above or below the list. */ @@ -149,16 +161,16 @@ /** * Set the button that shows this menu. It allows to update the label * of the button and define the alignment of the menu with respect to it. - * This function must be called after QPushButton::setMenu(). + * This function doesn't call QPushButton::setMenu(). * @param button Trigger button. - * @param bAutoUpdateTextButton Determines whether the text of the button should be + * @param positionX Horizontal position of the menu with respect to the trigger button. + * @param positionY Vertical position of the menu with respect to the trigger button. + * @param autoUpdateTextButton Determines whether the text of the button should be * changed when selecting an item from the menu. - * @param position Position of the menu with respect to the trigger button. - * See KateModeMenuList::AlignmentButton. * - * @see AlignmentButton + * @see AlignmentHButton, AlignmentVButton, AutoUpdateTextButton */ - void setButton(QPushButton *button, const bool bAutoUpdateTextButton = false, AlignmentButton position = Inverse); + void setButton(QPushButton *button, AlignmentHButton positionX = AlignHDefault, AlignmentVButton positionY = AlignTop, AutoUpdateTextButton autoUpdateTextButton = AutoUpdateTextButton(false)); /** * Define the size of the list widget, in pixels. @@ -248,8 +260,9 @@ inline void loadEmptyMsg(); AutoScroll m_autoScroll = ScrollToSelectedItem; - AlignmentButton m_position; - bool m_bAutoUpdateTextButton; + AlignmentHButton m_positionX; + AlignmentVButton m_positionY; + AutoUpdateTextButton m_autoUpdateTextButton; QPushButton *m_pushButton = nullptr; QLabel *m_emptyListMsg = nullptr; diff --git a/src/mode/katemodemenulist.cpp b/src/mode/katemodemenulist.cpp --- a/src/mode/katemodemenulist.cpp +++ b/src/mode/katemodemenulist.cpp @@ -285,22 +285,23 @@ return section; } -void KateModeMenuList::setButton(QPushButton *button, const bool bAutoUpdateTextButton, AlignmentButton position) +void KateModeMenuList::setButton(QPushButton *button, AlignmentHButton positionX, AlignmentVButton positionY, AutoUpdateTextButton autoUpdateTextButton) { - if (position == Inverse) { + if (positionX == AlignHInverse) { if (layoutDirection() == Qt::RightToLeft) { - m_position = KateModeMenuList::Left; + m_positionX = KateModeMenuList::AlignLeft; } else { - m_position = KateModeMenuList::Right; + m_positionX = KateModeMenuList::AlignRight; } - } else if (position == Left && layoutDirection() != Qt::RightToLeft) { - m_position = KateModeMenuList::Default; + } else if (positionX == AlignLeft && layoutDirection() != Qt::RightToLeft) { + m_positionX = KateModeMenuList::AlignHDefault; } else { - m_position = position; + m_positionX = positionX; } + m_positionY = positionY; m_pushButton = button; - m_bAutoUpdateTextButton = bAutoUpdateTextButton; + m_autoUpdateTextButton = autoUpdateTextButton; } void KateModeMenuList::setSizeList(const int height, const int width) @@ -331,19 +332,39 @@ // Set the menu position if (m_pushButton && m_pushButton->isVisible()) { - if (m_position == Right) { - // New menu position + /* + * Get vertical position. + * NOTE: In KDE Plasma with Wayland, the reference point of the position + * is the main window, not the desktop. Therefore, if the window is vertically + * smaller than the menu, it will be positioned on the upper edge of the window. + */ + int newMenu_y; // New vertical menu position + if (m_positionY == AlignTop) { + newMenu_y = m_pushButton->mapToGlobal(QPoint(0, 0)).y() - geometry().height(); + if (newMenu_y < 0) { + newMenu_y = 0; + } + } else { + newMenu_y = pos().y(); + } + + // Set horizontal position. + if (m_positionX == AlignRight) { + // New horizontal menu position int newMenu_x = pos().x() - geometry().width() + m_pushButton->geometry().width(); // Get position of the right edge of the toggle button const int buttonPositionRight = m_pushButton->mapToGlobal(QPoint(0, 0)).x() + m_pushButton->geometry().width(); if (newMenu_x < 0) { newMenu_x = 0; } else if (newMenu_x + geometry().width() < buttonPositionRight) { newMenu_x = buttonPositionRight - geometry().width(); } - move(newMenu_x, pos().y()); - } else if (m_position == Left) { - move(m_pushButton->mapToGlobal(QPoint(0, 0)).x(), pos().y()); + move(newMenu_x, newMenu_y); + } else if (m_positionX == AlignLeft) { + move(m_pushButton->mapToGlobal(QPoint(0, 0)).x(), newMenu_y); + } else if (m_positionY == AlignTop) { + // Set vertical position, use the default horizontal position + move(pos().x(), newMenu_y); } } @@ -383,7 +404,7 @@ m_list->setCurrentItem(item->row()); // Change text of the trigger button - if (m_bAutoUpdateTextButton && m_pushButton && item->hasMode()) { + if (bool(m_autoUpdateTextButton) && m_pushButton && item->hasMode()) { m_pushButton->setText(item->getMode()->nameTranslated()); } } diff --git a/src/view/katestatusbar.cpp b/src/view/katestatusbar.cpp --- a/src/view/katestatusbar.cpp +++ b/src/view/katestatusbar.cpp @@ -202,11 +202,10 @@ modeMenuList->updateMenu(m_view->doc()); /** * add mode button which allows user to switch mode of document - * this will reuse the mode action menu of the view */ m_mode = new StatusBarButton(this); topLayout->addWidget(m_mode); - modeMenuList->setButton(m_mode, false, KateModeMenuList::Inverse); + modeMenuList->setButton(m_mode, KateModeMenuList::AlignHInverse, KateModeMenuList::AlignTop, KateModeMenuList::AutoUpdateTextButton(false)); m_mode->setMenu(modeMenuList); m_mode->setWhatsThis(i18n("Syntax highlighting"));