1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qwidgetanimator_p.h"
5
6#if QT_CONFIG(animation)
7#include <QtCore/qpropertyanimation.h>
8#endif
9#include <QtWidgets/qwidget.h>
10#include <QtWidgets/qstyle.h>
11#if QT_CONFIG(mainwindow)
12#include <private/qmainwindowlayout_p.h>
13#endif
14
15QT_BEGIN_NAMESPACE
16
17QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout)
18#if QT_CONFIG(mainwindow)
19: m_mainWindowLayout(layout)
20#endif
21{
22 Q_UNUSED(layout);
23}
24
25void QWidgetAnimator::abort(QWidget *w)
26{
27#if QT_CONFIG(animation)
28 const auto it = m_animation_map.constFind(key: w);
29 if (it == m_animation_map.cend())
30 return;
31 QPropertyAnimation *anim = *it;
32 m_animation_map.erase(it);
33 if (anim) {
34 anim->stop();
35 }
36#if QT_CONFIG(mainwindow)
37 m_mainWindowLayout->animationFinished(widget: w);
38#endif
39#else
40 Q_UNUSED(w); //there is no animation to abort
41#endif // animation
42}
43
44#if QT_CONFIG(animation)
45void QWidgetAnimator::animationFinished()
46{
47 QPropertyAnimation *anim = qobject_cast<QPropertyAnimation*>(object: sender());
48 abort(w: static_cast<QWidget*>(anim->targetObject()));
49}
50#endif // animation
51
52void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate)
53{
54 QRect r = widget->geometry();
55 if (r.right() < 0 || r.bottom() < 0)
56 r = QRect();
57
58 animate = animate && !r.isNull() && !_final_geometry.isNull();
59
60 // might make the widget go away by sending it to negative space
61 const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
62 QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
63
64#if QT_CONFIG(animation)
65 //If the QStyle has animations, animate
66 if (const int animationDuration = widget->style()->styleHint(stylehint: QStyle::SH_Widget_Animation_Duration, opt: nullptr, widget)) {
67 AnimationMap::const_iterator it = m_animation_map.constFind(key: widget);
68 if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
69 return;
70
71 QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
72 anim->setDuration(animate ? animationDuration : 0);
73 anim->setEasingCurve(QEasingCurve::InOutQuad);
74 anim->setEndValue(final_geometry);
75 m_animation_map[widget] = anim;
76 connect(asender: anim, SIGNAL(finished()), SLOT(animationFinished()));
77 anim->start(policy: QPropertyAnimation::DeleteWhenStopped);
78 } else
79#endif // animation
80 {
81 //we do it in one shot
82 widget->setGeometry(final_geometry);
83#if QT_CONFIG(mainwindow)
84 m_mainWindowLayout->animationFinished(widget);
85#endif // QT_CONFIG(mainwindow)
86 }
87}
88
89bool QWidgetAnimator::animating() const
90{
91 return !m_animation_map.isEmpty();
92}
93
94QT_END_NAMESPACE
95
96#include "moc_qwidgetanimator_p.cpp"
97

source code of qtbase/src/widgets/widgets/qwidgetanimator.cpp