aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-04-06 22:13:27 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-04-06 22:13:27 +0200
commit2784902b9b42de127c0903c3d6b076297cf47a07 (patch)
tree3b95b5cdf61c951f7d54fccf47b14a0ccbce7e6c
parent0a96b436d9845899888f7c7d153f0d9909ce4c06 (diff)
parentf8224c9c9e3dfc1fd4cc3bff915e7e2d1c411d05 (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/imports/templates/qtquicktemplates2plugin.cpp Change-Id: I4a07d331163a85a0fb98a5f58f3970863f8da0fc
-rw-r--r--.gitignore1
-rw-r--r--examples/quickcontrols2/gallery/gallery.qml9
-rw-r--r--src/imports/calendar/qquickmonthgrid.cpp3
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-index.qdoc43
-rw-r--r--src/imports/controls/material/qquickmaterialbusyindicator.cpp2
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp1
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp6
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp12
-rw-r--r--src/quicktemplates2/qquickdial.cpp9
-rw-r--r--src/quicktemplates2/qquickdialog.cpp2
-rw-r--r--src/quicktemplates2/qquickdialogbuttonbox.cpp2
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp3
-rw-r--r--src/quicktemplates2/qquickpage.cpp3
-rw-r--r--src/quicktemplates2/qquickpageindicator.cpp12
-rw-r--r--src/quicktemplates2/qquickpane.cpp6
-rw-r--r--src/quicktemplates2/qquickpopup.cpp20
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp11
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp16
-rw-r--r--src/quicktemplates2/qquickslider.cpp9
-rw-r--r--src/quicktemplates2/qquickspinbox.cpp17
-rw-r--r--src/quicktemplates2/qquickstackview_p.cpp17
-rw-r--r--src/quicktemplates2/qquickstackview_p_p.h3
-rw-r--r--src/quicktemplates2/qquicktabbar_p.h4
-rw-r--r--tests/auto/auto.pro1
-rw-r--r--tests/auto/controls/data/tst_combobox.qml6
-rw-r--r--tests/auto/controls/data/tst_dial.qml14
-rw-r--r--tests/auto/controls/data/tst_rangeslider.qml53
-rw-r--r--tests/auto/controls/data/tst_slider.qml54
-rw-r--r--tests/auto/controls/data/tst_stackview.qml9
-rw-r--r--tests/auto/cursor/cursor.pro14
-rw-r--r--tests/auto/cursor/data/buttons.qml104
-rw-r--r--tests/auto/cursor/data/containers.qml77
-rw-r--r--tests/auto/cursor/data/editable.qml72
-rw-r--r--tests/auto/cursor/data/pageindicator.qml62
-rw-r--r--tests/auto/cursor/data/scrollbar.qml70
-rw-r--r--tests/auto/cursor/data/sliders.qml71
-rw-r--r--tests/auto/cursor/tst_cursor.cpp197
37 files changed, 916 insertions, 99 deletions
diff --git a/.gitignore b/.gitignore
index 6b88d21f..24c46395 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@
/tests/auto/controls/default/tst_default
/tests/auto/controls/material/tst_material
/tests/auto/controls/universal/tst_universal
+/tests/auto/cursor/tst_cursor
/tests/auto/drawer/tst_drawer
/tests/auto/focus/tst_focus
/tests/auto/menu/tst_menu
diff --git a/examples/quickcontrols2/gallery/gallery.qml b/examples/quickcontrols2/gallery/gallery.qml
index ed5171df..9f253ab3 100644
--- a/examples/quickcontrols2/gallery/gallery.qml
+++ b/examples/quickcontrols2/gallery/gallery.qml
@@ -48,7 +48,7 @@
**
****************************************************************************/
-import QtQuick 2.6
+import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.1
@@ -68,7 +68,7 @@ ApplicationWindow {
}
Shortcut {
- sequence: "Esc"
+ sequences: ["Esc", "Back"]
enabled: stackView.depth > 1
onActivated: {
stackView.pop()
@@ -76,6 +76,11 @@ ApplicationWindow {
}
}
+ Shortcut {
+ sequence: "Menu"
+ onActivated: optionsMenu.open()
+ }
+
header: ToolBar {
Material.foreground: "white"
diff --git a/src/imports/calendar/qquickmonthgrid.cpp b/src/imports/calendar/qquickmonthgrid.cpp
index 5eb0798c..9621f49a 100644
--- a/src/imports/calendar/qquickmonthgrid.cpp
+++ b/src/imports/calendar/qquickmonthgrid.cpp
@@ -195,6 +195,9 @@ QQuickMonthGrid::QQuickMonthGrid(QQuickItem *parent) :
setFlag(ItemIsFocusScope);
setActiveFocusOnTab(true);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
d->model = new QQuickMonthModel(this);
d->source = QVariant::fromValue(d->model);
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc
index 99b6c2ea..4f0771a6 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc
@@ -35,6 +35,36 @@
to build complete interfaces in Qt Quick. The module was introduced
in Qt 5.7.
+ Qt Quick Controls 2 comes with a selection customizable styles.
+ See \l {Styling Qt Quick Controls 2} for more details.
+
+ \raw HTML
+ <table style="background:transparent; border:0px" width="66%">
+ <tr>
+ <td style="border:0px; padding-right:25px;">
+ <a href="qtquickcontrols2-default.html">
+ <img src="images/qtquickcontrols2-default.png" alt="Default" width="100%"/>
+ </a>
+ </td>
+ <td style="border:0px; padding-right:25px;">
+ <a href="qtquickcontrols2-material.html">
+ <img src="images/qtquickcontrols2-material.png" alt="Material" width="100%"/>
+ </a>
+ </td>
+ <td style="border:0px;">
+ <a href="qtquickcontrols2-universal.html">
+ <img src="images/qtquickcontrols2-universal.png" alt="Universal" width="100%"/>
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td style="border:0px">Default</td>
+ <td style="border:0px">Material</td>
+ <td style="border:0px">Universal</td>
+ </tr>
+ </table>
+ \endraw
+
\section1 Prerequisites
The \l{Qt Quick Controls 2 QML Types}{QML types} can be imported into your
@@ -62,7 +92,7 @@
\section1 Versions
- Qt Quick Controls 2.0 was released in Qt 5.7. Subsequent minor Qt releases
+ Qt Quick Controls 2.0 was introduced in Qt 5.7. Subsequent minor Qt releases
increment the import version of the Qt Quick Controls 2 modules by one. The
experimental Qt Labs modules use import version 1.0.
@@ -71,35 +101,31 @@
\li \c Qt
\li \l {Qt Quick QML Types}{\c QtQuick}
\li \l {Qt Quick Controls 2 QML Types}{\c QtQuick.Controls},\br
- \l {Qt Quick Templates 2 QML Types}{\c QtQuick.Templates},
- \li \l {Material Style}{\c QtQuick.Controls.Material},\br
- \l {Universal Style}{\c QtQuick.Controls.Universal}
+ \l {Material Style}{\c QtQuick.Controls.Material},\br
+ \l {Universal Style}{\c QtQuick.Controls.Universal},\br
+ \l {Qt Quick Templates 2 QML Types}{\c QtQuick.Templates}
\li \l {Qt Labs Calendar QML Types}{\c Qt.labs.calendar},\br
\l {Qt Labs Platform QML Types}{\c Qt.labs.platform}
\row
\li 5.7
\li 2.7
\li 2.0
- \li 2.0
\li 1.0
\row
\li 5.8
\li 2.8
\li 2.1
- \li 2.1
\li 1.0
\row
\li 5.9
\li 2.9
\li 2.2
- \li 2.2
\li 1.0
\row
\li ...
\li ...
\li ...
\li ...
- \li ...
\endtable
\section1 Important Concepts in Qt Quick Controls 2
@@ -129,6 +155,7 @@
\li \l{Qt Quick Controls 2 - Gallery}{Gallery}
\li \l{Qt Quick Controls 2 - Chat Tutorial}{Chat Tutorial}
\li \l{Qt Quick Controls 2 - Text Editor}{Text Editor}
+ \li \l{Qt Quick Controls 2 - Wearable Demo}{Wearable Demo}
\li \l{Qt Quick Controls 2 Examples}{All Examples}
\endlist
diff --git a/src/imports/controls/material/qquickmaterialbusyindicator.cpp b/src/imports/controls/material/qquickmaterialbusyindicator.cpp
index 7bc96505..9df8f5d2 100644
--- a/src/imports/controls/material/qquickmaterialbusyindicator.cpp
+++ b/src/imports/controls/material/qquickmaterialbusyindicator.cpp
@@ -178,7 +178,7 @@ void QQuickMaterialBusyIndicatorNode::sync(QQuickItem *item)
}
QQuickMaterialBusyIndicator::QQuickMaterialBusyIndicator(QQuickItem *parent) :
- QQuickItem(parent)
+ QQuickItem(parent), m_elapsed(0), m_color(Qt::black)
{
setFlag(ItemHasContents);
}
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index a43d5baf..becea232 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -252,6 +252,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
// NOTE: register the latest revisions of all template/control base classes to
// make revisioned properties available to their subclasses (synced with Qt 5.9)
qmlRegisterRevision<QQuickText, 9>(uri, 2, 2);
+ qmlRegisterRevision<QQuickTextInput, 9>(uri, 2, 2);
// QtQuick.Templates 2.3 (new types and revisions in Qt 5.10)
qmlRegisterType<QQuickIcon>();
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index c0d8101e..9b1a51fb 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -342,6 +342,9 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickItem *parent)
setActiveFocusOnTab(true);
setFocusPolicy(Qt::StrongFocus);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent)
@@ -350,6 +353,9 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQui
setActiveFocusOnTab(true);
setFocusPolicy(Qt::StrongFocus);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
QQuickAbstractButton::~QQuickAbstractButton()
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 786db55b..85c577b4 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -628,6 +628,9 @@ QQuickComboBox::QQuickComboBox(QQuickItem *parent)
setFocusPolicy(Qt::StrongFocus);
setFlag(QQuickItem::ItemIsFocusScope);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
setInputMethodHints(Qt::ImhNoPredictiveText);
}
@@ -737,12 +740,18 @@ void QQuickComboBox::setEditable(bool editable)
QObjectPrivate::connect(input, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
QObjectPrivate::connect(input, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
}
+#if QT_CONFIG(cursor)
+ d->contentItem->setCursor(Qt::IBeamCursor);
+#endif
} else {
d->contentItem->removeEventFilter(this);
if (QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem)) {
QObjectPrivate::disconnect(input, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
QObjectPrivate::disconnect(input, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
}
+#if QT_CONFIG(cursor)
+ d->contentItem->unsetCursor();
+#endif
}
}
@@ -1542,6 +1551,9 @@ void QQuickComboBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
connect(newInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickComboBox::inputMethodComposingChanged);
connect(newInput, &QQuickTextInput::acceptableInputChanged, this, &QQuickComboBox::acceptableInputChanged);
}
+#if QT_CONFIG(cursor)
+ newItem->setCursor(Qt::IBeamCursor);
+#endif
}
}
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 24a8df01..5b98992b 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -207,8 +207,6 @@ void QQuickDialPrivate::handlePress(const QPointF &point)
void QQuickDialPrivate::handleMove(const QPointF &point)
{
Q_Q(QQuickDial);
- if (!q->keepMouseGrab() && !q->keepTouchGrab())
- return;
const qreal oldPos = position;
qreal pos = positionAt(point);
if (snapMode == QQuickDial::SnapAlways)
@@ -260,6 +258,9 @@ QQuickDial::QQuickDial(QQuickItem *parent)
{
setActiveFocusOnTab(true);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
/*!
@@ -648,6 +649,7 @@ void QQuickDial::mousePressEvent(QMouseEvent *event)
Q_D(QQuickDial);
QQuickControl::mousePressEvent(event);
d->handlePress(event->localPos());
+ d->handleMove(event->localPos());
}
void QQuickDial::mouseMoveEvent(QMouseEvent *event)
@@ -708,7 +710,8 @@ void QQuickDial::touchEvent(QTouchEvent *event)
setKeepTouchGrab(overYDragThreshold);
}
}
- d->handleMove(point.pos());
+ if (keepTouchGrab())
+ d->handleMove(point.pos());
}
break;
diff --git a/src/quicktemplates2/qquickdialog.cpp b/src/quicktemplates2/qquickdialog.cpp
index fbb612b3..3ac99caa 100644
--- a/src/quicktemplates2/qquickdialog.cpp
+++ b/src/quicktemplates2/qquickdialog.cpp
@@ -257,6 +257,8 @@ void QQuickDialog::setFooter(QQuickItem *footer)
\snippet qtquickcontrols2-dialog.qml 1
+ The buttons will be positioned in the appropriate order for the user's platform.
+
Possible flags:
\value Dialog.Ok An "OK" button defined with the \c AcceptRole.
\value Dialog.Open An "Open" button defined with the \c AcceptRole.
diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp
index f1971635..386577da 100644
--- a/src/quicktemplates2/qquickdialogbuttonbox.cpp
+++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp
@@ -437,6 +437,8 @@ void QQuickDialogButtonBox::resetAlignment()
\snippet qtquickcontrols2-dialogbuttonbox.qml 1
+ The buttons will be positioned in the appropriate order for the user's platform.
+
Possible flags:
\value DialogButtonBox.Ok An "OK" button defined with the \c AcceptRole.
\value DialogButtonBox.Open An "Open" button defined with the \c AcceptRole.
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index c72979ae..d31186cd 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -97,6 +97,9 @@ static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQ
item->setZ(popup->z());
if (popup->isModal()) {
item->setAcceptedMouseButtons(Qt::AllButtons);
+#if QT_CONFIG(cursor)
+ item->setCursor(Qt::ArrowCursor);
+#endif
#if QT_CONFIG(quicktemplates2_hover)
// TODO: switch to QStyleHints::useHoverEffects in Qt 5.8
item->setAcceptHoverEvents(true);
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp
index 701916b6..6b0b3a38 100644
--- a/src/quicktemplates2/qquickpage.cpp
+++ b/src/quicktemplates2/qquickpage.cpp
@@ -117,6 +117,9 @@ QQuickPage::QQuickPage(QQuickItem *parent)
Q_D(QQuickPage);
setFlag(ItemIsFocusScope);
setAcceptedMouseButtons(Qt::AllButtons);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
d->layout.reset(new QQuickPageLayout(this));
}
diff --git a/src/quicktemplates2/qquickpageindicator.cpp b/src/quicktemplates2/qquickpageindicator.cpp
index 92b6c0c0..b4c9c14c 100644
--- a/src/quicktemplates2/qquickpageindicator.cpp
+++ b/src/quicktemplates2/qquickpageindicator.cpp
@@ -247,7 +247,17 @@ void QQuickPageIndicator::setInteractive(bool interactive)
return;
d->interactive = interactive;
- setAcceptedMouseButtons(interactive ? Qt::LeftButton : Qt::NoButton);
+ if (interactive) {
+ setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
+ } else {
+ setAcceptedMouseButtons(Qt::NoButton);
+#if QT_CONFIG(cursor)
+ unsetCursor();
+#endif
+ }
emit interactiveChanged();
}
diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp
index 6cb81316..efa85e0c 100644
--- a/src/quicktemplates2/qquickpane.cpp
+++ b/src/quicktemplates2/qquickpane.cpp
@@ -123,6 +123,9 @@ QQuickPane::QQuickPane(QQuickItem *parent)
{
setFlag(QQuickItem::ItemIsFocusScope);
setAcceptedMouseButtons(Qt::AllButtons);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
QQuickPane::QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent)
@@ -130,6 +133,9 @@ QQuickPane::QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent)
{
setFlag(QQuickItem::ItemIsFocusScope);
setAcceptedMouseButtons(Qt::AllButtons);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
/*!
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 9b541803..8c37ea84 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -176,7 +176,7 @@ QT_BEGIN_NAMESPACE
This signal is emitted when the popup is opened.
- \sa closed
+ \sa aboutToShow()
*/
/*!
@@ -184,7 +184,23 @@ QT_BEGIN_NAMESPACE
This signal is emitted when the popup is closed.
- \sa opened
+ \sa aboutToHide()
+*/
+
+/*!
+ \qmlsignal void QtQuick.Controls::Popup::aboutToShow()
+
+ This signal is emitted when the popup is about to show.
+
+ \sa opened()
+*/
+
+/*!
+ \qmlsignal void QtQuick.Controls::Popup::aboutToHide()
+
+ This signal is emitted when the popup is about to hide.
+
+ \sa closed()
*/
QQuickPopupPrivate::QQuickPopupPrivate()
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp
index 175ca06e..9996d041 100644
--- a/src/quicktemplates2/qquickrangeslider.cpp
+++ b/src/quicktemplates2/qquickrangeslider.cpp
@@ -456,8 +456,6 @@ void QQuickRangeSliderPrivate::handlePress(const QPointF &point, int touchId)
void QQuickRangeSliderPrivate::handleMove(const QPointF &point, int touchId)
{
Q_Q(QQuickRangeSlider);
- if (!q->keepMouseGrab() && !q->keepTouchGrab())
- return;
QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId);
if (pressedNode) {
qreal pos = positionAt(q, pressedNode->handle(), point);
@@ -521,8 +519,11 @@ QQuickRangeSlider::QQuickRangeSlider(QQuickItem *parent)
d->first = new QQuickRangeSliderNode(0.0, this);
d->second = new QQuickRangeSliderNode(1.0, this);
- setAcceptedMouseButtons(Qt::LeftButton);
setFlag(QQuickItem::ItemIsFocusScope);
+ setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
/*!
@@ -982,6 +983,7 @@ void QQuickRangeSlider::mousePressEvent(QMouseEvent *event)
Q_D(QQuickRangeSlider);
QQuickControl::mousePressEvent(event);
d->handlePress(event->localPos());
+ d->handleMove(event->localPos());
}
void QQuickRangeSlider::mouseMoveEvent(QMouseEvent *event)
@@ -994,7 +996,8 @@ void QQuickRangeSlider::mouseMoveEvent(QMouseEvent *event)
else
setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(event->localPos().y() - d->pressPoint.y(), Qt::YAxis, event));
}
- d->handleMove(event->localPos());
+ if (keepMouseGrab())
+ d->handleMove(event->localPos());
}
void QQuickRangeSlider::mouseReleaseEvent(QMouseEvent *event)
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp
index 9aeec74f..6050149e 100644
--- a/src/quicktemplates2/qquickscrollbar.cpp
+++ b/src/quicktemplates2/qquickscrollbar.cpp
@@ -196,9 +196,18 @@ void QQuickScrollBarPrivate::setInteractive(bool enabled)
return;
interactive = enabled;
- q->setAcceptedMouseButtons(interactive ? Qt::LeftButton : Qt::NoButton);
- if (!interactive)
+ if (interactive) {
+ q->setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ q->setCursor(Qt::ArrowCursor);
+#endif
+ } else {
+ q->setAcceptedMouseButtons(Qt::NoButton);
+#if QT_CONFIG(cursor)
+ q->unsetCursor();
+#endif
q->ungrabMouse();
+ }
emit q->interactiveChanged();
}
@@ -274,6 +283,9 @@ QQuickScrollBar::QQuickScrollBar(QQuickItem *parent)
{
setKeepMouseGrab(true);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
QQuickScrollBarAttached *QQuickScrollBar::qmlAttachedProperties(QObject *object)
diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp
index 47f51cf2..7c64957b 100644
--- a/src/quicktemplates2/qquickslider.cpp
+++ b/src/quicktemplates2/qquickslider.cpp
@@ -194,8 +194,6 @@ void QQuickSliderPrivate::handlePress(const QPointF &point)
void QQuickSliderPrivate::handleMove(const QPointF &point)
{
Q_Q(QQuickSlider);
- if (!q->keepMouseGrab() && !q->keepTouchGrab())
- return;
const qreal oldPos = position;
qreal pos = positionAt(point);
if (snapMode == QQuickSlider::SnapAlways)
@@ -243,6 +241,9 @@ QQuickSlider::QQuickSlider(QQuickItem *parent)
setActiveFocusOnTab(true);
setFocusPolicy(Qt::StrongFocus);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
/*!
@@ -650,6 +651,7 @@ void QQuickSlider::mousePressEvent(QMouseEvent *event)
Q_D(QQuickSlider);
QQuickControl::mousePressEvent(event);
d->handlePress(event->localPos());
+ d->handleMove(event->localPos());
}
void QQuickSlider::mouseMoveEvent(QMouseEvent *event)
@@ -704,7 +706,8 @@ void QQuickSlider::touchEvent(QTouchEvent *event)
else
setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().y() - d->pressPoint.y(), Qt::YAxis, &point));
}
- d->handleMove(point.pos());
+ if (keepTouchGrab())
+ d->handleMove(point.pos());
}
break;
diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp
index 657102c3..b70366ea 100644
--- a/src/quicktemplates2/qquickspinbox.cpp
+++ b/src/quicktemplates2/qquickspinbox.cpp
@@ -351,6 +351,9 @@ QQuickSpinBox::QQuickSpinBox(QQuickItem *parent)
setFlag(ItemIsFocusScope);
setFiltersChildMouseEvents(true);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
}
/*!
@@ -470,6 +473,15 @@ void QQuickSpinBox::setEditable(bool editable)
if (d->editable == editable)
return;
+#if QT_CONFIG(cursor)
+ if (d->contentItem) {
+ if (editable)
+ d->contentItem->setCursor(Qt::IBeamCursor);
+ else
+ d->contentItem->unsetCursor();
+ }
+#endif
+
d->editable = editable;
emit editableChanged();
}
@@ -905,11 +917,16 @@ void QQuickSpinBox::itemChange(ItemChange change, const ItemChangeData &value)
void QQuickSpinBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
+ Q_D(QQuickSpinBox);
if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem))
disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickSpinBox::inputMethodComposingChanged);
if (newItem) {
newItem->setActiveFocusOnTab(true);
+#if QT_CONFIG(cursor)
+ if (d->editable)
+ newItem->setCursor(Qt::IBeamCursor);
+#endif
if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem))
connect(newInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickSpinBox::inputMethodComposingChanged);
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp
index c6f9291d..3c983d6b 100644
--- a/src/quicktemplates2/qquickstackview_p.cpp
+++ b/src/quicktemplates2/qquickstackview_p.cpp
@@ -93,6 +93,7 @@ static bool initProperties(QQuickStackElement *element, const QV4::Value &props,
QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(int from, QQmlV4Function *args, QStringList *errors)
{
QV4::ExecutionEngine *v4 = args->v4engine();
+ QQmlContextData *context = v4->callingQmlContext();
QV4::Scope scope(v4);
QList<QQuickStackElement *> elements;
@@ -105,7 +106,7 @@ QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(int from, QQml
for (int j = 0; j < len; ++j) {
QString error;
QV4::ScopedValue value(scope, array->getIndexed(j));
- QQuickStackElement *element = createElement(value, &error);
+ QQuickStackElement *element = createElement(value, context, &error);
if (element) {
if (j < len - 1) {
QV4::ScopedValue props(scope, array->getIndexed(j + 1));
@@ -119,7 +120,7 @@ QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(int from, QQml
}
} else {
QString error;
- QQuickStackElement *element = createElement(arg, &error);
+ QQuickStackElement *element = createElement(arg, context, &error);
if (element) {
if (i < argc - 1) {
QV4::ScopedValue props(scope, (*args)[i + 1]);
@@ -153,11 +154,19 @@ QQuickStackElement *QQuickStackViewPrivate::findElement(const QV4::Value &value)
return nullptr;
}
-QQuickStackElement *QQuickStackViewPrivate::createElement(const QV4::Value &value, QString *error)
+static QString resolvedUrl(const QString &str, QQmlContextData *context)
+{
+ QUrl url(str);
+ if (url.isRelative())
+ return context->resolvedUrl(url).toString();
+ return str;
+}
+
+QQuickStackElement *QQuickStackViewPrivate::createElement(const QV4::Value &value, QQmlContextData *context, QString *error)
{
Q_Q(QQuickStackView);
if (const QV4::String *s = value.as<QV4::String>())
- return QQuickStackElement::fromString(s->toQString(), q, error);
+ return QQuickStackElement::fromString(resolvedUrl(s->toQString(), context), q, error);
if (const QV4::QObjectWrapper *o = value.as<QV4::QObjectWrapper>())
return QQuickStackElement::fromObject(o->object(), q, error);
return nullptr;
diff --git a/src/quicktemplates2/qquickstackview_p_p.h b/src/quicktemplates2/qquickstackview_p_p.h
index 26d741f8..81ca9164 100644
--- a/src/quicktemplates2/qquickstackview_p_p.h
+++ b/src/quicktemplates2/qquickstackview_p_p.h
@@ -57,6 +57,7 @@
QT_BEGIN_NAMESPACE
+class QQmlContextData;
class QQuickStackElement;
struct QQuickStackTransition;
@@ -79,7 +80,7 @@ public:
QList<QQuickStackElement *> parseElements(int from, QQmlV4Function *args, QStringList *errors);
QQuickStackElement *findElement(QQuickItem *item) const;
QQuickStackElement *findElement(const QV4::Value &value) const;
- QQuickStackElement *createElement(const QV4::Value &value, QString *error);
+ QQuickStackElement *createElement(const QV4::Value &value, QQmlContextData *context, QString *error);
bool pushElements(const QList<QQuickStackElement *> &elements);
bool pushElement(QQuickStackElement *element);
bool popElements(QQuickStackElement *element);
diff --git a/src/quicktemplates2/qquicktabbar_p.h b/src/quicktemplates2/qquicktabbar_p.h
index bc228346..0ffd53d5 100644
--- a/src/quicktemplates2/qquicktabbar_p.h
+++ b/src/quicktemplates2/qquicktabbar_p.h
@@ -83,8 +83,8 @@ public:
Q_SIGNALS:
void positionChanged();
- void contentWidthChanged();
- void contentHeightChanged();
+ Q_REVISION(2) void contentWidthChanged();
+ Q_REVISION(2) void contentHeightChanged();
protected:
void updatePolish() override;
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 38f098c9..0162c38f 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -4,6 +4,7 @@ SUBDIRS += \
applicationwindow \
calendar \
controls \
+ cursor \
drawer \
menu \
platform \
diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml
index fb4dc57c..05eb2de1 100644
--- a/tests/auto/controls/data/tst_combobox.qml
+++ b/tests/auto/controls/data/tst_combobox.qml
@@ -55,8 +55,8 @@ import QtQuick.Controls 2.2
TestCase {
id: testCase
- width: 200
- height: 200
+ width: 400
+ height: 400
visible: true
when: windowShown
name: "ComboBox"
@@ -724,6 +724,8 @@ TestCase {
compare(downSpy.count, 3)
compare(pressedSpy.count, 2)
+ compare(control.popup.y, control.height)
+
control.down = false
compare(control.down, false)
compare(downSpy.count, 4)
diff --git a/tests/auto/controls/data/tst_dial.qml b/tests/auto/controls/data/tst_dial.qml
index 98c3a002..3b20e91d 100644
--- a/tests/auto/controls/data/tst_dial.qml
+++ b/tests/auto/controls/data/tst_dial.qml
@@ -465,7 +465,7 @@ TestCase {
compare(dial.value, dial.to);
}
- function test_snapMode_data() {
+ function test_snapMode_data(immediate) {
return [
{ tag: "NoSnap", snapMode: Slider.NoSnap, from: 0, to: 2, values: [0, 0, 1], positions: [0, 0.5, 0.5] },
{ tag: "SnapAlways (0..2)", snapMode: Slider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 1.0], positions: [0.0, 0.5, 0.5] },
@@ -474,13 +474,13 @@ TestCase {
{ tag: "SnapAlways (1..-1)", snapMode: Slider.SnapAlways, from: 1, to: -1, values: [1.0, 1.0, 0.0], positions: [0.0, 0.5, 0.5] },
{ tag: "SnapOnRelease (0..2)", snapMode: Slider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 1.0], positions: [0.0, 0.5, 0.5] },
{ tag: "SnapOnRelease (1..3)", snapMode: Slider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 2.0], positions: [0.0, 0.5, 0.5] },
- { tag: "SnapOnRelease (-1..1)", snapMode: Slider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, 0.0], positions: [0.5, 0.5, 0.5] },
+ { tag: "SnapOnRelease (-1..1)", snapMode: Slider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, 0.0], positions: [immediate ? 0.0 : 0.5, 0.5, 0.5] },
{ tag: "SnapOnRelease (1..-1)", snapMode: Slider.SnapOnRelease, from: 1, to: -1, values: [1.0, 1.0, 0.0], positions: [0.0, 0.5, 0.5] }
]
}
function test_snapMode_mouse_data() {
- return test_snapMode_data()
+ return test_snapMode_data(true)
}
function test_snapMode_mouse(data) {
@@ -492,11 +492,11 @@ TestCase {
dial.to = data.to;
dial.stepSize = 0.2;
- var fuzz = 0.05;
+ var fuzz = 0.055;
mousePress(dial, dial.width * 0.25, dial.height * 0.75);
- compare(dial.value, data.values[0]);
- compare(dial.position, data.positions[0]);
+ fuzzyCompare(dial.value, data.values[0], fuzz);
+ fuzzyCompare(dial.position, data.positions[0], fuzz);
mouseMove(dial, dial.width * 0.5, dial.height * 0.25);
fuzzyCompare(dial.value, data.values[1], fuzz);
@@ -508,7 +508,7 @@ TestCase {
}
function test_snapMode_touch_data() {
- return test_snapMode_data()
+ return test_snapMode_data(false)
}
function test_snapMode_touch(data) {
diff --git a/tests/auto/controls/data/tst_rangeslider.qml b/tests/auto/controls/data/tst_rangeslider.qml
index 867bb70a..bc3ce515 100644
--- a/tests/auto/controls/data/tst_rangeslider.qml
+++ b/tests/auto/controls/data/tst_rangeslider.qml
@@ -294,7 +294,7 @@ TestCase {
var secondPressedSpy = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"})
verify(secondPressedSpy.valid)
- mousePress(control, control.width * 0.25, control.height * 0.75, Qt.LeftButton)
+ mousePress(control, control.leftPadding, control.height - control.bottomPadding, Qt.LeftButton)
compare(firstPressedSpy.count, 1)
compare(secondPressedSpy.count, 0)
compare(control.first.pressed, true)
@@ -304,7 +304,7 @@ TestCase {
compare(control.second.value, 1.0)
compare(control.second.position, 1.0)
- mouseRelease(control, control.width * 0.25, control.height * 0.75, Qt.LeftButton)
+ mouseRelease(control, control.leftPadding, control.height - control.bottomPadding, Qt.LeftButton)
compare(firstPressedSpy.count, 2)
compare(secondPressedSpy.count, 0)
compare(control.first.pressed, false)
@@ -314,7 +314,7 @@ TestCase {
compare(control.second.value, 1.0)
compare(control.second.position, 1.0)
- mousePress(control, control.width * 0.75, control.height * 0.25, Qt.LeftButton)
+ mousePress(control, control.width - control.rightPadding, control.topPadding, Qt.LeftButton)
compare(firstPressedSpy.count, 2)
compare(secondPressedSpy.count, 1)
compare(control.first.pressed, false)
@@ -324,7 +324,7 @@ TestCase {
compare(control.second.value, 1.0)
compare(control.second.position, 1.0)
- mouseRelease(control, control.width * 0.75, control.height * 0.25, Qt.LeftButton)
+ mouseRelease(control, control.width - control.rightPadding, control.topPadding, Qt.LeftButton)
compare(firstPressedSpy.count, 2)
compare(secondPressedSpy.count, 2)
compare(control.first.pressed, false)
@@ -354,7 +354,7 @@ TestCase {
compare(control.second.value, 1.0)
compare(control.second.position, 1.0)
- mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton)
+ mousePress(control, control.leftPadding, control.height - control.bottomPadding, Qt.LeftButton)
compare(firstPressedSpy.count, 5)
compare(secondPressedSpy.count, 2)
compare(control.first.pressed, true)
@@ -745,7 +745,8 @@ TestCase {
control.first.value = 0
control.locale = Qt.locale("ar_EG")
- mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton)
+ mousePress(control, control.first.handle.x + control.first.handle.width / 2,
+ control.first.handle.y + control.first.handle.height / 2, Qt.LeftButton)
compare(firstPressedSpy.count, 3)
compare(control.first.pressed, true)
compare(control.first.value, 0.0)
@@ -774,22 +775,22 @@ TestCase {
compare(control.first.visualPosition, 0.5)
}
- function test_snapMode_data() {
+ function test_snapMode_data(immediate) {
return [
{ tag: "NoSnap", snapMode: RangeSlider.NoSnap, from: 0, to: 2, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] },
{ tag: "SnapAlways (0..2)", snapMode: RangeSlider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] },
{ tag: "SnapAlways (1..3)", snapMode: RangeSlider.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] },
- { tag: "SnapAlways (-1..1)", snapMode: RangeSlider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] },
- { tag: "SnapAlways (1..-1)", snapMode: RangeSlider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] },
+ { tag: "SnapAlways (-1..1)", snapMode: RangeSlider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] },
+ { tag: "SnapAlways (1..-1)", snapMode: RangeSlider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] },
{ tag: "SnapOnRelease (0..2)", snapMode: RangeSlider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] },
{ tag: "SnapOnRelease (1..3)", snapMode: RangeSlider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] },
- { tag: "SnapOnRelease (-1..1)", snapMode: RangeSlider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] },
- { tag: "SnapOnRelease (1..-1)", snapMode: RangeSlider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] }
+ { tag: "SnapOnRelease (-1..1)", snapMode: RangeSlider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] },
+ { tag: "SnapOnRelease (1..-1)", snapMode: RangeSlider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }
]
}
function test_snapMode_mouse_data() {
- return test_snapMode_data()
+ return test_snapMode_data(true)
}
function test_snapMode_mouse(data) {
@@ -799,28 +800,26 @@ TestCase {
control.first.value = 0
control.second.value = data.to
- function sliderCompare(left, right) {
- return Math.abs(left - right) < 0.05
- }
+ var fuzz = 0.05
- mousePress(control, control.first.handle.x, control.first.handle.y)
+ mousePress(control, control.leftPadding)
compare(control.first.pressed, true)
compare(control.first.value, data.values[0])
compare(control.first.position, data.positions[0])
mouseMove(control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2))
compare(control.first.pressed, true)
- verify(sliderCompare(control.first.value, data.values[1]))
- verify(sliderCompare(control.first.position, data.positions[1]))
+ fuzzyCompare(control.first.value, data.values[1], fuzz)
+ fuzzyCompare(control.first.position, data.positions[1], fuzz)
mouseRelease(control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2))
compare(control.first.pressed, false)
- verify(sliderCompare(control.first.value, data.values[2]))
- verify(sliderCompare(control.first.position, data.positions[2]))
+ fuzzyCompare(control.first.value, data.values[2], fuzz)
+ fuzzyCompare(control.first.position, data.positions[2], fuzz)
}
function test_snapMode_touch_data() {
- return test_snapMode_data()
+ return test_snapMode_data(false)
}
function test_snapMode_touch(data) {
@@ -830,9 +829,7 @@ TestCase {
control.first.value = 0
control.second.value = data.to
- function sliderCompare(left, right) {
- return Math.abs(left - right) < 0.05
- }
+ var fuzz = 0.05
var touch = touchEvent(control)
touch.press(0, control, control.first.handle.x, control.first.handle.y).commit()
@@ -842,13 +839,13 @@ TestCase {
touch.move(0, control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2)).commit()
compare(control.first.pressed, true)
- verify(sliderCompare(control.first.value, data.values[1]))
- verify(sliderCompare(control.first.position, data.positions[1]))
+ fuzzyCompare(control.first.value, data.values[1], fuzz)
+ fuzzyCompare(control.first.position, data.positions[1], fuzz)
touch.release(0, control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2)).commit()
compare(control.first.pressed, false)
- verify(sliderCompare(control.first.value, data.values[2]))
- verify(sliderCompare(control.first.position, data.positions[2]))
+ fuzzyCompare(control.first.value, data.values[2], fuzz)
+ fuzzyCompare(control.first.position, data.positions[2], fuzz)
}
function test_focus() {
diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml
index 26cb305e..240f734f 100644
--- a/tests/auto/controls/data/tst_slider.qml
+++ b/tests/auto/controls/data/tst_slider.qml
@@ -236,7 +236,7 @@ TestCase {
var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"})
verify(movedSpy.valid)
- mousePress(control, 0, 0, Qt.LeftButton)
+ mousePress(control, 0, control.height, Qt.LeftButton)
compare(pressedSpy.count, ++pressedCount)
compare(movedSpy.count, movedCount)
compare(control.pressed, true)
@@ -265,17 +265,17 @@ TestCase {
compare(control.value, 0.5)
compare(control.position, 0.5)
- mousePress(control, control.width, control.height, Qt.LeftButton)
+ mousePress(control, control.width, 0, Qt.LeftButton)
compare(pressedSpy.count, ++pressedCount)
- compare(movedSpy.count, movedCount)
+ compare(movedSpy.count, ++movedCount)
compare(control.pressed, true)
- compare(control.value, 0.5)
- compare(control.position, 0.5)
+ compare(control.value, data.live ? 1.0 : 0.5)
+ compare(control.position, 1.0)
// maximum on the right in horizontal vs. at the top in vertical
mouseMove(control, control.width * 2, -control.height, 0)
compare(pressedSpy.count, pressedCount)
- compare(movedSpy.count, ++movedCount)
+ compare(movedSpy.count, movedCount)
compare(control.pressed, true)
compare(control.value, data.live ? 1.0 : 0.5)
compare(control.position, 1.0)
@@ -624,8 +624,8 @@ TestCase {
compare(pressedSpy.count, 3)
compare(control.pressed, true)
compare(control.value, 0.0)
- compare(control.position, 0.0)
- compare(control.visualPosition, 1.0)
+ compare(control.position, 1.0)
+ compare(control.visualPosition, 0.0)
mouseMove(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, 0)
compare(pressedSpy.count, 3)
@@ -649,31 +649,29 @@ TestCase {
compare(control.visualPosition, 0.5)
}
- function test_snapMode_data() {
+ function test_snapMode_data(immediate) {
return [
{ tag: "NoSnap", snapMode: Slider.NoSnap, from: 0, to: 2, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] },
{ tag: "SnapAlways (0..2)", snapMode: Slider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] },
{ tag: "SnapAlways (1..3)", snapMode: Slider.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] },
- { tag: "SnapAlways (-1..1)", snapMode: Slider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] },
- { tag: "SnapAlways (1..-1)", snapMode: Slider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] },
+ { tag: "SnapAlways (-1..1)", snapMode: Slider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] },
+ { tag: "SnapAlways (1..-1)", snapMode: Slider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] },
{ tag: "SnapOnRelease (0..2)", snapMode: Slider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] },
{ tag: "SnapOnRelease (1..3)", snapMode: Slider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] },
- { tag: "SnapOnRelease (-1..1)", snapMode: Slider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] },
- { tag: "SnapOnRelease (1..-1)", snapMode: Slider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] }
+ { tag: "SnapOnRelease (-1..1)", snapMode: Slider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] },
+ { tag: "SnapOnRelease (1..-1)", snapMode: Slider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }
]
}
function test_snapMode_mouse_data() {
- return test_snapMode_data()
+ return test_snapMode_data(true)
}
function test_snapMode_mouse(data) {
var control = createTemporaryObject(slider, testCase, {live: false, snapMode: data.snapMode, from: data.from, to: data.to, stepSize: 0.2})
verify(control)
- function sliderCompare(left, right) {
- return Math.abs(left - right) < 0.05
- }
+ var fuzz = 0.05
mousePress(control, control.leftPadding)
compare(control.value, data.values[0])
@@ -681,25 +679,23 @@ TestCase {
mouseMove(control, control.leftPadding + 0.15 * (control.availableWidth + control.handle.width / 2))
- verify(sliderCompare(control.value, data.values[1]))
- verify(sliderCompare(control.position, data.positions[1]))
+ fuzzyCompare(control.value, data.values[1], fuzz)
+ fuzzyCompare(control.position, data.positions[1], fuzz)
mouseRelease(control, control.leftPadding + 0.15 * (control.availableWidth + control.handle.width / 2))
- verify(sliderCompare(control.value, data.values[2]))
- verify(sliderCompare(control.position, data.positions[2]))
+ fuzzyCompare(control.value, data.values[2], fuzz)
+ fuzzyCompare(control.position, data.positions[2], fuzz)
}
function test_snapMode_touch_data() {
- return test_snapMode_data()
+ return test_snapMode_data(false)
}
function test_snapMode_touch(data) {
var control = createTemporaryObject(slider, testCase, {live: false, snapMode: data.snapMode, from: data.from, to: data.to, stepSize: 0.2})
verify(control)
- function sliderCompare(left, right) {
- return Math.abs(left - right) < 0.05
- }
+ var fuzz = 0.05
var touch = touchEvent(control)
touch.press(0, control, control.leftPadding).commit()
@@ -708,12 +704,12 @@ TestCase {
touch.move(0, control, control.leftPadding + 0.15 * (control.availableWidth + control.handle.width / 2)).commit()
- verify(sliderCompare(control.value, data.values[1]))
- verify(sliderCompare(control.position, data.positions[1]))
+ fuzzyCompare(control.value, data.values[1], fuzz)
+ fuzzyCompare(control.position, data.positions[1], fuzz)
touch.release(0, control, control.leftPadding + 0.15 * (control.availableWidth + control.handle.width / 2)).commit()
- verify(sliderCompare(control.value, data.values[2]))
- verify(sliderCompare(control.position, data.positions[2]))
+ fuzzyCompare(control.value, data.values[2], fuzz)
+ fuzzyCompare(control.position, data.positions[2], fuzz)
}
function test_wheel_data() {
diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml
index c56a04de..37bd5222 100644
--- a/tests/auto/controls/data/tst_stackview.qml
+++ b/tests/auto/controls/data/tst_stackview.qml
@@ -1101,4 +1101,13 @@ TestCase {
control.destroy()
}
+
+ function test_resolve() {
+ var control = createTemporaryObject(stackView, testCase)
+ verify(control)
+
+ var item = control.push("TestItem.qml")
+ compare(control.depth, 1)
+ verify(item)
+ }
}
diff --git a/tests/auto/cursor/cursor.pro b/tests/auto/cursor/cursor.pro
new file mode 100644
index 00000000..4948e943
--- /dev/null
+++ b/tests/auto/cursor/cursor.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_cursor
+SOURCES += tst_cursor.cpp
+
+macos:CONFIG -= app_bundle
+
+QT += core-private gui-private qml-private quick-private testlib quicktemplates2-private
+
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += \
+ data/*.qml
diff --git a/tests/auto/cursor/data/buttons.qml b/tests/auto/cursor/data/buttons.qml
new file mode 100644
index 00000000..21226ef5
--- /dev/null
+++ b/tests/auto/cursor/data/buttons.qml
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.2
+
+MouseArea {
+ width: column.width
+ height: column.height
+ cursorShape: Qt.ForbiddenCursor
+
+ Column {
+ id: column
+ padding: 10
+ spacing: 10
+
+ Button {
+ text: "Button"
+ }
+ CheckBox {
+ text: "CheckBox"
+ }
+ CheckDelegate {
+ text: "CheckDelegate"
+ }
+ ItemDelegate {
+ text: "ItemDelegate"
+ }
+ MenuItem {
+ text: "MenuItem"
+ }
+ RadioButton {
+ text: "RadioButton"
+ }
+ RadioDelegate {
+ text: "RadioDelegate"
+ }
+ RoundButton {
+ text: "X"
+ }
+ SwipeDelegate {
+ text: "SwipeDelegate"
+ }
+ Switch {
+ text: "Switch"
+ }
+ SwitchDelegate {
+ text: "SwitchDelegate"
+ }
+ TabButton {
+ text: "TabButton"
+ }
+ ToolButton {
+ text: "ToolButton"
+ }
+ }
+}
diff --git a/tests/auto/cursor/data/containers.qml b/tests/auto/cursor/data/containers.qml
new file mode 100644
index 00000000..09fbbc18
--- /dev/null
+++ b/tests/auto/cursor/data/containers.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.2
+
+MouseArea {
+ width: column.width
+ height: column.height
+ cursorShape: Qt.ForbiddenCursor
+
+ Column {
+ id: column
+ padding: 10
+ spacing: 10
+
+ Page {
+ width: 200
+ height: 20
+ }
+ Pane {
+ width: 200
+ height: 20
+ }
+ ToolBar {
+ width: 200
+ height: 20
+ }
+ }
+}
diff --git a/tests/auto/cursor/data/editable.qml b/tests/auto/cursor/data/editable.qml
new file mode 100644
index 00000000..1956889b
--- /dev/null
+++ b/tests/auto/cursor/data/editable.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.2
+
+MouseArea {
+ width: column.width
+ height: column.height
+ cursorShape: Qt.ForbiddenCursor
+
+ Column {
+ id: column
+ padding: 10
+ spacing: 10
+
+ ComboBox {
+ editable: true
+ model: "ComboBox"
+ }
+ SpinBox {
+ editable: true
+ }
+ }
+}
diff --git a/tests/auto/cursor/data/pageindicator.qml b/tests/auto/cursor/data/pageindicator.qml
new file mode 100644
index 00000000..1e550a78
--- /dev/null
+++ b/tests/auto/cursor/data/pageindicator.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.2
+
+MouseArea {
+ width: 200
+ height: 200
+ cursorShape: Qt.ForbiddenCursor
+
+ PageIndicator {
+ anchors.centerIn: parent
+ }
+}
diff --git a/tests/auto/cursor/data/scrollbar.qml b/tests/auto/cursor/data/scrollbar.qml
new file mode 100644
index 00000000..01dcd2ae
--- /dev/null
+++ b/tests/auto/cursor/data/scrollbar.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.0
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias textArea: textArea
+ property alias scrollBar: scrollBar
+
+ Flickable {
+ anchors.fill: parent
+ TextArea.flickable: TextArea {
+ id: textArea
+ }
+ ScrollBar.vertical: ScrollBar {
+ id: scrollBar
+ }
+ }
+}
diff --git a/tests/auto/cursor/data/sliders.qml b/tests/auto/cursor/data/sliders.qml
new file mode 100644
index 00000000..408e8947
--- /dev/null
+++ b/tests/auto/cursor/data/sliders.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.2
+
+MouseArea {
+ width: column.width
+ height: column.height
+ cursorShape: Qt.ForbiddenCursor
+
+ Column {
+ id: column
+ padding: 10
+ spacing: 10
+
+ Dial {
+ }
+ Slider {
+ }
+ RangeSlider {
+ }
+ }
+}
diff --git a/tests/auto/cursor/tst_cursor.cpp b/tests/auto/cursor/tst_cursor.cpp
new file mode 100644
index 00000000..6256112d
--- /dev/null
+++ b/tests/auto/cursor/tst_cursor.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/qtest.h>
+#include "../shared/visualtestutil.h"
+
+#include <QtQuick/qquickview.h>
+#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
+#include <QtQuickTemplates2/private/qquickcontrol_p.h>
+#include <QtQuickTemplates2/private/qquickpageindicator_p.h>
+#include <QtQuickTemplates2/private/qquickscrollbar_p.h>
+#include <QtQuickTemplates2/private/qquicktextarea_p.h>
+
+using namespace QQuickVisualTestUtil;
+
+class tst_cursor : public QQmlDataTest
+{
+ Q_OBJECT
+
+private slots:
+ void controls_data();
+ void controls();
+ void editable();
+ void pageIndicator();
+ void scrollBar();
+};
+
+void tst_cursor::controls_data()
+{
+ QTest::addColumn<QString>("testFile");
+
+ QTest::newRow("buttons") << "buttons.qml";
+ QTest::newRow("containers") << "containers.qml";
+ QTest::newRow("sliders") << "sliders.qml";
+}
+
+void tst_cursor::controls()
+{
+ QFETCH(QString, testFile);
+
+ QQuickView view(testFileUrl(testFile));
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QQuickItem *mouseArea = view.rootObject();
+ QVERIFY(mouseArea);
+ QCOMPARE(mouseArea->cursor().shape(), Qt::ForbiddenCursor);
+
+ QQuickItem *column = mouseArea->childItems().value(0);
+ QVERIFY(column);
+
+ const auto controls = column->childItems();
+ for (QQuickItem *control : controls) {
+ QCOMPARE(control->cursor().shape(), Qt::ArrowCursor);
+
+ QTest::mouseMove(&view, control->mapToScene(QPointF(-1, -1)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor);
+
+ QTest::mouseMove(&view, control->mapToScene(QPointF(0, 0)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ArrowCursor);
+
+ QTest::mouseMove(&view, control->mapToScene(QPointF(control->width() + 1, control->height() + 1)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor);
+ }
+}
+
+void tst_cursor::editable()
+{
+ QQuickView view(testFileUrl("editable.qml"));
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QQuickItem *mouseArea = view.rootObject();
+ QVERIFY(mouseArea);
+ QCOMPARE(mouseArea->cursor().shape(), Qt::ForbiddenCursor);
+
+ QQuickItem *column = mouseArea->childItems().value(0);
+ QVERIFY(column);
+
+ const auto children = column->childItems();
+ for (QQuickItem *child : children) {
+ QQuickControl *control = qobject_cast<QQuickControl *>(child);
+ QVERIFY(control);
+ QCOMPARE(control->cursor().shape(), Qt::ArrowCursor);
+ QCOMPARE(control->contentItem()->cursor().shape(), Qt::IBeamCursor);
+
+ QTest::mouseMove(&view, control->mapToScene(QPointF(-1, -1)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor);
+
+ QTest::mouseMove(&view, control->mapToScene(QPointF(control->width() / 2, control->height() / 2)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::IBeamCursor);
+
+ control->setProperty("editable", false);
+ QCOMPARE(control->cursor().shape(), Qt::ArrowCursor);
+ QCOMPARE(control->contentItem()->cursor().shape(), Qt::ArrowCursor);
+ QCOMPARE(view.cursor().shape(), Qt::ArrowCursor);
+
+ QTest::mouseMove(&view, control->mapToScene(QPointF(control->width() + 1, control->height() + 1)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor);
+ }
+}
+
+void tst_cursor::pageIndicator()
+{
+ QQuickView view(testFileUrl("pageindicator.qml"));
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QQuickItem *mouseArea = view.rootObject();
+ QVERIFY(mouseArea);
+ QCOMPARE(mouseArea->cursor().shape(), Qt::ForbiddenCursor);
+
+ QQuickPageIndicator *indicator = qobject_cast<QQuickPageIndicator *>(mouseArea->childItems().value(0));
+ QVERIFY(indicator);
+
+ QTest::mouseMove(&view, indicator->mapToScene(QPointF(-1, -1)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor);
+
+ QTest::mouseMove(&view, indicator->mapToScene(QPointF(0, 0)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor);
+
+ indicator->setInteractive(true);
+ QCOMPARE(view.cursor().shape(), Qt::ArrowCursor);
+
+ QTest::mouseMove(&view, indicator->mapToScene(QPointF(indicator->width() + 1, indicator->height() + 1)).toPoint());
+ QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor);
+}
+
+// QTBUG-59629
+void tst_cursor::scrollBar()
+{
+ // Ensure that the mouse cursor has the correct shape when over a scrollbar
+ // which is itself over a text area with IBeamCursor.
+ QQuickApplicationHelper helper(this, QStringLiteral("scrollbar.qml"));
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickScrollBar *scrollBar = helper.appWindow->property("scrollBar").value<QQuickScrollBar*>();
+ QVERIFY(scrollBar);
+
+ QQuickTextArea *textArea = helper.appWindow->property("textArea").value<QQuickTextArea*>();
+ QVERIFY(textArea);
+
+ textArea->setText(QString("\n").repeated(100));
+
+ const QPoint textAreaPos(window->width() / 2, window->height() / 2);
+ QTest::mouseMove(window, textAreaPos);
+ QCOMPARE(window->cursor().shape(), textArea->cursor().shape());
+ QCOMPARE(textArea->cursor().shape(), Qt::CursorShape::IBeamCursor);
+
+ const QPoint scrollBarPos(window->width() - scrollBar->width() / 2, window->height() / 2);
+ QTest::mouseMove(window, scrollBarPos);
+ QVERIFY(scrollBar->isActive());
+ QCOMPARE(window->cursor().shape(), scrollBar->cursor().shape());
+ QCOMPARE(scrollBar->cursor().shape(), Qt::CursorShape::ArrowCursor);
+
+ scrollBar->setInteractive(false);
+ QCOMPARE(window->cursor().shape(), textArea->cursor().shape());
+}
+
+QTEST_MAIN(tst_cursor)
+
+#include "tst_cursor.moc"