diff options
| author | Morteza Jamshidi <morteza.jamshidi@qt.io> | 2025-08-01 11:48:56 +0200 |
|---|---|---|
| committer | Morteza Jamshidi <morteza.jamshidi@qt.io> | 2025-08-14 11:06:22 +0200 |
| commit | 21ff1d42c0563b5369f5dca78417adb3d9008787 (patch) | |
| tree | aa8c1cf72824694130666dcef030e5781f47b6a0 /src/quickcontrols/material/impl/qquickmaterialtextcontainer.cpp | |
| parent | 3bfc8ef2e9c736ea60674a089c610095e4fc15b3 (diff) | |
Material Style: fix focusIn and focusOut animation issues
When a property potentially used in focusIn or focusOut animation is
changed, we need to reschedule the animation with the correct parameters.
properties like verticalPadding, leftPadding, controlHasText, ...
To fix the issue I simplified focus animation logic.
Fixes: QTBUG-138028
Change-Id: I115fb6fdd5676ae0282b5b4b5bd460ea3b28392a
Pick-to: 6.10 6.9 6.8
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quickcontrols/material/impl/qquickmaterialtextcontainer.cpp')
| -rw-r--r-- | src/quickcontrols/material/impl/qquickmaterialtextcontainer.cpp | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/src/quickcontrols/material/impl/qquickmaterialtextcontainer.cpp b/src/quickcontrols/material/impl/qquickmaterialtextcontainer.cpp index a0ad0967fb..20c4609cb5 100644 --- a/src/quickcontrols/material/impl/qquickmaterialtextcontainer.cpp +++ b/src/quickcontrols/material/impl/qquickmaterialtextcontainer.cpp @@ -163,7 +163,7 @@ void QQuickMaterialTextContainer::setControlHasText(bool controlHasText) m_controlHasText = controlHasText; // TextArea's text length is updated after component completion, // so account for that here and in setPlaceholderHasText(). - maybeSetFocusAnimationProgress(); + updateFocusAnimation(); update(); emit controlHasTextChanged(); } @@ -179,7 +179,7 @@ void QQuickMaterialTextContainer::setPlaceholderHasText(bool placeholderHasText) return; m_placeholderHasText = placeholderHasText; - maybeSetFocusAnimationProgress(); + updateFocusAnimation(); update(); emit placeholderHasTextChanged(); } @@ -349,6 +349,10 @@ QQuickItem *QQuickMaterialTextContainer::textControl() const void QQuickMaterialTextContainer::controlGotActiveFocus() { + if (m_focusAnimation) { + m_focusAnimation->stop(); + m_focusAnimation.clear(); + } const bool shouldAnimate = m_filled ? !m_controlHasText : shouldAnimateOutline(); if (!shouldAnimate) { // It does have focus, but sometimes we don't need to animate anything, just change colors. @@ -361,11 +365,15 @@ void QQuickMaterialTextContainer::controlGotActiveFocus() return; } - startFocusAnimation(); + updateFocusAnimation(true); } void QQuickMaterialTextContainer::controlLostActiveFocus() { + if (m_focusAnimation) { + m_focusAnimation->stop(); + m_focusAnimation.clear(); + } // We don't want to animate the active indicator line (at the bottom) of filled containers // when the control loses focus, only when it gets it. if (m_filled || !shouldAnimateOutline()) { @@ -377,35 +385,43 @@ void QQuickMaterialTextContainer::controlLostActiveFocus() return; } - QPropertyAnimation *animation = new QPropertyAnimation(this, "focusAnimationProgress", this); - animation->setDuration(300); - animation->setStartValue(1); - animation->setEndValue(0); - animation->start(QAbstractAnimation::DeleteWhenStopped); + updateFocusAnimation(true); } -void QQuickMaterialTextContainer::startFocusAnimation() +void QQuickMaterialTextContainer::updateFocusAnimation(bool createIfNeeded) { - // Each time setFocusAnimationProgress is called by the animation, it'll call update(), - // which will cause us to be re-rendered. - QPropertyAnimation *animation = new QPropertyAnimation(this, "focusAnimationProgress", this); - animation->setDuration(300); - animation->setStartValue(0); - animation->setEndValue(1); - animation->start(QAbstractAnimation::DeleteWhenStopped); -} - -void QQuickMaterialTextContainer::maybeSetFocusAnimationProgress() -{ - if (m_filled) + if (m_filled) { + if (m_focusAnimation) { + m_focusAnimation->stop(); + m_focusAnimation.clear(); + } return; + } + int focusAnimationProgressValue = 0; if (m_controlHasText && m_placeholderHasText) { // Show the interrupted outline when there is text. - setFocusAnimationProgress(1); - } else if (!m_controlHasText && !m_controlHasActiveFocus) { - // If the text was cleared while it didn't have focus, don't animate, just close the gap. - setFocusAnimationProgress(0); + focusAnimationProgressValue = 1; + } else if (!m_controlHasText) { + if (m_controlHasActiveFocus && m_placeholderHasText) + focusAnimationProgressValue = 1; + else + focusAnimationProgressValue = 0; + } + + if (m_focusAnimation || createIfNeeded) { + int duration = 300; + if (m_focusAnimation) { + duration = m_focusAnimation->totalDuration() - m_focusAnimation->currentTime(); + m_focusAnimation->stop(); + } + m_focusAnimation = new QPropertyAnimation(this, "focusAnimationProgress", this); + m_focusAnimation->setDuration(duration); + m_focusAnimation->setStartValue(focusAnimationProgress()); + m_focusAnimation->setEndValue(focusAnimationProgressValue); + m_focusAnimation->start(QAbstractAnimation::DeleteWhenStopped); + } else { + setFocusAnimationProgress(focusAnimationProgressValue); } } @@ -416,7 +432,7 @@ void QQuickMaterialTextContainer::componentComplete() if (!parentItem()) qmlWarning(this) << "Expected parent item by component completion!"; - maybeSetFocusAnimationProgress(); + updateFocusAnimation(); } QT_END_NAMESPACE |
