summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/widgets')
-rw-r--r--tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp195
1 files changed, 179 insertions, 16 deletions
diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
index 41f1cb5e64..630b5c1167 100644
--- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
+++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
@@ -101,6 +101,8 @@ private slots:
void mouseReleaseOutsideTabBar();
void mouseWheel();
+ void kineticWheel_data();
+ void kineticWheel();
void scrollButtons_data();
void scrollButtons();
@@ -889,20 +891,25 @@ void tst_QTabBar::checkPositions(const TabBar &tabbar, const QList<int> &positio
}
#if QT_CONFIG(wheelevent)
-// defined to be 120 by the wheel mouse vendors according to the docs
-#define WHEEL_DELTA 120
class TabBarScrollingProxyStyle : public QProxyStyle
{
public:
- TabBarScrollingProxyStyle() : QProxyStyle(), scrolling(true)
+ TabBarScrollingProxyStyle(const QString &defStyle = {})
+ : QProxyStyle(defStyle), scrolling(true)
{ }
int styleHint(StyleHint hint, const QStyleOption *option = 0,
const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const override
{
- if (hint == QStyle::SH_TabBar_AllowWheelScrolling)
+ switch (hint) {
+ case QStyle::SH_TabBar_AllowWheelScrolling:
return scrolling;
+ case SH_TabBar_ElideMode:
+ return Qt::ElideNone;
+ default:
+ break;
+ }
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
@@ -912,37 +919,193 @@ public:
void tst_QTabBar::mouseWheel()
{
+ TabBar tabbar;
- // apply custom style to app, which can toggle tabbar scrolling behavior
- QCoreApplication *applicationInstance = QApplication::instance();
- QVERIFY(applicationInstance != 0);
- auto *proxyStyle = new TabBarScrollingProxyStyle;
- QApplication::setStyle(proxyStyle);
+ // apply custom style to the tabbar, which can toggle tabbar scrolling behavior
+ TabBarScrollingProxyStyle proxyStyle;
+ tabbar.setStyle(&proxyStyle);
// make tabbar with three tabs, select the middle one
- TabBar tabbar;
tabbar.addTab("one");
tabbar.addTab("two");
tabbar.addTab("three");
int startIndex = 1;
tabbar.setCurrentIndex(startIndex);
+ const auto systemId = QPointingDevice::primaryPointingDevice()->systemId() + 1;
+ QPointingDevice clickyWheel("test clicky wheel", systemId, QInputDevice::DeviceType::Mouse,
+ QPointingDevice::PointerType::Generic,
+ QInputDevice::Capability::Position | QInputDevice::Capability::Scroll,
+ 1, 3);
+
// define scroll event
const QPoint wheelPoint = tabbar.rect().bottomRight();
- QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), QPoint(), QPoint(0, WHEEL_DELTA),
- Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint),
+ QPoint(), QPoint(0, QWheelEvent::DefaultDeltasPerStep),
+ Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false,
+ Qt::MouseEventSynthesizedByApplication, &clickyWheel);
// disable scrolling, send scroll event, confirm that tab did not change
- proxyStyle->scrolling = false;
- QVERIFY(applicationInstance->sendEvent(&tabbar, &event));
+ proxyStyle.scrolling = false;
+ QVERIFY(QApplication::sendEvent(&tabbar, &event));
QVERIFY(tabbar.currentIndex() == startIndex);
// enable scrolling, send scroll event, confirm that tab changed
- proxyStyle->scrolling = true;
- QVERIFY(applicationInstance->sendEvent(&tabbar, &event));
+ proxyStyle.scrolling = true;
+ QVERIFY(QApplication::sendEvent(&tabbar, &event));
QVERIFY(tabbar.currentIndex() != startIndex);
}
+void tst_QTabBar::kineticWheel_data()
+{
+ QTest::addColumn<QTabBar::Shape>("tabShape");
+
+ QTest::addRow("North") << QTabBar::RoundedNorth;
+ QTest::addRow("East") << QTabBar::RoundedEast;
+ QTest::addRow("South") << QTabBar::RoundedSouth;
+ QTest::addRow("West") << QTabBar::RoundedWest;
+}
+
+void tst_QTabBar::kineticWheel()
+{
+ const auto systemId = QPointingDevice::primaryPointingDevice()->systemId() + 1;
+ QPointingDevice pixelPad("test pixel pad", systemId, QInputDevice::DeviceType::TouchPad,
+ QPointingDevice::PointerType::Generic,
+ QInputDevice::Capability::Position | QInputDevice::Capability::PixelScroll,
+ 1, 3);
+
+ QFETCH(QTabBar::Shape, tabShape);
+ QWidget window;
+ TabBar tabbar(&window);
+ // Since the macOS style makes sure that all tabs are always visible, we
+ // replace it with the windows style for this test, and use the proxy that
+ // makes sure that scrolling is enabled and that tab texts are not elided.
+ QString defaultStyle;
+ if (QApplication::style()->name() == QStringLiteral("macos"))
+ defaultStyle = "windows";
+ TabBarScrollingProxyStyle proxyStyle(defaultStyle);
+ tabbar.setStyle(&proxyStyle);
+
+ tabbar.addTab("long tab text 1");
+ tabbar.addTab("long tab text 2");
+ tabbar.addTab("long tab text 3");
+
+ // Make sure we don't have enough space for the tabs and need to scroll
+ const int tabbarLength = tabbar.tabRect(0).width() * 2;
+
+ tabbar.setShape(tabShape);
+ const bool horizontal = tabShape == QTabBar::RoundedNorth
+ || tabShape == QTabBar::RoundedSouth;
+ if (horizontal)
+ tabbar.setFixedWidth(tabbarLength);
+ else
+ tabbar.setFixedHeight(tabbarLength);
+
+ // start with the middle tab, QTabBar will scroll to make it visible
+ const int startIndex = 1;
+ tabbar.setCurrentIndex(startIndex);
+
+ window.setMinimumSize(tabbarLength, tabbarLength);
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ const auto *leftButton = tabbar.findChild<QAbstractButton*>(u"ScrollLeftButton"_qs);
+ const auto *rightButton = tabbar.findChild<QAbstractButton*>(u"ScrollRightButton"_qs);
+ QVERIFY(leftButton && rightButton);
+ QVERIFY(leftButton->isEnabled() && rightButton->isEnabled());
+
+ // Figure out if any of the buttons is laid out to be in front of the tabs.
+ // We can't use setUsesScrollButtons(false), as then several styles will enforce
+ // a minimum size for the tab bar.
+ const bool leftInFront = ((horizontal && leftButton->pos().x() < tabbar.rect().center().x())
+ || (!horizontal && leftButton->pos().y() < tabbar.rect().center().y()));
+ const bool rightInFront = ((horizontal && rightButton->pos().x() < tabbar.rect().center().x())
+ || (!horizontal && rightButton->pos().y() < tabbar.rect().center().y()));
+ QPoint leftEdge;
+ QPoint rightEdge;
+ if (leftInFront && rightInFront) { // both on the left
+ leftEdge = rightButton->geometry().bottomRight();
+ rightEdge = tabbar.rect().bottomRight();
+ } else if (leftInFront && !rightInFront) {
+ leftEdge = leftButton->geometry().bottomRight();
+ rightEdge = rightButton->geometry().topLeft();
+ } else { // both on the right
+ leftEdge = QPoint(0, 0);
+ rightEdge = leftButton->geometry().topLeft();
+ }
+ // avoid border lines
+ leftEdge += QPoint(2, 2);
+ if (horizontal) {
+ rightEdge += QPoint(-2, 2);
+ } else {
+ rightEdge += QPoint(2, -2);
+ }
+
+ QCOMPARE(tabbar.tabAt(leftEdge), 0);
+ QCOMPARE(tabbar.tabAt(rightEdge), 1);
+
+ const QPoint delta = horizontal ? QPoint(10, 0) : QPoint(0, 10);
+ const QPoint wheelPoint = tabbar.rect().center();
+
+ bool accepted = true;
+ Qt::ScrollPhase phase = Qt::ScrollBegin;
+ // scroll all the way to the end
+ while (accepted) {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), -delta, -delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ if (phase == Qt::ScrollBegin)
+ phase = Qt::ScrollUpdate;
+ QApplication::sendEvent(&tabbar, &event);
+ accepted = event.isAccepted();
+ }
+ QCOMPARE(tabbar.tabAt(leftEdge), 1);
+ QCOMPARE(tabbar.tabAt(rightEdge), 2);
+ QVERIFY(leftButton->isEnabled());
+ QVERIFY(!rightButton->isEnabled());
+ // kinetic wheel events don't change the current index
+ QVERIFY(tabbar.currentIndex() == startIndex);
+
+ // scroll all the way to the beginning
+ accepted = true;
+ while (accepted) {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), delta, delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ QApplication::sendEvent(&tabbar, &event);
+ accepted = event.isAccepted();
+ }
+
+ QCOMPARE(tabbar.tabAt(leftEdge), 0);
+ QCOMPARE(tabbar.tabAt(rightEdge), 1);
+ QVERIFY(!leftButton->isEnabled());
+ QVERIFY(rightButton->isEnabled());
+ // kinetic wheel events don't change the current index
+ QVERIFY(tabbar.currentIndex() == startIndex);
+
+ // make tabs small so that we have enough space, and verify sure we can't scroll
+ tabbar.setTabText(0, "A");
+ tabbar.setTabText(1, "B");
+ tabbar.setTabText(2, "C");
+ QVERIFY(tabbar.sizeHint().width() <= tabbar.width() && tabbar.sizeHint().height() <= tabbar.height());
+
+ {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), -delta, -delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ QApplication::sendEvent(&tabbar, &event);
+ QVERIFY(!event.isAccepted());
+ }
+
+ {
+ QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), delta, delta,
+ Qt::NoButton, Qt::NoModifier, phase, false,
+ Qt::MouseEventSynthesizedByApplication, &pixelPad);
+ QApplication::sendEvent(&tabbar, &event);
+ QVERIFY(!event.isAccepted());
+ }
+}
+
#endif // QT_CONFIG(wheelevent)
void tst_QTabBar::scrollButtons_data()