source: trunk/examples/graphicsview/padnavigator/padnavigator.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 13.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "flippablepad.h"
42#include "padnavigator.h"
43#include "splashitem.h"
44
45#include <QtGui/QtGui>
46#ifndef QT_NO_OPENGL
47#include <QtOpenGL/QtOpenGL>
48#endif
49
50//! [0]
51PadNavigator::PadNavigator(const QSize &size, QWidget *parent)
52 : QGraphicsView(parent)
53{
54//! [0]
55//! [1]
56 // Splash item
57 SplashItem *splash = new SplashItem;
58 splash->setZValue(1);
59//! [1]
60
61//! [2]
62 // Pad item
63 FlippablePad *pad = new FlippablePad(size);
64 QGraphicsRotation *flipRotation = new QGraphicsRotation(pad);
65 QGraphicsRotation *xRotation = new QGraphicsRotation(pad);
66 QGraphicsRotation *yRotation = new QGraphicsRotation(pad);
67 flipRotation->setAxis(Qt::YAxis);
68 xRotation->setAxis(Qt::YAxis);
69 yRotation->setAxis(Qt::XAxis);
70 pad->setTransformations(QList<QGraphicsTransform *>()
71 << flipRotation
72 << xRotation << yRotation);
73//! [2]
74
75//! [3]
76 // Back (proxy widget) item
77 QGraphicsProxyWidget *backItem = new QGraphicsProxyWidget(pad);
78 QWidget *widget = new QWidget;
79 form.setupUi(widget);
80 form.hostName->setFocus();
81 backItem->setWidget(widget);
82 backItem->setVisible(false);
83 backItem->setFocus();
84 backItem->setCacheMode(QGraphicsItem::ItemCoordinateCache);
85 const QRectF r = backItem->rect();
86 backItem->setTransform(QTransform()
87 .rotate(180, Qt::YAxis)
88 .translate(-r.width()/2, -r.height()/2));
89//! [3]
90
91//! [4]
92 // Selection item
93 RoundRectItem *selectionItem = new RoundRectItem(QRectF(-60, -60, 120, 120),
94 Qt::gray, pad);
95 selectionItem->setZValue(0.5);
96//! [4]
97
98//! [5]
99 // Splash animations
100 QPropertyAnimation *smoothSplashMove = new QPropertyAnimation(splash, "y");
101 QPropertyAnimation *smoothSplashOpacity = new QPropertyAnimation(splash, "opacity");
102 smoothSplashMove->setEasingCurve(QEasingCurve::InQuad);
103 smoothSplashMove->setDuration(250);
104 smoothSplashOpacity->setDuration(250);
105//! [5]
106
107//! [6]
108 // Selection animation
109 QPropertyAnimation *smoothXSelection = new QPropertyAnimation(selectionItem, "x");
110 QPropertyAnimation *smoothYSelection = new QPropertyAnimation(selectionItem, "y");
111 QPropertyAnimation *smoothXRotation = new QPropertyAnimation(xRotation, "angle");
112 QPropertyAnimation *smoothYRotation = new QPropertyAnimation(yRotation, "angle");
113 smoothXSelection->setDuration(125);
114 smoothYSelection->setDuration(125);
115 smoothXRotation->setDuration(125);
116 smoothYRotation->setDuration(125);
117 smoothXSelection->setEasingCurve(QEasingCurve::InOutQuad);
118 smoothYSelection->setEasingCurve(QEasingCurve::InOutQuad);
119 smoothXRotation->setEasingCurve(QEasingCurve::InOutQuad);
120 smoothYRotation->setEasingCurve(QEasingCurve::InOutQuad);
121//! [6]
122
123//! [7]
124 // Flip animation setup
125 QPropertyAnimation *smoothFlipRotation = new QPropertyAnimation(flipRotation, "angle");
126 QPropertyAnimation *smoothFlipScale = new QPropertyAnimation(pad, "scale");
127 QPropertyAnimation *smoothFlipXRotation = new QPropertyAnimation(xRotation, "angle");
128 QPropertyAnimation *smoothFlipYRotation = new QPropertyAnimation(yRotation, "angle");
129 QParallelAnimationGroup *flipAnimation = new QParallelAnimationGroup(this);
130 smoothFlipScale->setDuration(500);
131 smoothFlipRotation->setDuration(500);
132 smoothFlipXRotation->setDuration(500);
133 smoothFlipYRotation->setDuration(500);
134 smoothFlipScale->setEasingCurve(QEasingCurve::InOutQuad);
135 smoothFlipRotation->setEasingCurve(QEasingCurve::InOutQuad);
136 smoothFlipXRotation->setEasingCurve(QEasingCurve::InOutQuad);
137 smoothFlipYRotation->setEasingCurve(QEasingCurve::InOutQuad);
138 smoothFlipScale->setKeyValueAt(0, qVariantValue<qreal>(1.0));
139 smoothFlipScale->setKeyValueAt(0.5, qVariantValue<qreal>(0.7));
140 smoothFlipScale->setKeyValueAt(1, qVariantValue<qreal>(1.0));
141 flipAnimation->addAnimation(smoothFlipRotation);
142 flipAnimation->addAnimation(smoothFlipScale);
143 flipAnimation->addAnimation(smoothFlipXRotation);
144 flipAnimation->addAnimation(smoothFlipYRotation);
145//! [7]
146
147//! [8]
148 // Flip animation delayed property assignment
149 QSequentialAnimationGroup *setVariablesSequence = new QSequentialAnimationGroup;
150 QPropertyAnimation *setFillAnimation = new QPropertyAnimation(pad, "fill");
151 QPropertyAnimation *setBackItemVisibleAnimation = new QPropertyAnimation(backItem, "visible");
152 QPropertyAnimation *setSelectionItemVisibleAnimation = new QPropertyAnimation(selectionItem, "visible");
153 setFillAnimation->setDuration(0);
154 setBackItemVisibleAnimation->setDuration(0);
155 setSelectionItemVisibleAnimation->setDuration(0);
156 setVariablesSequence->addPause(250);
157 setVariablesSequence->addAnimation(setBackItemVisibleAnimation);
158 setVariablesSequence->addAnimation(setSelectionItemVisibleAnimation);
159 setVariablesSequence->addAnimation(setFillAnimation);
160 flipAnimation->addAnimation(setVariablesSequence);
161//! [8]
162
163//! [9]
164 // Build the state machine
165 QStateMachine *stateMachine = new QStateMachine(this);
166 QState *splashState = new QState(stateMachine);
167 QState *frontState = new QState(stateMachine);
168 QHistoryState *historyState = new QHistoryState(frontState);
169 QState *backState = new QState(stateMachine);
170//! [9]
171//! [10]
172 frontState->assignProperty(pad, "fill", false);
173 frontState->assignProperty(splash, "opacity", 0.0);
174 frontState->assignProperty(backItem, "visible", false);
175 frontState->assignProperty(flipRotation, "angle", qVariantValue<qreal>(0.0));
176 frontState->assignProperty(selectionItem, "visible", true);
177 backState->assignProperty(pad, "fill", true);
178 backState->assignProperty(backItem, "visible", true);
179 backState->assignProperty(xRotation, "angle", qVariantValue<qreal>(0.0));
180 backState->assignProperty(yRotation, "angle", qVariantValue<qreal>(0.0));
181 backState->assignProperty(flipRotation, "angle", qVariantValue<qreal>(180.0));
182 backState->assignProperty(selectionItem, "visible", false);
183 stateMachine->addDefaultAnimation(smoothXRotation);
184 stateMachine->addDefaultAnimation(smoothYRotation);
185 stateMachine->addDefaultAnimation(smoothXSelection);
186 stateMachine->addDefaultAnimation(smoothYSelection);
187 stateMachine->setInitialState(splashState);
188//! [10]
189
190//! [11]
191 // Transitions
192 QEventTransition *anyKeyTransition = new QEventTransition(this, QEvent::KeyPress, splashState);
193 anyKeyTransition->setTargetState(frontState);
194 anyKeyTransition->addAnimation(smoothSplashMove);
195 anyKeyTransition->addAnimation(smoothSplashOpacity);
196//! [11]
197
198//! [12]
199 QKeyEventTransition *enterTransition = new QKeyEventTransition(this, QEvent::KeyPress,
200 Qt::Key_Enter, backState);
201 QKeyEventTransition *returnTransition = new QKeyEventTransition(this, QEvent::KeyPress,
202 Qt::Key_Return, backState);
203 QKeyEventTransition *backEnterTransition = new QKeyEventTransition(this, QEvent::KeyPress,
204 Qt::Key_Enter, frontState);
205 QKeyEventTransition *backReturnTransition = new QKeyEventTransition(this, QEvent::KeyPress,
206 Qt::Key_Return, frontState);
207 enterTransition->setTargetState(historyState);
208 returnTransition->setTargetState(historyState);
209 backEnterTransition->setTargetState(backState);
210 backReturnTransition->setTargetState(backState);
211 enterTransition->addAnimation(flipAnimation);
212 returnTransition->addAnimation(flipAnimation);
213 backEnterTransition->addAnimation(flipAnimation);
214 backReturnTransition->addAnimation(flipAnimation);
215//! [12]
216
217//! [13]
218 // Create substates for each icon; store in temporary grid.
219 int columns = size.width();
220 int rows = size.height();
221 QVector< QVector< QState * > > stateGrid;
222 stateGrid.resize(rows);
223 for (int y = 0; y < rows; ++y) {
224 stateGrid[y].resize(columns);
225 for (int x = 0; x < columns; ++x)
226 stateGrid[y][x] = new QState(frontState);
227 }
228 frontState->setInitialState(stateGrid[0][0]);
229 selectionItem->setPos(pad->iconAt(0, 0)->pos());
230//! [13]
231
232//! [14]
233 // Enable key navigation using state transitions
234 for (int y = 0; y < rows; ++y) {
235 for (int x = 0; x < columns; ++x) {
236 QState *state = stateGrid[y][x];
237 QKeyEventTransition *rightTransition = new QKeyEventTransition(this, QEvent::KeyPress,
238 Qt::Key_Right, state);
239 QKeyEventTransition *leftTransition = new QKeyEventTransition(this, QEvent::KeyPress,
240 Qt::Key_Left, state);
241 QKeyEventTransition *downTransition = new QKeyEventTransition(this, QEvent::KeyPress,
242 Qt::Key_Down, state);
243 QKeyEventTransition *upTransition = new QKeyEventTransition(this, QEvent::KeyPress,
244 Qt::Key_Up, state);
245 rightTransition->setTargetState(stateGrid[y][(x + 1) % columns]);
246 leftTransition->setTargetState(stateGrid[y][((x - 1) + columns) % columns]);
247 downTransition->setTargetState(stateGrid[(y + 1) % rows][x]);
248 upTransition->setTargetState(stateGrid[((y - 1) + rows) % rows][x]);
249//! [14]
250//! [15]
251 RoundRectItem *icon = pad->iconAt(x, y);
252 state->assignProperty(xRotation, "angle", -icon->x() / 6.0);
253 state->assignProperty(yRotation, "angle", icon->y() / 6.0);
254 state->assignProperty(selectionItem, "x", icon->x());
255 state->assignProperty(selectionItem, "y", icon->y());
256 frontState->assignProperty(icon, "visible", true);
257 backState->assignProperty(icon, "visible", false);
258
259 QPropertyAnimation *setIconVisibleAnimation = new QPropertyAnimation(icon, "visible");
260 setIconVisibleAnimation->setDuration(0);
261 setVariablesSequence->addAnimation(setIconVisibleAnimation);
262 }
263 }
264//! [15]
265
266//! [16]
267 // Scene
268 QGraphicsScene *scene = new QGraphicsScene(this);
269 scene->setBackgroundBrush(QPixmap(":/images/blue_angle_swirl.jpg"));
270 scene->setItemIndexMethod(QGraphicsScene::NoIndex);
271 scene->addItem(pad);
272 scene->setSceneRect(scene->itemsBoundingRect());
273 setScene(scene);
274//! [16]
275
276//! [17]
277 // Adjust splash item to scene contents
278 const QRectF sbr = splash->boundingRect();
279 splash->setPos(-sbr.width() / 2, scene->sceneRect().top() - 2);
280 frontState->assignProperty(splash, "y", splash->y() - 100.0);
281 scene->addItem(splash);
282//! [17]
283
284//! [18]
285 // View
286 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
287 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
288 setMinimumSize(50, 50);
289 setViewportUpdateMode(FullViewportUpdate);
290 setCacheMode(CacheBackground);
291 setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
292#ifndef QT_NO_OPENGL
293 setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
294#endif
295
296 stateMachine->start();
297//! [18]
298}
299
300//! [19]
301void PadNavigator::resizeEvent(QResizeEvent *event)
302{
303 QGraphicsView::resizeEvent(event);
304 fitInView(scene()->sceneRect(), Qt::KeepAspectRatio);
305}
306//! [19]
Note: See TracBrowser for help on using the repository browser.