source: trunk/demos/embedded/digiflip/digiflip.cpp@ 769

Last change on this file since 769 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 12.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the demonstration applications of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtCore>
43#include <QtGui>
44
45class Digits: public QWidget
46{
47 Q_OBJECT
48
49public:
50
51 enum {
52 Slide,
53 Flip,
54 Rotate
55 };
56
57 Digits(QWidget *parent)
58 : QWidget(parent)
59 , m_number(0)
60 , m_transition(Slide)
61 {
62 setAttribute(Qt::WA_OpaquePaintEvent, true);
63 setAttribute(Qt::WA_NoSystemBackground, true);
64 connect(&m_animator, SIGNAL(frameChanged(int)), SLOT(update()));
65 m_animator.setFrameRange(0, 100);
66 m_animator.setDuration(600);
67 m_animator.setCurveShape(QTimeLine::EaseInOutCurve);
68 }
69
70 void setTransition(int tr) {
71 m_transition = tr;
72 }
73
74 int transition() const {
75 return m_transition;
76 }
77
78 void setNumber(int n) {
79 if (m_number != n) {
80 m_number = qBound(0, n, 99);
81 preparePixmap();
82 update();
83 }
84 }
85
86 void flipTo(int n) {
87 if (m_number != n) {
88 m_number = qBound(0, n, 99);
89 m_lastPixmap = m_pixmap;
90 preparePixmap();
91 m_animator.stop();
92 m_animator.start();
93 }
94 }
95
96protected:
97
98 void drawFrame(QPainter *p, const QRect &rect) {
99 p->setPen(Qt::NoPen);
100 QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
101 gradient.setColorAt(0.00, QColor(245, 245, 245));
102 gradient.setColorAt(0.49, QColor(192, 192, 192));
103 gradient.setColorAt(0.51, QColor(245, 245, 245));
104 gradient.setColorAt(1.00, QColor(192, 192, 192));
105 p->setBrush(gradient);
106 QRect r = rect;
107 p->drawRoundedRect(r, 15, 15, Qt::RelativeSize);
108 r.adjust(1, 4, -1, -4);
109 p->setPen(QColor(181, 181, 181));
110 p->setBrush(Qt::NoBrush);
111 p->drawRoundedRect(r, 15, 15, Qt::RelativeSize);
112 p->setPen(QColor(159, 159, 159));
113 int y = rect.top() + rect.height() / 2 - 1;
114 p->drawLine(rect.left(), y, rect.right(), y);
115 }
116
117 QPixmap drawDigits(int n, const QRect &rect) {
118
119 int scaleFactor = 2;
120#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
121 if (rect.height() > 240)
122 scaleFactor = 1;
123#endif
124
125 QString str = QString::number(n);
126 if (str.length() == 1)
127 str.prepend("0");
128
129 QFont font;
130 font.setFamily("Helvetica");
131 int fontHeight = scaleFactor * 0.55 * rect.height();
132 font.setPixelSize(fontHeight);
133 font.setBold(true);
134
135 QPixmap pixmap(rect.size() * scaleFactor);
136 pixmap.fill(Qt::transparent);
137
138 QLinearGradient gradient(QPoint(0, 0), QPoint(0, pixmap.height()));
139 gradient.setColorAt(0.00, QColor(128, 128, 128));
140 gradient.setColorAt(0.49, QColor(64, 64, 64));
141 gradient.setColorAt(0.51, QColor(128, 128, 128));
142 gradient.setColorAt(1.00, QColor(16, 16, 16));
143
144 QPainter p;
145 p.begin(&pixmap);
146 p.setFont(font);
147 QPen pen;
148 pen.setBrush(QBrush(gradient));
149 p.setPen(pen);
150 p.drawText(pixmap.rect(), Qt::AlignCenter, str);
151 p.end();
152
153 return pixmap.scaledToWidth(width(), Qt::SmoothTransformation);
154 }
155
156 void preparePixmap() {
157 m_pixmap = QPixmap(size());
158 m_pixmap.fill(Qt::transparent);
159 QPainter p;
160 p.begin(&m_pixmap);
161 p.drawPixmap(0, 0, drawDigits(m_number, rect()));
162 p.end();
163 }
164
165 void resizeEvent(QResizeEvent*) {
166 preparePixmap();
167 update();
168 }
169
170 void paintStatic() {
171 QPainter p(this);
172 p.fillRect(rect(), Qt::black);
173
174 int pad = width() / 10;
175 drawFrame(&p, rect().adjusted(pad, pad, -pad, -pad));
176 p.drawPixmap(0, 0, m_pixmap);
177 }
178
179 void paintSlide() {
180 QPainter p(this);
181 p.fillRect(rect(), Qt::black);
182
183 int pad = width() / 10;
184 QRect fr = rect().adjusted(pad, pad, -pad, -pad);
185 drawFrame(&p, fr);
186 p.setClipRect(fr);
187
188 int y = height() * m_animator.currentFrame() / 100;
189 p.drawPixmap(0, y, m_lastPixmap);
190 p.drawPixmap(0, y - height(), m_pixmap);
191 }
192
193 void paintFlip() {
194 QPainter p(this);
195#if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_WINCE_WM)
196 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
197 p.setRenderHint(QPainter::Antialiasing, true);
198#endif
199 p.fillRect(rect(), Qt::black);
200
201 int hw = width() / 2;
202 int hh = height() / 2;
203
204 // behind is the new pixmap
205 int pad = width() / 10;
206 QRect fr = rect().adjusted(pad, pad, -pad, -pad);
207 drawFrame(&p, fr);
208 p.drawPixmap(0, 0, m_pixmap);
209
210 int index = m_animator.currentFrame();
211
212 if (index <= 50) {
213
214 // the top part of the old pixmap is flipping
215 int angle = -180 * index / 100;
216 QTransform transform;
217 transform.translate(hw, hh);
218 transform.rotate(angle, Qt::XAxis);
219 p.setTransform(transform);
220 drawFrame(&p, fr.adjusted(-hw, -hh, -hw, -hh));
221 p.drawPixmap(-hw, -hh, m_lastPixmap);
222
223 // the bottom part is still the old pixmap
224 p.resetTransform();
225 p.setClipRect(0, hh, width(), hh);
226 drawFrame(&p, fr);
227 p.drawPixmap(0, 0, m_lastPixmap);
228 } else {
229
230 p.setClipRect(0, hh, width(), hh);
231
232 // the bottom part is still the old pixmap
233 drawFrame(&p, fr);
234 p.drawPixmap(0, 0, m_lastPixmap);
235
236 // the bottom part of the new pixmap is flipping
237 int angle = 180 - 180 * m_animator.currentFrame() / 100;
238 QTransform transform;
239 transform.translate(hw, hh);
240 transform.rotate(angle, Qt::XAxis);
241 p.setTransform(transform);
242 drawFrame(&p, fr.adjusted(-hw, -hh, -hw, -hh));
243 p.drawPixmap(-hw, -hh, m_pixmap);
244
245 }
246
247 }
248
249 void paintRotate() {
250 QPainter p(this);
251
252 int pad = width() / 10;
253 QRect fr = rect().adjusted(pad, pad, -pad, -pad);
254 drawFrame(&p, fr);
255 p.setClipRect(fr);
256
257 int angle1 = -180 * m_animator.currentFrame() / 100;
258 int angle2 = 180 - 180 * m_animator.currentFrame() / 100;
259 int angle = (m_animator.currentFrame() <= 50) ? angle1 : angle2;
260 QPixmap pix = (m_animator.currentFrame() <= 50) ? m_lastPixmap : m_pixmap;
261
262 QTransform transform;
263 transform.translate(width() / 2, height() / 2);
264 transform.rotate(angle, Qt::XAxis);
265
266 p.setTransform(transform);
267 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
268 p.drawPixmap(-width() / 2, -height() / 2, pix);
269 }
270
271 void paintEvent(QPaintEvent *event) {
272 Q_UNUSED(event);
273 if (m_animator.state() == QTimeLine::Running) {
274 if (m_transition == Slide)
275 paintSlide();
276 if (m_transition == Flip)
277 paintFlip();
278 if (m_transition == Rotate)
279 paintRotate();
280 } else {
281 paintStatic();
282 }
283 }
284
285private:
286 int m_number;
287 int m_transition;
288 QPixmap m_pixmap;
289 QPixmap m_lastPixmap;
290 QTimeLine m_animator;
291};
292
293class DigiFlip : public QMainWindow
294{
295 Q_OBJECT
296
297public:
298 DigiFlip(QWidget *parent = 0)
299 : QMainWindow(parent)
300 {
301 m_hour = new Digits(this);
302 m_hour->show();
303 m_minute = new Digits(this);
304 m_minute->show();
305
306 QPalette pal = palette();
307 pal.setColor(QPalette::Window, Qt::black);
308 setPalette(pal);
309
310 m_ticker.start(1000, this);
311 QTime t = QTime::currentTime();
312 m_hour->setNumber(t.hour());
313 m_minute->setNumber(t.minute());
314 updateTime();
315
316 QAction *slideAction = new QAction("&Slide", this);
317 QAction *flipAction = new QAction("&Flip", this);
318 QAction *rotateAction = new QAction("&Rotate", this);
319 connect(slideAction, SIGNAL(triggered()), SLOT(chooseSlide()));
320 connect(flipAction, SIGNAL(triggered()), SLOT(chooseFlip()));
321 connect(rotateAction, SIGNAL(triggered()), SLOT(chooseRotate()));
322#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
323 menuBar()->addAction(slideAction);
324 menuBar()->addAction(flipAction);
325 menuBar()->addAction(rotateAction);
326#else
327 addAction(slideAction);
328 addAction(flipAction);
329 addAction(rotateAction);
330 setContextMenuPolicy(Qt::ActionsContextMenu);
331#endif
332 }
333
334 void updateTime() {
335 QTime t = QTime::currentTime();
336 m_hour->flipTo(t.hour());
337 m_minute->flipTo(t.minute());
338 QString str = t.toString("hh:mm:ss");
339 str.prepend(": ");
340 if (m_hour->transition() == Digits::Slide)
341 str.prepend("Slide");
342 if (m_hour->transition() == Digits::Flip)
343 str.prepend("Flip");
344 if (m_hour->transition() == Digits::Rotate)
345 str.prepend("Rotate");
346 setWindowTitle(str);
347 }
348
349 void switchTransition(int delta) {
350 int i = (m_hour->transition() + delta + 3) % 3;
351 m_hour->setTransition(i);
352 m_minute->setTransition(i);
353 updateTime();
354 }
355
356protected:
357 void resizeEvent(QResizeEvent*) {
358 int digitsWidth = width() / 2;
359 int digitsHeight = digitsWidth * 1.2;
360
361 int y = (height() - digitsHeight) / 3;
362
363 m_hour->resize(digitsWidth, digitsHeight);
364 m_hour->move(0, y);
365
366 m_minute->resize(digitsWidth, digitsHeight);
367 m_minute->move(width() / 2, y);
368 }
369
370 void timerEvent(QTimerEvent*) {
371 updateTime();
372 }
373
374 void keyPressEvent(QKeyEvent *event) {
375 if (event->key() == Qt::Key_Right) {
376 switchTransition(1);
377 event->accept();
378 }
379 if (event->key() == Qt::Key_Left) {
380 switchTransition(-1);
381 event->accept();
382 }
383 }
384
385private slots:
386 void chooseSlide() {
387 m_hour->setTransition(0);
388 m_minute->setTransition(0);
389 updateTime();
390 }
391
392 void chooseFlip() {
393 m_hour->setTransition(1);
394 m_minute->setTransition(1);
395 updateTime();
396 }
397
398 void chooseRotate() {
399 m_hour->setTransition(2);
400 m_minute->setTransition(2);
401 updateTime();
402 }
403
404private:
405 QBasicTimer m_ticker;
406 Digits *m_hour;
407 Digits *m_minute;
408};
409
410#include "digiflip.moc"
411
412int main(int argc, char *argv[])
413{
414 QApplication app(argc, argv);
415
416 DigiFlip time;
417#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
418 time.showMaximized();
419#else
420 time.resize(320, 240);
421 time.show();
422#endif
423
424 return app.exec();
425}
Note: See TracBrowser for help on using the repository browser.