source: trunk/src/gui/widgets/qwidgetanimator.cpp@ 331

Last change on this file since 331 was 2, checked in by Dmitry A. Kuminov, 17 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 6.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtCore/qtimer.h>
43#include <QtCore/qdatetime.h>
44#include <QtGui/qwidget.h>
45#include <QtGui/qtextedit.h>
46#include <QtGui/private/qwidget_p.h>
47#include <qdebug.h>
48
49#include "qwidgetanimator_p.h"
50
51QT_BEGIN_NAMESPACE
52
53static const int g_animation_steps = 12;
54static const int g_animation_interval = 16;
55
56// 1000 * (x/(1 + x*x) + 0.5) on interval [-1, 1]
57static const int g_animate_function[] =
58{
59 0, 1, 5, 12, 23, 38, 58, 84, 116, 155, 199, 251, 307, 368,
60 433, 500, 566, 631, 692, 748, 799, 844, 883, 915, 941, 961,
61 976, 987, 994, 998, 1000
62};
63static const int g_animate_function_points = sizeof(g_animate_function)/sizeof(int);
64
65static inline int animateHelper(int start, int stop, int step, int steps)
66{
67 if (start == stop)
68 return start;
69 if (step == 0)
70 return start;
71 if (step == steps)
72 return stop;
73
74 int x = g_animate_function_points*step/(steps + 1);
75 return start + g_animate_function[x]*(stop - start)/1000;
76}
77
78QWidgetAnimator::QWidgetAnimator(QObject *parent)
79 : QObject(parent)
80{
81 m_time = new QTime();
82 m_timer = new QTimer(this);
83 m_timer->setInterval(g_animation_interval);
84 connect(m_timer, SIGNAL(timeout()), this, SLOT(animationStep()));
85}
86
87QWidgetAnimator::~QWidgetAnimator()
88{
89 delete m_time;
90}
91
92void QWidgetAnimator::abort(QWidget *w)
93{
94 if (m_animation_map.remove(w) == 0)
95 return;
96 if (m_animation_map.isEmpty()) {
97 m_timer->stop();
98 emit finishedAll();
99 }
100}
101
102void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate)
103{
104 QRect final_geometry = _final_geometry;
105
106 QRect r = widget->geometry();
107 if (r.right() < 0 || r.bottom() < 0)
108 r = QRect();
109
110 if (r.isNull() || final_geometry.isNull())
111 animate = false;
112
113 AnimationMap::const_iterator it = m_animation_map.constFind(widget);
114 if (it == m_animation_map.constEnd()) {
115 if (r == final_geometry) {
116 emit finished(widget);
117 return;
118 }
119 } else {
120 if ((*it).r2 == final_geometry)
121 return;
122 }
123
124 if (animate) {
125 AnimationItem item(widget, r, final_geometry);
126 m_animation_map[widget] = item;
127 if (!m_timer->isActive()) {
128 m_timer->start();
129 m_time->start();
130 }
131 } else {
132 m_animation_map.remove(widget);
133 if (m_animation_map.isEmpty())
134 m_timer->stop();
135
136 if (!final_geometry.isValid() && !widget->isWindow()) {
137 // Make the wigdet go away by sending it to negative space
138 QSize s = widget->size();
139 final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height());
140 }
141 widget->setGeometry(final_geometry);
142
143 emit finished(widget);
144
145 if (m_animation_map.isEmpty())
146 emit finishedAll();
147
148 return;
149 }
150}
151
152void QWidgetAnimator::animationStep()
153{
154 int steps = (1 + m_time->restart())/g_animation_interval;
155 AnimationMap::iterator it = m_animation_map.begin();
156 while (it != m_animation_map.end()) {
157 AnimationItem &item = *it;
158
159 item.step = qMin(item.step + steps, g_animation_steps);
160
161 int x = animateHelper(item.r1.left(), item.r2.left(),
162 item.step, g_animation_steps);
163 int y = animateHelper(item.r1.top(), item.r2.top(),
164 item.step, g_animation_steps);
165 int w = animateHelper(item.r1.width(), item.r2.width(),
166 item.step, g_animation_steps);
167 int h = animateHelper(item.r1.height(), item.r2.height(),
168 item.step, g_animation_steps);
169
170 item.widget->setGeometry(x, y, w, h);
171
172 if (item.step == g_animation_steps) {
173 emit finished(item.widget);
174 AnimationMap::iterator tmp = it;
175 ++it;
176 m_animation_map.erase(tmp);
177 } else {
178 ++it;
179 }
180 }
181
182 if (m_animation_map.isEmpty()) {
183 m_timer->stop();
184 emit finishedAll();
185 }
186}
187
188bool QWidgetAnimator::animating() const
189{
190 return m_timer->isActive();
191}
192
193bool QWidgetAnimator::animating(QWidget *widget)
194{
195 return m_animation_map.contains(widget);
196}
197
198QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.