diff options
author | Liang Qi <liang.qi@qt.io> | 2018-06-25 10:49:57 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-06-25 10:49:57 +0200 |
commit | 66a781692a4d21ba4c8a124cb4be84e4e2ffa742 (patch) | |
tree | 4fe9261e26281ddb5f1444563cda53c8bf39d978 | |
parent | 7fec7105b7f6119135aafd6f9ee609128125d594 (diff) | |
parent | d5fbbddd7794265f24d392d33c4874ac756cb9c9 (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts:
src/imports/controls/imagine/TextArea.qml
src/imports/controls/imagine/TextField.qml
tests/auto/controls/data/tst_tumbler.qml
Change-Id: I25a8228a4299fb7a53db70b7223663a1637ed933
-rw-r--r-- | dist/changes-5.11.1 | 25 | ||||
-rw-r--r-- | src/imports/controls/TextArea.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/TextField.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/doc/src/qtquickcontrols2-imagine.qdoc | 54 | ||||
-rw-r--r-- | src/imports/controls/doc/src/qtquickcontrols2-index.qdoc | 9 | ||||
-rw-r--r-- | src/imports/controls/fusion/TextArea.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/fusion/TextField.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/imagine/TextArea.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/imagine/TextField.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/material/TextArea.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/material/TextField.qml | 2 | ||||
-rw-r--r-- | src/imports/controls/universal/TextArea.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/universal/TextField.qml | 1 | ||||
-rw-r--r-- | src/quickcontrols2/qquicktumblerview.cpp | 6 | ||||
-rw-r--r-- | src/quicktemplates2/qquickspinbox.cpp | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktumbler.cpp | 149 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktumbler_p_p.h | 13 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_tumbler.qml | 66 |
18 files changed, 265 insertions, 70 deletions
diff --git a/dist/changes-5.11.1 b/dist/changes-5.11.1 new file mode 100644 index 00000000..5680f38b --- /dev/null +++ b/dist/changes-5.11.1 @@ -0,0 +1,25 @@ +Qt 5.11.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.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.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +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. + +**************************************************************************** +* Qt 5.11.1 Changes * +**************************************************************************** + + - [QTBUG-67684] ComboBox: don't block the escape/back key + - [QTBUG-67684] ComboBox: reset when hidden diff --git a/src/imports/controls/TextArea.qml b/src/imports/controls/TextArea.qml index 2250cb5e..ff252bba 100644 --- a/src/imports/controls/TextArea.qml +++ b/src/imports/controls/TextArea.qml @@ -70,5 +70,6 @@ T.TextArea { verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight + renderType: control.renderType } } diff --git a/src/imports/controls/TextField.qml b/src/imports/controls/TextField.qml index 58de180e..aa57da81 100644 --- a/src/imports/controls/TextField.qml +++ b/src/imports/controls/TextField.qml @@ -70,6 +70,7 @@ T.TextField { verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight + renderType: control.renderType } background: Rectangle { diff --git a/src/imports/controls/doc/src/qtquickcontrols2-imagine.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-imagine.qdoc index 9f0010c4..f24f82a9 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-imagine.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-imagine.qdoc @@ -2358,6 +2358,60 @@ \image qtquickcontrols2-imagine-9-patch-inset-boundaries.png + \section3 Exporting 9-Patch Images + + Various vector and bitmap editors can be used to create 9-patch images + suitable for use with the Imagine style. The following sections briefly + explain the export process for each editor, and the last section explains + how to ensure the exported images are 9-patch-conformant. + + \section4 Illustrator + + See Adobe's + \l {https://helpx.adobe.com/in/illustrator/using/collect-assets-export-for-screens.html#panel} + {Asset Export panel} documentation. + + \section4 Inkscape + + The \l {https://github.com/mitchcurtis/inkscape-9-patch-export} + {Inkscape 9-Patch Export Extension} can be used to export assets with + Inkscape. + + \section4 Photoshop + + See Adobe's + \l {https://helpx.adobe.com/photoshop/using/generate-assets-layers.html} + {Generate image assets from layers} documentation. + + \section4 Sketch + + See Sketch's \l {https://sketchapp.com/docs/exporting/}{Exporting} documentation. + + Qt Quick Controls 2 also provides a + \l {http://code.qt.io/cgit/qt/qtquickcontrols2.git/tree/src/imports/controls/imagine/design} + {plugin} for Sketch that automatically fixes the thickness of the 9-patch lines + after the assets are exported. To install this file, double-click on it. + Once Sketch has confirmed that the 9-patch export plugin has been installed, + the plugin will automatically process images when they are exported. + + \section4 Fixing 9-Patch Lines + + When exporting 9-patch images in several DPI variants (\c {@2x}, \c {@3x}, + etc.), the 9-patch lines will typically be scaled up along with the image. + There are several ways to fix this, but perhaps the simplest approach is + to use \l {https://www.imagemagick.org/script/mogrify.php}{ImageMagick's mogrify} + tool. The tool has a \c -shave feature that can be used to crop the image + to reduce the thickness of the 9-patch lines: + + \badcode + mogrify -shave 1x1 -path path/to/images *@2x.9.png + mogrify -shave 2x2 -path path/to/images *@3x.9.png + mogrify -shave 3x3 -path path/to/images *@4x.9.png + \endcode + + Regular DPI images (those without the \c @Nx prefix) are not affected, so it + is only necessary to run the command on images intended for high DPI displays. + \section2 Animated Images The \l {https://developers.google.com/speed/webp/}{WebP} and GIF animated diff --git a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc index ba8d7527..8e3a12e7 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc @@ -65,6 +65,15 @@ For more details, see \l {Getting Started with Qt Quick Controls 2}. + \section2 Building From Source + + When building from source, ensure that the \l {Qt Graphical Effects} module + is also built, as Qt Quick Controls 2 requires it. + + The \l {Qt Image Formats} module is recommended, but not + required. It provides support for the \c {.webp} format used by the + \l {Animated Images}{Imagine style}. + \section1 Versions Qt Quick Controls 2.0 was introduced in Qt 5.7. Subsequent minor Qt releases diff --git a/src/imports/controls/fusion/TextArea.qml b/src/imports/controls/fusion/TextArea.qml index 04b25cb3..d2469d28 100644 --- a/src/imports/controls/fusion/TextArea.qml +++ b/src/imports/controls/fusion/TextArea.qml @@ -72,5 +72,6 @@ T.TextArea { verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight + renderType: control.renderType } } diff --git a/src/imports/controls/fusion/TextField.qml b/src/imports/controls/fusion/TextField.qml index 12331dd6..6f5f49b3 100644 --- a/src/imports/controls/fusion/TextField.qml +++ b/src/imports/controls/fusion/TextField.qml @@ -71,6 +71,7 @@ T.TextField { verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight + renderType: control.renderType } background: Rectangle { diff --git a/src/imports/controls/imagine/TextArea.qml b/src/imports/controls/imagine/TextArea.qml index c50b2f18..94fe237c 100644 --- a/src/imports/controls/imagine/TextArea.qml +++ b/src/imports/controls/imagine/TextArea.qml @@ -80,6 +80,7 @@ T.TextArea { verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight + renderType: control.renderType } background: NinePatchImage { diff --git a/src/imports/controls/imagine/TextField.qml b/src/imports/controls/imagine/TextField.qml index 94298fbc..2943396e 100644 --- a/src/imports/controls/imagine/TextField.qml +++ b/src/imports/controls/imagine/TextField.qml @@ -79,6 +79,7 @@ T.TextField { verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight + renderType: control.renderType } background: NinePatchImage { diff --git a/src/imports/controls/material/TextArea.qml b/src/imports/controls/material/TextArea.qml index 7fbc5cbc..ce49af53 100644 --- a/src/imports/controls/material/TextArea.qml +++ b/src/imports/controls/material/TextArea.qml @@ -71,6 +71,7 @@ T.TextArea { color: control.placeholderTextColor verticalAlignment: control.verticalAlignment elide: Text.ElideRight + renderType: control.renderType visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) } diff --git a/src/imports/controls/material/TextField.qml b/src/imports/controls/material/TextField.qml index 40189d74..7aa612eb 100644 --- a/src/imports/controls/material/TextField.qml +++ b/src/imports/controls/material/TextField.qml @@ -72,8 +72,8 @@ T.TextField { color: control.placeholderTextColor verticalAlignment: control.verticalAlignment elide: Text.ElideRight + renderType: control.renderType visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) - } background: Rectangle { diff --git a/src/imports/controls/universal/TextArea.qml b/src/imports/controls/universal/TextArea.qml index 83602426..2d5934df 100644 --- a/src/imports/controls/universal/TextArea.qml +++ b/src/imports/controls/universal/TextArea.qml @@ -78,6 +78,7 @@ T.TextArea { visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) verticalAlignment: control.verticalAlignment elide: Text.ElideRight + renderType: control.renderType } background: Rectangle { diff --git a/src/imports/controls/universal/TextField.qml b/src/imports/controls/universal/TextField.qml index 1a181c00..04e40fa5 100644 --- a/src/imports/controls/universal/TextField.qml +++ b/src/imports/controls/universal/TextField.qml @@ -78,6 +78,7 @@ T.TextField { visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) verticalAlignment: control.verticalAlignment elide: Text.ElideRight + renderType: control.renderType } background: Rectangle { diff --git a/src/quickcontrols2/qquicktumblerview.cpp b/src/quickcontrols2/qquicktumblerview.cpp index 59d05211..a510a1fe 100644 --- a/src/quickcontrols2/qquicktumblerview.cpp +++ b/src/quickcontrols2/qquicktumblerview.cpp @@ -221,9 +221,9 @@ void QQuickTumblerView::updateModel() // 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(); + tumblerPrivate->beginSetModel(); m_pathView->setModel(m_model); - tumblerPrivate->unlockWrap(); + tumblerPrivate->endSetModel(); // 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. @@ -234,7 +234,7 @@ void QQuickTumblerView::updateModel() QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler); // setModel() causes QQuickTumblerPrivate::_q_onViewCountChanged() to - // be called called, which calls QQuickTumbler::setCurrentIndex(), + // be called, which calls QQuickTumbler::setCurrentIndex(), // which results in QQuickItemViewPrivate::createHighlightItem() being // called. When the highlight item is created, // QQuickTumblerPrivate::itemChildAdded() is notified and diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 3ce776eb..7f4f59fa 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -647,7 +647,7 @@ QJSValue QQuickSpinBox::textFromValue() const if (!d->textFromValue.isCallable()) { QQmlEngine *engine = qmlEngine(this); if (engine) - d->textFromValue = engine->evaluate(QStringLiteral("function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }")); + d->textFromValue = engine->evaluate(QStringLiteral("(function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); })")); } return d->textFromValue; } diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp index 941cb14d..797f2455 100644 --- a/src/quicktemplates2/qquicktumbler.cpp +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -186,12 +186,17 @@ void QQuickTumblerPrivate::_q_updateItemWidths() void QQuickTumblerPrivate::_q_onViewCurrentIndexChanged() { Q_Q(QQuickTumbler); - if (view && !ignoreCurrentIndexChanges) { - const int oldCurrentIndex = currentIndex; - currentIndex = view->property("currentIndex").toInt(); - if (oldCurrentIndex != currentIndex) - emit q->currentIndexChanged(); + if (!view || ignoreCurrentIndexChanges || currentIndexSetDuringModelChange) { + // If the user set currentIndex in the onModelChanged handler, + // we have to respect that currentIndex by ignoring changes in the view + // until the model has finished being set. + return; } + + const int oldCurrentIndex = currentIndex; + currentIndex = view->property("currentIndex").toInt(); + if (oldCurrentIndex != currentIndex) + emit q->currentIndexChanged(); } void QQuickTumblerPrivate::_q_onViewCountChanged() @@ -206,7 +211,7 @@ void QQuickTumblerPrivate::_q_onViewCountChanged() if (pendingCurrentIndex != -1) { // If there was an attempt to set currentIndex at creation, try to finish that attempt now. // componentComplete() is too early, because the count might only be known sometime after completion. - q->setCurrentIndex(pendingCurrentIndex); + setCurrentIndex(pendingCurrentIndex); // If we could successfully set the currentIndex, consider it done. // Otherwise, we'll try again later in updatePolish(). if (currentIndex == pendingCurrentIndex) @@ -216,10 +221,10 @@ void QQuickTumblerPrivate::_q_onViewCountChanged() } else if (currentIndex == -1) { // If new items were added and our currentIndex was -1, we must // enforce our rule of a non-negative currentIndex when count > 0. - q->setCurrentIndex(0); + setCurrentIndex(0); } } else { - q->setCurrentIndex(-1); + setCurrentIndex(-1); } } @@ -299,17 +304,19 @@ void QQuickTumbler::setModel(const QVariant &model) if (model == d->model) return; - d->lockWrap(); + d->beginSetModel(); d->model = model; emit modelChanged(); - d->unlockWrap(); + d->endSetModel(); + + d->currentIndexSetDuringModelChange = false; // Don't try to correct the currentIndex if count() isn't known yet. // We can check in setupViewData() instead. if (isComponentComplete() && d->view && count() == 0) - setCurrentIndex(-1); + d->setCurrentIndex(-1); } /*! @@ -343,49 +350,9 @@ int QQuickTumbler::currentIndex() const void QQuickTumbler::setCurrentIndex(int currentIndex) { Q_D(QQuickTumbler); - if (currentIndex == d->currentIndex || currentIndex < -1) - return; - - if (!isComponentComplete()) { - // Views can't set currentIndex until they're ready. - d->pendingCurrentIndex = currentIndex; - return; - } - - // -1 doesn't make sense for a non-empty Tumbler, because unlike - // e.g. ListView, there's always one item selected. - // Wait until the component has finished before enforcing this rule, though, - // because the count might not be known yet. - if ((d->count > 0 && currentIndex == -1) || (currentIndex >= d->count)) { - return; - } - - // The view might not have been created yet, as is the case - // if you create a Tumbler component and pass e.g. { currentIndex: 2 } - // to createObject(). - if (d->view) { - // Only actually set our currentIndex if the view was able to set theirs. - bool couldSet = false; - if (d->count == 0 && currentIndex == -1) { - // PathView insists on using 0 as the currentIndex when there are no items. - 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; - } - - if (couldSet) { - // The view's currentIndex might not have actually changed, but ours has, - // and that's what user code sees. - d->currentIndex = currentIndex; - emit currentIndexChanged(); - } - } + if (d->modelBeingSet) + d->currentIndexSetDuringModelChange = true; + d->setCurrentIndex(currentIndex, QQuickTumblerPrivate::UserChange); } /*! @@ -690,6 +657,64 @@ void QQuickTumblerPrivate::syncCurrentIndex() q->polish(); } +void QQuickTumblerPrivate::setCurrentIndex(int newCurrentIndex, + QQuickTumblerPrivate::PropertyChangeReason changeReason) +{ + Q_Q(QQuickTumbler); + if (newCurrentIndex == currentIndex || newCurrentIndex < -1) + return; + + if (!q->isComponentComplete()) { + // Views can't set currentIndex until they're ready. + pendingCurrentIndex = newCurrentIndex; + return; + } + + if (modelBeingSet && changeReason == UserChange) { + // If modelBeingSet is true and the user set the currentIndex, + // the model is in the process of being set and the user has set + // the currentIndex in onModelChanged. We have to queue the currentIndex + // change until we're ready. + pendingCurrentIndex = newCurrentIndex; + return; + } + + // -1 doesn't make sense for a non-empty Tumbler, because unlike + // e.g. ListView, there's always one item selected. + // Wait until the component has finished before enforcing this rule, though, + // because the count might not be known yet. + if ((count > 0 && newCurrentIndex == -1) || (newCurrentIndex >= count)) { + return; + } + + // The view might not have been created yet, as is the case + // if you create a Tumbler component and pass e.g. { currentIndex: 2 } + // to createObject(). + if (view) { + // Only actually set our currentIndex if the view was able to set theirs. + bool couldSet = false; + if (count == 0 && newCurrentIndex == -1) { + // PathView insists on using 0 as the currentIndex when there are no items. + couldSet = true; + } else { + ignoreCurrentIndexChanges = true; + ignoreSignals = true; + view->setProperty("currentIndex", newCurrentIndex); + ignoreSignals = false; + ignoreCurrentIndexChanges = false; + + couldSet = view->property("currentIndex").toInt() == newCurrentIndex; + } + + if (couldSet) { + // The view's currentIndex might not have actually changed, but ours has, + // and that's what user code sees. + currentIndex = newCurrentIndex; + emit q->currentIndexChanged(); + } + } +} + void QQuickTumblerPrivate::setCount(int newCount) { if (newCount == count) @@ -705,7 +730,7 @@ void QQuickTumblerPrivate::setCount(int newCount) void QQuickTumblerPrivate::setWrapBasedOnCount() { - if (count == 0 || explicitWrap || ignoreWrapChanges) + if (count == 0 || explicitWrap || modelBeingSet) return; setWrap(count >= visibleItemCount, false); @@ -750,17 +775,17 @@ void QQuickTumblerPrivate::setWrap(bool shouldWrap, bool isExplicit) if (q->isComponentComplete() || contentItem) setupViewData(contentItem); - q->setCurrentIndex(oldCurrentIndex); + setCurrentIndex(oldCurrentIndex); } -void QQuickTumblerPrivate::lockWrap() +void QQuickTumblerPrivate::beginSetModel() { - ignoreWrapChanges = true; + modelBeingSet = true; } -void QQuickTumblerPrivate::unlockWrap() +void QQuickTumblerPrivate::endSetModel() { - ignoreWrapChanges = false; + modelBeingSet = false; setWrapBasedOnCount(); } @@ -796,12 +821,12 @@ void QQuickTumbler::updatePolish() // If there is a pending currentIndex at this stage, it means that // the view wouldn't set our currentIndex in _q_onViewCountChanged // because it wasn't ready. Try one last time here. - setCurrentIndex(d->pendingCurrentIndex); + d->setCurrentIndex(d->pendingCurrentIndex); if (d->currentIndex != d->pendingCurrentIndex && d->currentIndex == -1) { // If we *still* couldn't set it, it's probably invalid. // See if we can at least enforce our rule of "non-negative currentIndex when count > 0" instead. - setCurrentIndex(0); + d->setCurrentIndex(0); } d->pendingCurrentIndex = -1; diff --git a/src/quicktemplates2/qquicktumbler_p_p.h b/src/quicktemplates2/qquicktumbler_p_p.h index 4d4c3bcf..2f8b1207 100644 --- a/src/quicktemplates2/qquicktumbler_p_p.h +++ b/src/quicktemplates2/qquicktumbler_p_p.h @@ -76,7 +76,8 @@ public: int visibleItemCount = 5; bool wrap = true; bool explicitWrap = false; - bool ignoreWrapChanges = false; + bool modelBeingSet = false; + bool currentIndexSetDuringModelChange = false; QQuickItem *view = nullptr; QQuickItem *viewContentItem = nullptr; ContentItemType viewContentItemType = UnsupportedContentItemType; @@ -104,11 +105,17 @@ public: void warnAboutIncorrectContentItem(); void syncCurrentIndex(); + enum PropertyChangeReason { + UserChange, + InternalChange + }; + + void setCurrentIndex(int newCurrentIndex, PropertyChangeReason changeReason = InternalChange); void setCount(int newCount); void setWrapBasedOnCount(); void setWrap(bool shouldWrap, bool isExplicit); - void lockWrap(); - void unlockWrap(); + void beginSetModel(); + void endSetModel(); void itemChildAdded(QQuickItem *, QQuickItem *) override; void itemChildRemoved(QQuickItem *, QQuickItem *) override; diff --git a/tests/auto/controls/data/tst_tumbler.qml b/tests/auto/controls/data/tst_tumbler.qml index 46c73cfc..f62c62c2 100644 --- a/tests/auto/controls/data/tst_tumbler.qml +++ b/tests/auto/controls/data/tst_tumbler.qml @@ -1176,4 +1176,70 @@ TestCase { + " to have an y pos of " + expectedPos.y + " but it was " + actualPos.y) } } + + Component { + id: setCurrentIndexOnImperativeModelChangeComponent + + Tumbler { + onModelChanged: currentIndex = model - 2 + } + } + + function test_setCurrentIndexOnImperativeModelChange() { + var tumbler = createTemporaryObject(setCurrentIndexOnImperativeModelChangeComponent, testCase); + verify(tumbler); + + tumbler.model = 4 + compare(tumbler.count, 4); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 4); + + // 4 - 2 = 2 + compare(tumbler.currentIndex, 2); + + ++tumbler.model; + compare(tumbler.count, 5); + compare(tumbler.wrap, true); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 5); + // 5 - 2 = 3 + compare(tumbler.currentIndex, 3); + } + + Component { + id: setCurrentIndexOnDeclarativeModelChangeComponent + + Item { + property alias tumbler: tumbler + + property int setting: 4 + + Tumbler { + id: tumbler + model: setting + onModelChanged: currentIndex = model - 2 + } + } + } + + function test_setCurrentIndexOnDeclarativeModelChange() { + var root = createTemporaryObject(setCurrentIndexOnDeclarativeModelChangeComponent, testCase); + verify(root); + + var tumbler = root.tumbler; + compare(tumbler.count, 4); + compare(tumbler.wrap, false); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 4); + // 4 - 2 = 2 + compare(tumbler.currentIndex, 2); + + ++root.setting; + compare(tumbler.count, 5); + compare(tumbler.wrap, true); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 5); + // 5 - 2 = 3 + compare(tumbler.currentIndex, 3); + } } |