summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDongmei Wang <dongmei.wang@qt.io>2017-02-01 20:43:00 -0800
committerGabriel de Dietrich <gabriel.dedietrich@qt.io>2017-04-14 17:06:00 +0000
commiteea585ad0bfb92947ae2d77f3bc6662121cec9a9 (patch)
tree471533f2c5d4ed26a6d450c0904c6d55dda1c85b /tests
parente1c8451ffeeaa82f29aa2519addfa377f678ed9e (diff)
QMenu: Fix margins related display issues
Currently the contents margins and the menu paddings are not considered for calculating the menu size, the positions and the size of tear-off bar, scrollers and the positions of the menu items when scrolling the menu, which results in the following problems when valid contents margins and/or menu paddings are set: - The tear off area is displayed in a wrong position. The mouse events are not handled correctly in the tear off area. For example, when you click in the tear off area, the menu should be torn off but nothing happens - For a multi-column menu, the menu width is not calculated correctly - For a scrollable menu, - the menu width is not calculated correctly - the menu items are not displayed in correct positions - the scrollers are not displayed in correct positions - menu items are displayed on the area of borders and margins when scrolling the menu - the last menu item is not displayed above the bottom of the content area when scrolling the menu to the end. The changes are to fix the problems above. Change-Id: I7931e1088dff0029f2d4825e2aa34b4e32fdccd9 Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp185
1 files changed, 184 insertions, 1 deletions
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index b037cc2141..9109b2e8a3 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -55,6 +55,20 @@ static inline void centerOnScreen(QWidget *w, const QSize &size)
w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset);
}
+struct MenuMetrics {
+ int fw;
+ int hmargin;
+ int vmargin;
+ int tearOffHeight;
+
+ MenuMetrics(const QMenu *menu) {
+ fw = menu->style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, menu);
+ hmargin = menu->style()->pixelMetric(QStyle::PM_MenuHMargin, nullptr, menu);
+ vmargin = menu->style()->pixelMetric(QStyle::PM_MenuVMargin, nullptr, menu);
+ tearOffHeight = menu->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, nullptr, menu);
+ }
+};
+
static inline void centerOnScreen(QWidget *w)
{
centerOnScreen(w, w->geometry().size());
@@ -114,6 +128,8 @@ private slots:
void QTBUG_56917_wideMenuSize();
void QTBUG_56917_wideMenuScreenNumber();
void QTBUG_56917_wideSubmenuScreenNumber();
+ void menuSize_Scrolling_data();
+ void menuSize_Scrolling();
protected slots:
void onActivated(QAction*);
void onHighlighted(QAction*);
@@ -617,7 +633,10 @@ void tst_QMenu::tearOff()
QVERIFY(QTest::qWaitForWindowActive(menu.data()));
QVERIFY(!menu->isTearOffMenuVisible());
- QTest::mouseClick(menu.data(), Qt::LeftButton, 0, QPoint(3, 3), 10);
+ MenuMetrics mm(menu.data());
+ const int tearOffOffset = mm.fw + mm.vmargin + mm.tearOffHeight / 2;
+
+ QTest::mouseClick(menu.data(), Qt::LeftButton, 0, QPoint(10, tearOffOffset), 10);
QTRY_VERIFY(menu->isTearOffMenuVisible());
QPointer<QMenu> torn = getTornOffMenu();
QVERIFY(torn);
@@ -1373,5 +1392,169 @@ void tst_QMenu::QTBUG_56917_wideSubmenuScreenNumber()
}
}
+void tst_QMenu::menuSize_Scrolling_data()
+{
+ QTest::addColumn<int>("numItems");
+ QTest::addColumn<int>("topMargin");
+ QTest::addColumn<int>("bottomMargin");
+ QTest::addColumn<int>("leftMargin");
+ QTest::addColumn<int>("rightMargin");
+ QTest::addColumn<int>("topPadding");
+ QTest::addColumn<int>("bottomPadding");
+ QTest::addColumn<int>("leftPadding");
+ QTest::addColumn<int>("rightPadding");
+ QTest::addColumn<int>("border");
+ QTest::addColumn<bool>("scrollable");
+ QTest::addColumn<bool>("tearOff");
+
+ // test data
+ // a single column and non-scrollable menu with contents margins + border
+ QTest::newRow("data0") << 5 << 2 << 2 << 2 << 2 << 0 << 0 << 0 << 0 << 2 << false << false;
+ // a single column and non-scrollable menu with paddings + border
+ QTest::newRow("data1") << 5 << 0 << 0 << 0 << 0 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a single column and non-scrollable menu with contents margins + paddings + border
+ QTest::newRow("data2") << 5 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a single column and non-scrollable menu with contents margins + paddings + border + tear-off
+ QTest::newRow("data3") << 5 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << true;
+ // a multi-column menu with contents margins + border
+ QTest::newRow("data4") << 80 << 2 << 2 << 2 << 2 << 0 << 0 << 0 << 0 << 2 << false << false;
+ // a multi-column menu with paddings + border
+ QTest::newRow("data5") << 80 << 0 << 0 << 0 << 0 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a multi-column menu with contents margins + paddings + border
+ QTest::newRow("data6") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << false;
+ // a multi-column menu with contents margins + paddings + border + tear-off
+ QTest::newRow("data7") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << false << true;
+ // a scrollable menu with contents margins + border
+ QTest::newRow("data8") << 80 << 2 << 2 << 2 << 2 << 0 << 0 << 0 << 0 << 2 << true << false;
+ // a scrollable menu with paddings + border
+ QTest::newRow("data9") << 80 << 0 << 0 << 0 << 0 << 2 << 2 << 2 << 2 << 2 << true << false;
+ // a scrollable menu with contents margins + paddings + border
+ QTest::newRow("data10") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << true << false;
+ // a scrollable menu with contents margins + paddings + border + tear-off
+ QTest::newRow("data11") << 80 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << true << true;
+}
+
+void tst_QMenu::menuSize_Scrolling()
+{
+ class TestMenu : public QMenu
+ {
+ public:
+ struct ContentsMargins
+ {
+ ContentsMargins(int l, int t, int r, int b)
+ : left(l), top(t), right(r), bottom(b) {}
+ int left;
+ int top;
+ int right;
+ int bottom;
+ };
+
+ struct MenuPaddings
+ {
+ MenuPaddings(int l, int t, int r, int b)
+ : left(l), top(t), right(r), bottom(b) {}
+ int left;
+ int top;
+ int right;
+ int bottom;
+ };
+
+ TestMenu(int numItems, const ContentsMargins &margins, const MenuPaddings &paddings,
+ int border, bool scrollable, bool tearOff)
+ : QMenu("Test Menu"),
+ m_numItems(numItems),
+ m_scrollable(scrollable),
+ m_tearOff(tearOff)
+ {
+ init(margins, paddings, border);
+ }
+
+ ~TestMenu() {}
+
+ private:
+ void showEvent(QShowEvent *e) Q_DECL_OVERRIDE
+ {
+ QVERIFY(actions().length() == m_numItems);
+
+ int hmargin = style()->pixelMetric(QStyle::PM_MenuHMargin, nullptr, this);
+ int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, this);
+ int leftMargin, topMargin, rightMargin, bottomMargin;
+ getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
+ QRect lastItem = actionGeometry(actions().at(actions().length() - 1));
+ QSize s = size();
+ QCOMPARE( s.width(), lastItem.right() + fw + hmargin + rightMargin + 1);
+ QMenu::showEvent(e);
+ }
+
+ void init(const ContentsMargins &margins, const MenuPaddings &paddings, int border)
+ {
+ setLayoutDirection(Qt::LeftToRight);
+
+ setTearOffEnabled(m_tearOff);
+ setContentsMargins(margins.left, margins.top, margins.right, margins.bottom);
+ QString cssStyle("QMenu {menu-scrollable: ");
+ cssStyle += (m_scrollable ? QString::number(1) : QString::number(0));
+ cssStyle += "; border: ";
+ cssStyle += QString::number(border);
+ cssStyle += "px solid black; padding: ";
+ cssStyle += QString::number(paddings.top);
+ cssStyle += "px ";
+ cssStyle += QString::number(paddings.right);
+ cssStyle += "px ";
+ cssStyle += QString::number(paddings.bottom);
+ cssStyle += "px ";
+ cssStyle += QString::number(paddings.left);
+ cssStyle += "px;}";
+ setStyleSheet(cssStyle);
+ for (int i = 1; i <= m_numItems; i++)
+ addAction("MenuItem " + QString::number(i));
+ }
+
+ private:
+ int m_numItems;
+ bool m_scrollable;
+ bool m_tearOff;
+ };
+
+ QFETCH(int, numItems);
+ QFETCH(int, topMargin);
+ QFETCH(int, bottomMargin);
+ QFETCH(int, leftMargin);
+ QFETCH(int, rightMargin);
+ QFETCH(int, topPadding);
+ QFETCH(int, bottomPadding);
+ QFETCH(int, leftPadding);
+ QFETCH(int, rightPadding);
+ QFETCH(int, border);
+ QFETCH(bool, scrollable);
+ QFETCH(bool, tearOff);
+
+ qApp->setAttribute(Qt::AA_DontUseNativeMenuBar);
+
+ TestMenu::ContentsMargins margins(leftMargin, topMargin, rightMargin, bottomMargin);
+ TestMenu::MenuPaddings paddings(leftPadding, topPadding, rightPadding, bottomPadding);
+ TestMenu menu(numItems, margins, paddings, border, scrollable, tearOff);
+ menu.popup(QPoint(0,0));
+ centerOnScreen(&menu);
+ QVERIFY(QTest::qWaitForWindowExposed(&menu));
+
+ QList<QAction *> actions = menu.actions();
+ QCOMPARE(actions.length(), numItems);
+
+ MenuMetrics mm(&menu);
+ QTest::keyClick(&menu, Qt::Key_Home);
+ QTRY_COMPARE(menu.actionGeometry(actions.first()).y(), mm.fw + mm.vmargin + topMargin + (tearOff ? mm.tearOffHeight : 0));
+ QCOMPARE(menu.actionGeometry(actions.first()).x(), mm.fw + mm.hmargin + leftMargin);
+
+ if (!scrollable)
+ return;
+
+ QTest::keyClick(&menu, Qt::Key_End);
+ QTRY_COMPARE(menu.actionGeometry(actions.last()).right(),
+ menu.width() - mm.fw - mm.hmargin - leftMargin - 1);
+ QCOMPARE(menu.actionGeometry(actions.last()).bottom(),
+ menu.height() - mm.fw - mm.vmargin - bottomMargin - 1);
+}
+
QTEST_MAIN(tst_QMenu)
#include "tst_qmenu.moc"