Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: .qmake.conf tests/auto/controls/data/tst_scrollindicator.qml Change-Id: I1f5581ae7814c0d4152e4c9b79a30a8af5a3a17b
|
@ -0,0 +1,75 @@
|
|||
Qt 5.9.1 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.9.0.
|
||||
|
||||
For more details, refer to the online documentation included in this
|
||||
distribution. The documentation is also available online:
|
||||
|
||||
http://doc.qt.io/qt-5/index.html
|
||||
|
||||
The Qt version 5.9 series is binary compatible with the 5.8.x series.
|
||||
Applications compiled for 5.8 will continue to run with 5.9.
|
||||
|
||||
Some of the changes listed in this file include issue tracking numbers
|
||||
corresponding to tasks in the Qt Bug Tracker:
|
||||
|
||||
https://bugreports.qt.io/
|
||||
|
||||
Each of these identifiers can be entered in the bug tracker to obtain more
|
||||
information about a particular change.
|
||||
|
||||
****************************************************************************
|
||||
* General *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-58571] Enabled the use of QML caching at build time.
|
||||
- [QTBUG-61144] Added a configure feature for disabling multi- touch
|
||||
support (configure -no-feature-quicktemplates2-multitouch).
|
||||
|
||||
****************************************************************************
|
||||
* Controls *
|
||||
****************************************************************************
|
||||
|
||||
- ApplicationWindow:
|
||||
* [QTBUG-60893] Fixed access to revisioned members in base classes.
|
||||
|
||||
- ComboBox:
|
||||
* [QTBUG-60684] Fixed an empty popup being shown after model is cleared.
|
||||
|
||||
- Container:
|
||||
* [QTBUG-61310] Fixed a crash that occurred with Repeater under certain
|
||||
circumstances.
|
||||
|
||||
- Menu:
|
||||
* Fixed key navigation to skip separators.
|
||||
|
||||
- Page:
|
||||
* [QTBUG-61109] Fixed the initial content layouting of dynamically created
|
||||
Page instances.
|
||||
|
||||
- Popup:
|
||||
* [QTBUG-61114] Fixed font inheritance for popups.
|
||||
|
||||
- SpinBox:
|
||||
* [QTBUG-61426] Fixed valueModified() to get emitted on repeated value
|
||||
changes during long press.
|
||||
|
||||
- StackView:
|
||||
* Fixed clear() to not emit depthChanged() when the view is empty.
|
||||
|
||||
****************************************************************************
|
||||
* Styles *
|
||||
****************************************************************************
|
||||
|
||||
- QQuickStyle:
|
||||
* [QTBUG-60973] Fixed availableStyles() to exclude debug symbol folders
|
||||
(.dSYM) on macOS.
|
||||
|
||||
Default
|
||||
--------
|
||||
- RangeSlider:
|
||||
* Fixed the second handle to visualize its pressed state.
|
||||
|
||||
Material & Universal
|
||||
--------------------
|
||||
- ScrollBar:
|
||||
* Fixed flashing when calling decrease() or increase() for key navigation.
|
|
@ -83,7 +83,7 @@ ApplicationWindow {
|
|||
|
||||
Image {
|
||||
id: avatar
|
||||
source: "qrc:/" + modelData + ".png"
|
||||
source: "qrc:/" + modelData.replace(" ", "_") + ".png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ Page {
|
|||
|
||||
Image {
|
||||
id: avatar
|
||||
source: "qrc:/" + modelData + ".png"
|
||||
source: "qrc:/" + modelData.replace(" ", "_") + ".png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ Page {
|
|||
|
||||
Image {
|
||||
id: avatar
|
||||
source: "qrc:/" + model.display + ".png"
|
||||
source: "qrc:/" + model.display.replace(" ", "_") + ".png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ Page {
|
|||
|
||||
Image {
|
||||
id: avatar
|
||||
source: !sentByMe ? "qrc:/" + model.author + ".png" : ""
|
||||
source: !sentByMe ? "qrc:/" + model.author.replace(" ", "_") + ".png" : ""
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
|
@ -82,7 +82,7 @@ Page {
|
|||
|
||||
Image {
|
||||
id: avatar
|
||||
source: "qrc:/" + model.display + ".png"
|
||||
source: "qrc:/" + model.display.replace(" ", "_") + ".png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ Page {
|
|||
|
||||
Image {
|
||||
id: avatar
|
||||
source: !sentByMe ? "qrc:/" + model.author + ".png" : ""
|
||||
source: !sentByMe ? "qrc:/" + model.author.replace(" ", "_") + ".png" : ""
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
|
@ -149,7 +149,7 @@ how to navigate between several pages.
|
|||
\printuntil }
|
||||
|
||||
We replace the default \c{MainForm {...}} code block with a Page, which is
|
||||
sized to occupy all the space on the window using the \l{anchors.fill}
|
||||
sized to occupy all the space on the window using the \l {Item::}{anchors.fill}
|
||||
property.
|
||||
|
||||
Then, we assign a \l Label to its \l {Page::}{header} property. Label extends
|
||||
|
@ -245,7 +245,7 @@ Here is our ListView:
|
|||
\section2 Sizing and Positioning
|
||||
|
||||
The first thing we do is set a size for the view. It should fill the available
|
||||
space on the page, so we use \l {Item::anchors}{anchors.fill}. Note that
|
||||
space on the page, so we use \l {Item::}{anchors.fill}. Note that
|
||||
Page ensures that its header and footer have enough of their own space
|
||||
reserved, so the view in this case will sit below the header, for example.
|
||||
|
||||
|
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -1,16 +1,16 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>Albert Einstein.png</file>
|
||||
<file>Albert Einstein@2x.png</file>
|
||||
<file>Albert Einstein@3x.png</file>
|
||||
<file>Albert Einstein@4x.png</file>
|
||||
<file>Ernest Hemingway.png</file>
|
||||
<file>Ernest Hemingway@2x.png</file>
|
||||
<file>Ernest Hemingway@3x.png</file>
|
||||
<file>Ernest Hemingway@4x.png</file>
|
||||
<file>Hans Gude.png</file>
|
||||
<file>Hans Gude@2x.png</file>
|
||||
<file>Hans Gude@3x.png</file>
|
||||
<file>Hans Gude@4x.png</file>
|
||||
<file>Albert_Einstein.png</file>
|
||||
<file>Albert_Einstein@2x.png</file>
|
||||
<file>Albert_Einstein@3x.png</file>
|
||||
<file>Albert_Einstein@4x.png</file>
|
||||
<file>Ernest_Hemingway.png</file>
|
||||
<file>Ernest_Hemingway@2x.png</file>
|
||||
<file>Ernest_Hemingway@3x.png</file>
|
||||
<file>Ernest_Hemingway@4x.png</file>
|
||||
<file>Hans_Gude.png</file>
|
||||
<file>Hans_Gude@2x.png</file>
|
||||
<file>Hans_Gude@3x.png</file>
|
||||
<file>Hans_Gude@4x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -48,6 +48,30 @@ Column {
|
|||
showVerticalAlignment: true
|
||||
}
|
||||
|
||||
Section {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
caption: qsTr("Text Color")
|
||||
|
||||
ColorEditor {
|
||||
caption: qsTr("Text Color")
|
||||
backendValue: backendValues.color
|
||||
supportGradient: false
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
caption: qsTr("Style Color")
|
||||
|
||||
ColorEditor {
|
||||
caption: qsTr("Style Color")
|
||||
backendValue: backendValues.styleColor
|
||||
supportGradient: false
|
||||
}
|
||||
}
|
||||
|
||||
FontSection {
|
||||
width: parent.width
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
#include "qquicktumblerview_p.h"
|
||||
|
||||
#include <QtQml/private/qqmldelegatemodel_p.h>
|
||||
#include <QtQuick/private/qquickitem_p.h>
|
||||
#include <QtQuick/private/qquicklistview_p.h>
|
||||
#include <QtQuick/private/qquickpathview_p.h>
|
||||
|
@ -126,7 +125,17 @@ void QQuickTumblerView::createView()
|
|||
// the count yet, because we rely on the view to tell us the count.
|
||||
if (m_tumbler->wrap()) {
|
||||
if (m_listView) {
|
||||
delete m_listView;
|
||||
// It's necessary to call deleteLater() rather than delete,
|
||||
// as this code is most likely being run in rensponse to a signal
|
||||
// emission somewhere in the list view's internals, so we need to
|
||||
// wait until that has finished.
|
||||
m_listView->deleteLater();
|
||||
QQml_setParent_noEvent(m_listView, nullptr);
|
||||
// The auto tests pass with unparenting the list view alone, but
|
||||
// just to be sure, we unset some other things as well.
|
||||
m_listView->setParentItem(nullptr);
|
||||
m_listView->setVisible(false);
|
||||
m_listView->setModel(QVariant());
|
||||
m_listView = nullptr;
|
||||
}
|
||||
|
||||
|
@ -143,12 +152,16 @@ void QQuickTumblerView::createView()
|
|||
|
||||
// Give the view a size.
|
||||
updateView();
|
||||
// Ensure that the model is set eventually.
|
||||
polish();
|
||||
// Set the model.
|
||||
updateModel();
|
||||
}
|
||||
} else {
|
||||
if (m_pathView) {
|
||||
delete m_pathView;
|
||||
m_pathView->deleteLater();
|
||||
QQml_setParent_noEvent(m_pathView, nullptr);
|
||||
m_pathView->setParentItem(nullptr);
|
||||
m_pathView->setVisible(false);
|
||||
m_pathView->setModel(QVariant());
|
||||
m_pathView = nullptr;
|
||||
}
|
||||
|
||||
|
@ -164,8 +177,8 @@ void QQuickTumblerView::createView()
|
|||
|
||||
// Give the view a size.
|
||||
updateView();
|
||||
// Ensure that the model is set eventually.
|
||||
polish();
|
||||
// Set the model.
|
||||
updateModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,6 +206,56 @@ void QQuickTumblerView::updateView()
|
|||
}
|
||||
}
|
||||
|
||||
void QQuickTumblerView::updateModel()
|
||||
{
|
||||
if (m_pathView && !m_pathView->model().isValid() && m_model.isValid()) {
|
||||
// QQuickPathView::setPathItemCount() resets the offset animation,
|
||||
// so we just skip the animation while constructing the view.
|
||||
const int oldHighlightMoveDuration = m_pathView->highlightMoveDuration();
|
||||
m_pathView->setHighlightMoveDuration(0);
|
||||
|
||||
// Setting model can change the count, which can affect the wrap, which can cause
|
||||
// the current view to be deleted before setModel() is finished, which causes a crash.
|
||||
// Since QQuickTumbler can't know about QQuickTumblerView, we use its private API to
|
||||
// inform it that it should delay setting wrap.
|
||||
QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler);
|
||||
tumblerPrivate->lockWrap();
|
||||
m_pathView->setModel(m_model);
|
||||
tumblerPrivate->unlockWrap();
|
||||
|
||||
// The count-depends-on-wrap behavior could cause wrap to change after
|
||||
// the call above, so we must check that we're still using a PathView.
|
||||
if (m_pathView)
|
||||
m_pathView->setHighlightMoveDuration(oldHighlightMoveDuration);
|
||||
} else if (m_listView && !m_listView->model().isValid() && m_model.isValid()) {
|
||||
const int currentIndex = m_tumbler->currentIndex();
|
||||
QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler);
|
||||
|
||||
// setModel() causes QQuickTumblerPrivate::_q_onViewCountChanged() to
|
||||
// be called called, which calls QQuickTumbler::setCurrentIndex(),
|
||||
// which results in QQuickItemViewPrivate::createHighlightItem() being
|
||||
// called. When the highlight item is created,
|
||||
// QQuickTumblerPrivate::itemChildAdded() is notified and
|
||||
// QQuickTumblerPrivate::_q_updateItemHeights() is called, which causes
|
||||
// a geometry change in the item and createHighlight() is called again.
|
||||
// However, since the highlight item hadn't been assigned yet in the
|
||||
// previous call frame, the "if (highlight) { delete highlight; }"
|
||||
// check doesn't succeed, so the item is never deleted.
|
||||
//
|
||||
// To avoid this, we tell QQuickTumblerPrivate to ignore signals while
|
||||
// setting the model, and manually call _q_onViewCountChanged() to
|
||||
// ensure the correct sequence of calls happens (_q_onViewCountChanged()
|
||||
// has to be within the ignoreSignals scope, because it also generates
|
||||
// recursion otherwise).
|
||||
tumblerPrivate->ignoreSignals = true;
|
||||
m_listView->setModel(m_model);
|
||||
m_listView->setCurrentIndex(currentIndex);
|
||||
|
||||
tumblerPrivate->_q_onViewCountChanged();
|
||||
tumblerPrivate->ignoreSignals = false;
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickTumblerView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
|
||||
{
|
||||
QQuickItem::geometryChanged(newGeometry, oldGeometry);
|
||||
|
@ -223,42 +286,6 @@ void QQuickTumblerView::itemChange(QQuickItem::ItemChange change, const QQuickIt
|
|||
}
|
||||
}
|
||||
|
||||
void QQuickTumblerView::updatePolish()
|
||||
{
|
||||
// There are certain cases where model count changes can potentially cause problems.
|
||||
// An example of this is a ListModel that appends items in a for loop in Component.onCompleted.
|
||||
// If we didn't delay assignment of the model, the PathView/ListView would be deleted in
|
||||
// response to it emitting countChanged(), causing a crash. To avoid this issue,
|
||||
// and to avoid the overhead of count affecting the wrap property, which in turn may
|
||||
// unnecessarily create delegates that are never seen, we delay setting the model. This ensures that
|
||||
// Component.onCompleted would have been finished, for example.
|
||||
if (m_pathView && !m_pathView->model().isValid() && m_model.isValid()) {
|
||||
// QQuickPathView::setPathItemCount() resets the offset animation,
|
||||
// so we just skip the animation while constructing the view.
|
||||
const int oldHighlightMoveDuration = m_pathView->highlightMoveDuration();
|
||||
m_pathView->setHighlightMoveDuration(0);
|
||||
|
||||
// Setting model can change the count, which can affect the wrap, which can cause
|
||||
// the current view to be deleted before setModel() is finished, which causes a crash.
|
||||
// Since QQuickTumbler can't know about QQuickTumblerView, we use its private API to
|
||||
// inform it that it should delay setting wrap.
|
||||
QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler);
|
||||
tumblerPrivate->lockWrap();
|
||||
m_pathView->setModel(m_model);
|
||||
tumblerPrivate->unlockWrap();
|
||||
|
||||
// The count-depends-on-wrap behavior could cause wrap to change after
|
||||
// the call above, so we must check that we're still using a PathView.
|
||||
if (m_pathView)
|
||||
m_pathView->setHighlightMoveDuration(oldHighlightMoveDuration);
|
||||
} else if (m_listView && !m_listView->model().isValid() && m_model.isValid()) {
|
||||
// Usually we'd do this in QQuickTumbler::setWrap(), but that will be too early for polishes.
|
||||
const int currentIndex = m_tumbler->currentIndex();
|
||||
m_listView->setModel(m_model);
|
||||
m_listView->setCurrentIndex(currentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
QQuickItem *QQuickTumblerView::view()
|
||||
{
|
||||
if (!m_tumbler)
|
||||
|
|
|
@ -87,12 +87,12 @@ protected:
|
|||
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
|
||||
void componentComplete() override;
|
||||
void itemChange(ItemChange change, const ItemChangeData &data) override;
|
||||
void updatePolish() override;
|
||||
|
||||
private:
|
||||
QQuickItem *view();
|
||||
void createView();
|
||||
void updateView();
|
||||
void updateModel();
|
||||
|
||||
void wrapChange();
|
||||
|
||||
|
|
|
@ -115,6 +115,13 @@ void QQuickBusyIndicator::setRunning(bool running)
|
|||
emit runningChanged();
|
||||
}
|
||||
|
||||
#if QT_CONFIG(quicktemplates2_multitouch)
|
||||
void QQuickBusyIndicator::touchEvent(QTouchEvent *event)
|
||||
{
|
||||
event->ignore(); // QTBUG-61785
|
||||
}
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(accessibility)
|
||||
QAccessible::Role QQuickBusyIndicator::accessibleRole() const
|
||||
{
|
||||
|
|
|
@ -69,6 +69,10 @@ Q_SIGNALS:
|
|||
void runningChanged();
|
||||
|
||||
protected:
|
||||
#if QT_CONFIG(quicktemplates2_multitouch)
|
||||
void touchEvent(QTouchEvent *event) override;
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(accessibility)
|
||||
QAccessible::Role accessibleRole() const override;
|
||||
#endif
|
||||
|
|
|
@ -1482,13 +1482,8 @@ void QQuickControl::touchEvent(QTouchEvent *event)
|
|||
Q_D(QQuickControl);
|
||||
switch (event->type()) {
|
||||
case QEvent::TouchBegin:
|
||||
for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
|
||||
if (d->acceptTouch(point))
|
||||
d->handlePress(point.pos());
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::TouchUpdate:
|
||||
case QEvent::TouchEnd:
|
||||
for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
|
||||
if (!d->acceptTouch(point))
|
||||
continue;
|
||||
|
@ -1509,13 +1504,6 @@ void QQuickControl::touchEvent(QTouchEvent *event)
|
|||
}
|
||||
break;
|
||||
|
||||
case QEvent::TouchEnd:
|
||||
for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
|
||||
if (d->acceptTouch(point))
|
||||
d->handleRelease(point.pos());
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::TouchCancel:
|
||||
d->handleUngrab();
|
||||
break;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <QtGui/qstylehints.h>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <QtQml/qqmlinfo.h>
|
||||
#include <QtQuick/private/qquickwindow_p.h>
|
||||
#include <QtQuick/private/qquickanimation_p.h>
|
||||
#include <QtQuick/private/qquicktransition_p.h>
|
||||
|
@ -540,20 +541,32 @@ bool QQuickDrawerPrivate::prepareExitTransition()
|
|||
return QQuickPopupPrivate::prepareExitTransition();
|
||||
}
|
||||
|
||||
void QQuickDrawerPrivate::setEdge(Qt::Edge e)
|
||||
bool QQuickDrawerPrivate::setEdge(Qt::Edge e)
|
||||
{
|
||||
edge = e;
|
||||
if (edge == Qt::LeftEdge || edge == Qt::RightEdge) {
|
||||
Q_Q(QQuickDrawer);
|
||||
switch (e) {
|
||||
case Qt::LeftEdge:
|
||||
case Qt::RightEdge:
|
||||
allowVerticalMove = true;
|
||||
allowVerticalResize = true;
|
||||
allowHorizontalMove = false;
|
||||
allowHorizontalResize = false;
|
||||
} else {
|
||||
break;
|
||||
case Qt::TopEdge:
|
||||
case Qt::BottomEdge:
|
||||
allowVerticalMove = false;
|
||||
allowVerticalResize = false;
|
||||
allowHorizontalMove = true;
|
||||
allowHorizontalResize = true;
|
||||
break;
|
||||
default:
|
||||
qmlWarning(q) << "invalid edge value - valid values are: "
|
||||
<< "Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge";
|
||||
return false;
|
||||
}
|
||||
|
||||
edge = e;
|
||||
return true;
|
||||
}
|
||||
|
||||
QQuickDrawer::QQuickDrawer(QObject *parent)
|
||||
|
@ -588,7 +601,9 @@ void QQuickDrawer::setEdge(Qt::Edge edge)
|
|||
if (d->edge == edge)
|
||||
return;
|
||||
|
||||
d->setEdge(edge);
|
||||
if (!d->setEdge(edge))
|
||||
return;
|
||||
|
||||
if (isComponentComplete())
|
||||
d->reposition();
|
||||
emit edgeChanged();
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
bool prepareEnterTransition() override;
|
||||
bool prepareExitTransition() override;
|
||||
|
||||
void setEdge(Qt::Edge edge);
|
||||
bool setEdge(Qt::Edge edge);
|
||||
|
||||
Qt::Edge edge;
|
||||
qreal offset;
|
||||
|
|
|
@ -150,6 +150,11 @@ bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isTouchEvent(QEvent *event)
|
||||
{
|
||||
return event->type() == QEvent::TouchBegin || event->type() == QEvent::TouchUpdate || event->type() == QEvent::TouchEnd;
|
||||
}
|
||||
|
||||
bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuickPopup *target)
|
||||
{
|
||||
if (target) {
|
||||
|
@ -158,7 +163,7 @@ bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuick
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if (!mouseGrabberPopup) {
|
||||
} else if (!mouseGrabberPopup || isTouchEvent(event)) {
|
||||
// allow non-modal popups to close themselves,
|
||||
// and non-dimming modal popups to block the event
|
||||
const auto popups = stackingOrderPopups();
|
||||
|
|
|
@ -98,11 +98,16 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
QQuickItem *itemAt(const QPoint &pos) const;
|
||||
void updatePressed(bool pressed, const QPoint &pos = QPoint());
|
||||
void handlePress(const QPointF &point) override;
|
||||
void handleMove(const QPointF &point) override;
|
||||
void handleRelease(const QPointF &point) override;
|
||||
void handleUngrab() override;
|
||||
|
||||
QQuickItem *itemAt(const QPointF &pos) const;
|
||||
void updatePressed(bool pressed, const QPointF &pos = QPointF());
|
||||
void setContextProperty(QQuickItem *item, const QString &name, const QVariant &value);
|
||||
|
||||
void itemChildAdded(QQuickItem *, QQuickItem *child);
|
||||
void itemChildAdded(QQuickItem *, QQuickItem *child) override;
|
||||
|
||||
int count;
|
||||
int currentIndex;
|
||||
|
@ -111,7 +116,39 @@ public:
|
|||
QQuickItem *pressedItem;
|
||||
};
|
||||
|
||||
QQuickItem *QQuickPageIndicatorPrivate::itemAt(const QPoint &pos) const
|
||||
void QQuickPageIndicatorPrivate::handlePress(const QPointF &point)
|
||||
{
|
||||
QQuickControlPrivate::handlePress(point);
|
||||
if (interactive)
|
||||
updatePressed(true, point);
|
||||
}
|
||||
|
||||
void QQuickPageIndicatorPrivate::handleMove(const QPointF &point)
|
||||
{
|
||||
QQuickControlPrivate::handleMove(point);
|
||||
if (interactive)
|
||||
updatePressed(true, point);
|
||||
}
|
||||
|
||||
void QQuickPageIndicatorPrivate::handleRelease(const QPointF &point)
|
||||
{
|
||||
Q_Q(QQuickPageIndicator);
|
||||
QQuickControlPrivate::handleRelease(point);
|
||||
if (interactive) {
|
||||
if (pressedItem && contentItem)
|
||||
q->setCurrentIndex(contentItem->childItems().indexOf(pressedItem));
|
||||
updatePressed(false);
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickPageIndicatorPrivate::handleUngrab()
|
||||
{
|
||||
QQuickControlPrivate::handleUngrab();
|
||||
if (interactive)
|
||||
updatePressed(false);
|
||||
}
|
||||
|
||||
QQuickItem *QQuickPageIndicatorPrivate::itemAt(const QPointF &pos) const
|
||||
{
|
||||
Q_Q(const QQuickPageIndicator);
|
||||
if (!contentItem || !q->contains(pos))
|
||||
|
@ -144,7 +181,7 @@ QQuickItem *QQuickPageIndicatorPrivate::itemAt(const QPoint &pos) const
|
|||
return nearest;
|
||||
}
|
||||
|
||||
void QQuickPageIndicatorPrivate::updatePressed(bool pressed, const QPoint &pos)
|
||||
void QQuickPageIndicatorPrivate::updatePressed(bool pressed, const QPointF &pos)
|
||||
{
|
||||
QQuickItem *prevItem = pressedItem;
|
||||
pressedItem = pressed ? itemAt(pos) : nullptr;
|
||||
|
@ -298,41 +335,16 @@ void QQuickPageIndicator::contentItemChange(QQuickItem *newItem, QQuickItem *old
|
|||
QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children);
|
||||
}
|
||||
|
||||
void QQuickPageIndicator::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_D(QQuickPageIndicator);
|
||||
if (d->interactive) {
|
||||
d->updatePressed(true, event->pos());
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickPageIndicator::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_D(QQuickPageIndicator);
|
||||
if (d->interactive) {
|
||||
d->updatePressed(true, event->pos());
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickPageIndicator::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_D(QQuickPageIndicator);
|
||||
if (d->interactive) {
|
||||
if (d->pressedItem)
|
||||
setCurrentIndex(d->contentItem->childItems().indexOf(d->pressedItem));
|
||||
d->updatePressed(false);
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickPageIndicator::mouseUngrabEvent()
|
||||
#if QT_CONFIG(quicktemplates2_multitouch)
|
||||
void QQuickPageIndicator::touchEvent(QTouchEvent *event)
|
||||
{
|
||||
Q_D(QQuickPageIndicator);
|
||||
if (d->interactive)
|
||||
d->updatePressed(false);
|
||||
QQuickControl::touchEvent(event);
|
||||
else
|
||||
event->ignore(); // QTBUG-61785
|
||||
}
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(accessibility)
|
||||
QAccessible::Role QQuickPageIndicator::accessibleRole() const
|
||||
|
|
|
@ -87,10 +87,9 @@ Q_SIGNALS:
|
|||
protected:
|
||||
void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseUngrabEvent() override;
|
||||
#if QT_CONFIG(quicktemplates2_multitouch)
|
||||
void touchEvent(QTouchEvent *event) override;
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(accessibility)
|
||||
QAccessible::Role accessibleRole() const override;
|
||||
|
|
|
@ -384,15 +384,10 @@ bool QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event)
|
|||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::TouchBegin:
|
||||
for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
|
||||
if (acceptTouch(point))
|
||||
return handlePress(item, item->mapToScene(point.pos()), event->timestamp());
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::TouchUpdate:
|
||||
case QEvent::TouchEnd:
|
||||
for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
|
||||
if (!acceptTouch(point))
|
||||
if (!acceptTouch(point) && !blockInput(item, point.pos()))
|
||||
continue;
|
||||
|
||||
switch (point.state()) {
|
||||
|
@ -408,13 +403,6 @@ bool QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event)
|
|||
}
|
||||
break;
|
||||
|
||||
case QEvent::TouchEnd:
|
||||
for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
|
||||
if (acceptTouch(point))
|
||||
return handleRelease(item, item->mapToScene(point.pos()), event->timestamp());
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::TouchCancel:
|
||||
handleUngrab();
|
||||
break;
|
||||
|
@ -493,7 +481,13 @@ void QQuickPopupPrivate::finalizeExitTransition()
|
|||
destroyOverlay();
|
||||
|
||||
if (hadActiveFocusBeforeExitTransition && window) {
|
||||
if (!qobject_cast<QQuickPopupItem *>(window->activeFocusItem())) {
|
||||
// restore focus to the next popup in chain, or to the window content if there are no other popups open
|
||||
QQuickPopup *popup = nullptr;
|
||||
if (QQuickOverlay *overlay = QQuickOverlay::overlay(window))
|
||||
popup = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups().value(0);
|
||||
if (popup && popup->hasFocus()) {
|
||||
popup->forceActiveFocus();
|
||||
} else {
|
||||
QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window);
|
||||
if (applicationWindow)
|
||||
applicationWindow->contentItem()->setFocus(true);
|
||||
|
|
|
@ -567,6 +567,13 @@ void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical)
|
|||
emit verticalChanged();
|
||||
}
|
||||
|
||||
#if QT_CONFIG(quicktemplates2_multitouch)
|
||||
void QQuickScrollIndicator::touchEvent(QTouchEvent *event)
|
||||
{
|
||||
event->ignore(); // QTBUG-61785
|
||||
}
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(accessibility)
|
||||
QAccessible::Role QQuickScrollIndicator::accessibleRole() const
|
||||
{
|
||||
|
|
|
@ -94,6 +94,10 @@ Q_SIGNALS:
|
|||
void orientationChanged();
|
||||
|
||||
protected:
|
||||
#if QT_CONFIG(quicktemplates2_multitouch)
|
||||
void touchEvent(QTouchEvent *event) override;
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(accessibility)
|
||||
QAccessible::Role accessibleRole() const override;
|
||||
#endif
|
||||
|
|
|
@ -97,7 +97,8 @@ QQuickTumblerPrivate::QQuickTumblerPrivate()
|
|||
currentIndex(-1),
|
||||
pendingCurrentIndex(-1),
|
||||
ignoreCurrentIndexChanges(false),
|
||||
count(0)
|
||||
count(0),
|
||||
ignoreSignals(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -163,6 +164,9 @@ QQuickTumblerPrivate *QQuickTumblerPrivate::get(QQuickTumbler *tumbler)
|
|||
|
||||
void QQuickTumblerPrivate::_q_updateItemHeights()
|
||||
{
|
||||
if (ignoreSignals)
|
||||
return;
|
||||
|
||||
// Can't use our own private padding members here, as the padding property might be set,
|
||||
// which doesn't affect them, only their getters.
|
||||
Q_Q(const QQuickTumbler);
|
||||
|
@ -174,6 +178,9 @@ void QQuickTumblerPrivate::_q_updateItemHeights()
|
|||
|
||||
void QQuickTumblerPrivate::_q_updateItemWidths()
|
||||
{
|
||||
if (ignoreSignals)
|
||||
return;
|
||||
|
||||
Q_Q(const QQuickTumbler);
|
||||
const qreal availableWidth = q->availableWidth();
|
||||
const auto items = viewContentItemChildItems();
|
||||
|
@ -195,6 +202,8 @@ void QQuickTumblerPrivate::_q_onViewCurrentIndexChanged()
|
|||
void QQuickTumblerPrivate::_q_onViewCountChanged()
|
||||
{
|
||||
Q_Q(QQuickTumbler);
|
||||
if (ignoreSignals)
|
||||
return;
|
||||
|
||||
setCount(view->property("count").toInt());
|
||||
|
||||
|
@ -336,7 +345,9 @@ void QQuickTumbler::setCurrentIndex(int currentIndex)
|
|||
couldSet = true;
|
||||
} else {
|
||||
d->ignoreCurrentIndexChanges = true;
|
||||
d->ignoreSignals = true;
|
||||
d->view->setProperty("currentIndex", currentIndex);
|
||||
d->ignoreSignals = false;
|
||||
d->ignoreCurrentIndexChanges = false;
|
||||
|
||||
couldSet = d->view->property("currentIndex").toInt() == currentIndex;
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
int pendingCurrentIndex;
|
||||
bool ignoreCurrentIndexChanges;
|
||||
int count;
|
||||
bool ignoreSignals;
|
||||
|
||||
void _q_updateItemHeights();
|
||||
void _q_updateItemWidths();
|
||||
|
|
|
@ -57,9 +57,12 @@ ApplicationWindow {
|
|||
visible: true
|
||||
|
||||
signal focusScopeKeyPressed
|
||||
signal focusPopupKeyPressed
|
||||
|
||||
property alias fileMenu: fileMenu
|
||||
property alias toolButton: toolButton
|
||||
property alias focusScope: focusScope
|
||||
property alias focusPopup: focusPopup
|
||||
|
||||
header: ToolBar {
|
||||
ToolButton {
|
||||
|
@ -92,5 +95,17 @@ ApplicationWindow {
|
|||
|
||||
Keys.onSpacePressed: focusScopeKeyPressed()
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: focusPopup
|
||||
focus: true
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Item {
|
||||
focus: true
|
||||
Keys.onSpacePressed: focusPopupKeyPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include <QtQuickTemplates2/private/qquickoverlay_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickcontrol_p.h>
|
||||
#include <QtQuickTemplates2/private/qquicklabel_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickmenu_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickpopup_p.h>
|
||||
#include <QtQuickTemplates2/private/qquicktextarea_p.h>
|
||||
#include <QtQuickTemplates2/private/qquicktextfield_p.h>
|
||||
#include <QtQuickControls2/private/qquickproxytheme_p.h>
|
||||
|
@ -713,9 +715,9 @@ void tst_applicationwindow::focusAfterPopupClosed()
|
|||
QVERIFY(focusScope);
|
||||
QVERIFY(focusScope->hasActiveFocus());
|
||||
|
||||
QSignalSpy spy(window.data(), SIGNAL(focusScopeKeyPressed()));
|
||||
QSignalSpy focusScopeSpy(window.data(), SIGNAL(focusScopeKeyPressed()));
|
||||
QTest::keyClick(window.data(), Qt::Key_Space);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(focusScopeSpy.count(), 1);
|
||||
|
||||
// Open the menu.
|
||||
QQuickItem* toolButton = window->property("toolButton").value<QQuickItem*>();
|
||||
|
@ -726,14 +728,48 @@ void tst_applicationwindow::focusAfterPopupClosed()
|
|||
|
||||
// The FocusScope shouldn't receive any key events while the menu is open.
|
||||
QTest::keyClick(window.data(), Qt::Key_Space);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(focusScopeSpy.count(), 1);
|
||||
|
||||
// Close the menu. The FocusScope should regain focus.
|
||||
QTest::keyClick(window.data(), Qt::Key_Escape);
|
||||
QVERIFY(focusScope->hasActiveFocus());
|
||||
|
||||
QTest::keyClick(window.data(), Qt::Key_Space);
|
||||
QCOMPARE(spy.count(), 2);
|
||||
QCOMPARE(focusScopeSpy.count(), 2);
|
||||
|
||||
QQuickPopup *focusPopup = window->property("focusPopup").value<QQuickPopup*>();
|
||||
QVERIFY(focusPopup);
|
||||
QVERIFY(!focusPopup->hasActiveFocus());
|
||||
|
||||
focusPopup->open();
|
||||
QVERIFY(focusPopup->isVisible());
|
||||
|
||||
QSignalSpy focusPopupSpy(window.data(), SIGNAL(focusPopupKeyPressed()));
|
||||
QTest::keyClick(window.data(), Qt::Key_Space);
|
||||
QCOMPARE(focusPopupSpy.count(), 1);
|
||||
|
||||
QQuickMenu *fileMenu = window->property("fileMenu").value<QQuickMenu*>();
|
||||
QVERIFY(fileMenu);
|
||||
fileMenu->open();
|
||||
QVERIFY(fileMenu->isVisible());
|
||||
|
||||
// The Popup shouldn't receive any key events while the menu is open.
|
||||
QTest::keyClick(window.data(), Qt::Key_Space);
|
||||
QCOMPARE(focusPopupSpy.count(), 1);
|
||||
|
||||
// Close the menu. The Popup should regain focus.
|
||||
QTest::keyClick(window.data(), Qt::Key_Escape);
|
||||
QVERIFY(focusPopup->hasActiveFocus());
|
||||
|
||||
QTest::keyClick(window.data(), Qt::Key_Space);
|
||||
QCOMPARE(focusPopupSpy.count(), 2);
|
||||
|
||||
// Close the popup. The FocusScope should regain focus.
|
||||
QTest::keyClick(window.data(), Qt::Key_Escape);
|
||||
QVERIFY(focusScope->hasActiveFocus());
|
||||
|
||||
QTest::keyClick(window.data(), Qt::Key_Space);
|
||||
QCOMPARE(focusScopeSpy.count(), 3);
|
||||
}
|
||||
|
||||
void tst_applicationwindow::clearFocusOnDestruction()
|
||||
|
|
|
@ -87,6 +87,7 @@ Row {
|
|||
id: yearTumbler
|
||||
objectName: "yearTumbler"
|
||||
model: ListModel {
|
||||
objectName: "yearTumblerListModel"
|
||||
Component.onCompleted: {
|
||||
for (var i = 2000; i < 2100; ++i) {
|
||||
append({value: i.toString()});
|
||||
|
|
|
@ -65,6 +65,11 @@ TestCase {
|
|||
BusyIndicator { }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mouseArea
|
||||
MouseArea { }
|
||||
}
|
||||
|
||||
function test_running() {
|
||||
var control = createTemporaryObject(busyIndicator, testCase)
|
||||
verify(control)
|
||||
|
@ -73,4 +78,26 @@ TestCase {
|
|||
control.running = false
|
||||
compare(control.running, false)
|
||||
}
|
||||
|
||||
// QTBUG-61785
|
||||
function test_mouseArea() {
|
||||
var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height})
|
||||
verify(ma)
|
||||
|
||||
var control = busyIndicator.createObject(ma, {width: testCase.width, height: testCase.height})
|
||||
verify(control)
|
||||
|
||||
mousePress(control)
|
||||
verify(ma.pressed)
|
||||
|
||||
mouseRelease(control)
|
||||
verify(!ma.pressed)
|
||||
|
||||
var touch = touchEvent(control)
|
||||
touch.press(0, control).commit()
|
||||
verify(ma.pressed)
|
||||
|
||||
touch.release(0, control).commit()
|
||||
verify(!ma.pressed)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,16 @@ TestCase {
|
|||
compare(control.parent, Overlay.overlay)
|
||||
}
|
||||
|
||||
function test_invalidEdge() {
|
||||
var control = createTemporaryObject(drawer, testCase)
|
||||
compare(control.edge, Qt.LeftEdge)
|
||||
|
||||
// Test an invalid value - it should warn and ignore it.
|
||||
ignoreWarning(Qt.resolvedUrl("tst_drawer.qml") + ":65:9: QML Drawer: invalid edge value - valid values are: Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge")
|
||||
control.edge = Drawer.Right
|
||||
compare(control.edge, Qt.LeftEdge)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: rectDrawer
|
||||
|
||||
|
|
|
@ -65,6 +65,11 @@ TestCase {
|
|||
PageIndicator { }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mouseArea
|
||||
MouseArea { }
|
||||
}
|
||||
|
||||
function test_count() {
|
||||
var control = createTemporaryObject(pageIndicator, testCase)
|
||||
verify(control)
|
||||
|
@ -83,20 +88,35 @@ TestCase {
|
|||
compare(control.currentIndex, 5)
|
||||
}
|
||||
|
||||
function test_interactive() {
|
||||
function test_interactive_data() {
|
||||
return [
|
||||
{ tag: "mouse", touch: false },
|
||||
{ tag: "touch", touch: true }
|
||||
]
|
||||
}
|
||||
|
||||
function test_interactive(data) {
|
||||
var control = createTemporaryObject(pageIndicator, testCase, {count: 5, spacing: 10, padding: 10})
|
||||
verify(control)
|
||||
|
||||
verify(!control.interactive)
|
||||
compare(control.currentIndex, 0)
|
||||
|
||||
mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton)
|
||||
var touch = touchEvent(control)
|
||||
|
||||
if (data.touch)
|
||||
touch.press(0, control).commit().release(0, control).commit()
|
||||
else
|
||||
mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton)
|
||||
compare(control.currentIndex, 0)
|
||||
|
||||
control.interactive = true
|
||||
verify(control.interactive)
|
||||
|
||||
mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton)
|
||||
if (data.touch)
|
||||
touch.press(0, control).commit().release(0, control).commit()
|
||||
else
|
||||
mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton)
|
||||
compare(control.currentIndex, 2)
|
||||
|
||||
// test also clicking outside delegates => the nearest should be selected
|
||||
|
@ -108,10 +128,44 @@ TestCase {
|
|||
compare(control.currentIndex, -1)
|
||||
|
||||
var pos = control.mapFromItem(child, x, y)
|
||||
mouseClick(control, pos.x, pos.y, Qt.LeftButton)
|
||||
if (data.touch)
|
||||
touch.press(0, control, pos.x, pos.y).commit().release(0, control, pos.x, pos.y).commit()
|
||||
else
|
||||
mouseClick(control, pos.x, pos.y, Qt.LeftButton)
|
||||
compare(control.currentIndex, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function test_mouseArea_data() {
|
||||
return [
|
||||
{ tag: "interactive", interactive: true },
|
||||
{ tag: "non-interactive", interactive: false }
|
||||
]
|
||||
}
|
||||
|
||||
// QTBUG-61785
|
||||
function test_mouseArea(data) {
|
||||
var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height})
|
||||
verify(ma)
|
||||
|
||||
var control = pageIndicator.createObject(ma, {count: 5, interactive: data.interactive, width: testCase.width, height: testCase.height})
|
||||
verify(control)
|
||||
|
||||
compare(control.interactive, data.interactive)
|
||||
|
||||
mousePress(control)
|
||||
compare(ma.pressed, !data.interactive)
|
||||
|
||||
mouseRelease(control)
|
||||
verify(!ma.pressed)
|
||||
|
||||
var touch = touchEvent(control)
|
||||
touch.press(0, control).commit()
|
||||
compare(ma.pressed, !data.interactive)
|
||||
|
||||
touch.release(0, control).commit()
|
||||
verify(!ma.pressed)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,11 @@ TestCase {
|
|||
ScrollIndicator { }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mouseArea
|
||||
MouseArea { }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: flickable
|
||||
Flickable {
|
||||
|
@ -231,4 +236,26 @@ TestCase {
|
|||
compare(control.horizontal, true)
|
||||
compare(control.vertical, false)
|
||||
}
|
||||
|
||||
// QTBUG-61785
|
||||
function test_mouseArea() {
|
||||
var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height})
|
||||
verify(ma)
|
||||
|
||||
var control = scrollIndicator.createObject(ma, {active: true, size: 0.9, width: testCase.width, height: testCase.height})
|
||||
verify(control)
|
||||
|
||||
mousePress(control)
|
||||
verify(ma.pressed)
|
||||
|
||||
mouseRelease(control)
|
||||
verify(!ma.pressed)
|
||||
|
||||
var touch = touchEvent(control)
|
||||
touch.press(0, control).commit()
|
||||
verify(ma.pressed)
|
||||
|
||||
touch.release(0, control).commit()
|
||||
verify(!ma.pressed)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,7 +389,7 @@ TestCase {
|
|||
compare(tumbler.monthTumbler.currentIndex, 0);
|
||||
compare(tumbler.monthTumbler.count, 12);
|
||||
compare(tumbler.yearTumbler.currentIndex, 0);
|
||||
compare(tumbler.yearTumbler.count, 100);
|
||||
tryCompare(tumbler.yearTumbler, "count", 100);
|
||||
|
||||
verify(findView(tumbler.dayTumbler).children.length >= tumbler.dayTumbler.visibleItemCount);
|
||||
verify(findView(tumbler.monthTumbler).children.length >= tumbler.monthTumbler.visibleItemCount);
|
||||
|
@ -1057,4 +1057,41 @@ TestCase {
|
|||
compare(tumbler.moving, true)
|
||||
tryCompare(tumbler, "moving", false)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: qtbug61374Component
|
||||
|
||||
Row {
|
||||
property alias tumbler: tumbler
|
||||
property alias label: label
|
||||
|
||||
Component.onCompleted: {
|
||||
tumbler.currentIndex = 2
|
||||
}
|
||||
|
||||
Tumbler {
|
||||
id: tumbler
|
||||
model: 5
|
||||
// ...
|
||||
}
|
||||
|
||||
Label {
|
||||
id: label
|
||||
text: tumbler.currentItem.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function test_qtbug61374() {
|
||||
var row = createTemporaryObject(qtbug61374Component, testCase);
|
||||
verify(row);
|
||||
|
||||
var tumbler = row.tumbler;
|
||||
tryCompare(tumbler, "currentIndex", 2);
|
||||
|
||||
tumblerView = findView(tumbler);
|
||||
|
||||
var label = row.label;
|
||||
compare(label.text, "2");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,6 +307,40 @@ void tst_popup::overlay()
|
|||
|
||||
QVERIFY(!popup->isVisible());
|
||||
QCOMPARE(overlay->isVisible(), popup->isVisible());
|
||||
|
||||
// multi-touch
|
||||
popup->open();
|
||||
QVERIFY(popup->isVisible());
|
||||
QVERIFY(overlay->isVisible());
|
||||
QVERIFY(!button->isPressed());
|
||||
|
||||
QTest::touchEvent(window, device.data()).press(0, button->mapToScene(QPointF(1, 1)).toPoint());
|
||||
QVERIFY(popup->isVisible());
|
||||
QVERIFY(overlay->isVisible());
|
||||
QCOMPARE(button->isPressed(), !modal);
|
||||
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
|
||||
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
|
||||
|
||||
QTest::touchEvent(window, device.data()).stationary(0).press(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
|
||||
QVERIFY(popup->isVisible());
|
||||
QVERIFY(overlay->isVisible());
|
||||
QCOMPARE(button->isPressed(), !modal);
|
||||
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
|
||||
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
|
||||
|
||||
QTest::touchEvent(window, device.data()).release(0, button->mapToScene(QPointF(1, 1)).toPoint()).stationary(1);
|
||||
QVERIFY(!popup->isVisible());
|
||||
QVERIFY(!overlay->isVisible());
|
||||
QVERIFY(!button->isPressed());
|
||||
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
|
||||
QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount);
|
||||
|
||||
QTest::touchEvent(window, device.data()).release(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
|
||||
QVERIFY(!popup->isVisible());
|
||||
QVERIFY(!overlay->isVisible());
|
||||
QVERIFY(!button->isPressed());
|
||||
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
|
||||
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
|
||||
}
|
||||
|
||||
void tst_popup::zOrder_data()
|
||||
|
|