examples/graphicsview/padnavigator/padnavigator.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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]
       
    51 PadNavigator::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]
       
   301 void PadNavigator::resizeEvent(QResizeEvent *event)
       
   302 {
       
   303     QGraphicsView::resizeEvent(event);
       
   304     fitInView(scene()->sceneRect(), Qt::KeepAspectRatio);
       
   305 }
       
   306 //! [19]