aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2020-10-19 11:52:42 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-01-06 16:14:11 +0000
commit5f6133aac0f11feefabc9006c9633b7f6d61f2c0 (patch)
tree00a0d580c0531bd2e451a5a92b66a10148e56382
parenta2593ff9cf5d0af885c20c2e9f9faa6ca4f1c1a3 (diff)
Reset the opacity and scale properties after the exit transition
By resetting the opacity and scale properties after an exit transition we are ensuring that it does not lose the original values that the user may have set. [ChangeLog][Important Behavior Changes][Popup] After the exit transition is finished, then the opacity and scale properties will be reset to their values before the enter transition is started. Fixes: QTBUG-87283 Change-Id: I2b192c96eaea2906d968341255e80cd19be177e6 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> (cherry picked from commit df33c79fb6579f94498164531777320e79c36fd5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/imports/controls/material/ComboBox.qml8
-rw-r--r--src/quicktemplates2/qquickpopup.cpp20
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h2
-rw-r--r--tests/auto/controls/data/tst_combobox.qml50
4 files changed, 76 insertions, 4 deletions
diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml
index a9bdd934..6aada8c5 100644
--- a/src/imports/controls/material/ComboBox.qml
+++ b/src/imports/controls/material/ComboBox.qml
@@ -147,14 +147,14 @@ T.ComboBox {
enter: Transition {
// grow_fade_in
- NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 }
- NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 }
+ NumberAnimation { property: "scale"; from: 0.9; easing.type: Easing.OutQuint; duration: 220 }
+ NumberAnimation { property: "opacity"; from: 0.0; easing.type: Easing.OutCubic; duration: 150 }
}
exit: Transition {
// shrink_fade_out
- NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 }
- NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 }
+ NumberAnimation { property: "scale"; to: 0.9; easing.type: Easing.OutQuint; duration: 220 }
+ NumberAnimation { property: "opacity"; to: 0.0; easing.type: Easing.OutCubic; duration: 150 }
}
contentItem: ListView {
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 7130d2ea..312fb119 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -215,6 +215,19 @@ QT_BEGIN_NAMESPACE
To ensure that the popup is positioned within the bounds of the enclosing
window, the \l margins property can be set to a non-negative value.
+ \section1 Popup Transitions
+
+ Since Qt 5.15.3 the following properties are restored to their original values from before
+ the enter transition after the exit transition is completed.
+
+ \list
+ \li \l opacity
+ \li \l scale
+ \endlist
+
+ This allows the built-in styles to animate on these properties without losing any explicitly
+ defined value.
+
\sa {Popup Controls}, {Customizing Popup}, ApplicationWindow
*/
@@ -451,6 +464,11 @@ bool QQuickPopupPrivate::prepareExitTransition()
if (transitionState == ExitTransition && transitionManager.isRunning())
return false;
+ // We need to cache the original scale and opacity values so we can reset it after
+ // the exit transition is done so they have the original values again
+ prevScale = popupItem->scale();
+ prevOpacity = popupItem->opacity();
+
if (transitionState != ExitTransition) {
// The setFocus(false) call below removes any active focus before we're
// able to check it in finalizeExitTransition.
@@ -513,6 +531,8 @@ void QQuickPopupPrivate::finalizeExitTransition()
hadActiveFocusBeforeExitTransition = false;
emit q->visibleChanged();
emit q->closed();
+ popupItem->setScale(prevScale);
+ popupItem->setOpacity(prevOpacity);
}
QMarginsF QQuickPopupPrivate::getMargins() const
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index 8a85f914..ef4b112e 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -196,6 +196,8 @@ public:
QList<QQuickStateAction> exitActions;
QQuickPopupTransitionManager transitionManager;
QQuickPopupAnchors *anchors = nullptr;
+ qreal prevOpacity = 0;
+ qreal prevScale = 0;
friend class QQuickPopupTransitionManager;
};
diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml
index 1c58372f..4907b87f 100644
--- a/tests/auto/controls/data/tst_combobox.qml
+++ b/tests/auto/controls/data/tst_combobox.qml
@@ -948,6 +948,56 @@ TestCase {
tryCompare(control.popup, "visible", false)
}
+ Component {
+ id: reopenCombo
+ Window {
+ property alias innerCombo: innerCombo
+ visible: true
+ width: 300
+ height: 300
+ ComboBox {
+ id: innerCombo
+ model: 10
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ }
+
+ // This test checks that when reopening the combobox that it is still appears at the same y position as
+ // previously
+ function test_reopen_popup() {
+ var control = createTemporaryObject(reopenCombo, testCase)
+ verify(control)
+ var y = 0;
+ for (var i = 0; i < 2; ++i) {
+ tryCompare(control.innerCombo.popup, "visible", false)
+ control.innerCombo.y = control.height - (control.innerCombo.popup.contentItem.height * 0.99)
+ var popupYSpy = createTemporaryObject(signalSpy, testCase, {target: control.innerCombo.popup, signalName: "yChanged"})
+ verify(popupYSpy.valid)
+ mousePress(control.innerCombo)
+ compare(control.innerCombo.pressed, true)
+ compare(control.innerCombo.popup.visible, false)
+ mouseRelease(control.innerCombo)
+ compare(control.innerCombo.pressed, false)
+ compare(control.innerCombo.popup.visible, true)
+ if (control.innerCombo.popup.enter)
+ tryCompare(control.innerCombo.popup.enter, "running", false)
+ // Check on the second opening that it has the same y position as before
+ if (i !== 0) {
+ // y should not have changed again
+ verify(popupYSpy.count === 0)
+ verify(y === control.innerCombo.popup.y)
+ } else {
+ // In some cases on the initial show, y changes more than once
+ verify(popupYSpy.count >= 1)
+ y = control.innerCombo.popup.y
+ mouseClick(control.innerCombo)
+ compare(control.innerCombo.pressed, false)
+ tryCompare(control.innerCombo.popup, "visible", false)
+ }
+ }
+ }
+
function test_mouse() {
var control = createTemporaryObject(comboBox, testCase, {model: 3, hoverEnabled: false})
verify(control)