diff options
Diffstat (limited to 'examples/graphicsview/padnavigator/padnavigator.cpp')
-rw-r--r-- | examples/graphicsview/padnavigator/padnavigator.cpp | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/examples/graphicsview/padnavigator/padnavigator.cpp b/examples/graphicsview/padnavigator/padnavigator.cpp new file mode 100644 index 0000000..b1d19f6 --- /dev/null +++ b/examples/graphicsview/padnavigator/padnavigator.cpp @@ -0,0 +1,307 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "flippablepad.h" +#include "padnavigator.h" +#include "splashitem.h" + +#include <QtGui/QtGui> +#ifndef QT_NO_OPENGL +#include <QtOpenGL/QtOpenGL> +#endif + +//! [0] +PadNavigator::PadNavigator(const QSize &size, QWidget *parent) + : QGraphicsView(parent) +{ +//! [0] +//! [1] + // Splash item + SplashItem *splash = new SplashItem; + splash->setZValue(1); +//! [1] + +//! [2] + // Pad item + FlippablePad *pad = new FlippablePad(size); + QGraphicsRotation *flipRotation = new QGraphicsRotation(pad); + QGraphicsRotation *xRotation = new QGraphicsRotation(pad); + QGraphicsRotation *yRotation = new QGraphicsRotation(pad); + flipRotation->setAxis(Qt::YAxis); + xRotation->setAxis(Qt::YAxis); + yRotation->setAxis(Qt::XAxis); + pad->setTransformations(QList<QGraphicsTransform *>() + << flipRotation + << xRotation << yRotation); +//! [2] + +//! [3] + // Back (proxy widget) item + QGraphicsProxyWidget *backItem = new QGraphicsProxyWidget(pad); + QWidget *widget = new QWidget; + form.setupUi(widget); + form.hostName->setFocus(); + backItem->setWidget(widget); + backItem->setVisible(false); + backItem->setFocus(); + backItem->setCacheMode(QGraphicsItem::ItemCoordinateCache); + const QRectF r = backItem->rect(); + backItem->setTransform(QTransform() + .rotate(180, Qt::YAxis) + .translate(-r.width()/2, -r.height()/2)); +//! [3] + +//! [4] + // Selection item + RoundRectItem *selectionItem = new RoundRectItem(QRectF(-60, -60, 120, 120), + Qt::gray, pad); + selectionItem->setZValue(0.5); +//! [4] + +//! [5] + // Splash animations + QPropertyAnimation *smoothSplashMove = new QPropertyAnimation(splash, "y"); + QPropertyAnimation *smoothSplashOpacity = new QPropertyAnimation(splash, "opacity"); + smoothSplashMove->setEasingCurve(QEasingCurve::InQuad); + smoothSplashMove->setDuration(250); + smoothSplashOpacity->setDuration(250); +//! [5] + +//! [6] + // Selection animation + QPropertyAnimation *smoothXSelection = new QPropertyAnimation(selectionItem, "x"); + QPropertyAnimation *smoothYSelection = new QPropertyAnimation(selectionItem, "y"); + QPropertyAnimation *smoothXRotation = new QPropertyAnimation(xRotation, "angle"); + QPropertyAnimation *smoothYRotation = new QPropertyAnimation(yRotation, "angle"); + smoothXSelection->setDuration(125); + smoothYSelection->setDuration(125); + smoothXRotation->setDuration(125); + smoothYRotation->setDuration(125); + smoothXSelection->setEasingCurve(QEasingCurve::InOutQuad); + smoothYSelection->setEasingCurve(QEasingCurve::InOutQuad); + smoothXRotation->setEasingCurve(QEasingCurve::InOutQuad); + smoothYRotation->setEasingCurve(QEasingCurve::InOutQuad); +//! [6] + +//! [7] + // Flip animation setup + QPropertyAnimation *smoothFlipRotation = new QPropertyAnimation(flipRotation, "angle"); + QPropertyAnimation *smoothFlipScale = new QPropertyAnimation(pad, "scale"); + QPropertyAnimation *smoothFlipXRotation = new QPropertyAnimation(xRotation, "angle"); + QPropertyAnimation *smoothFlipYRotation = new QPropertyAnimation(yRotation, "angle"); + QParallelAnimationGroup *flipAnimation = new QParallelAnimationGroup(this); + smoothFlipScale->setDuration(500); + smoothFlipRotation->setDuration(500); + smoothFlipXRotation->setDuration(500); + smoothFlipYRotation->setDuration(500); + smoothFlipScale->setEasingCurve(QEasingCurve::InOutQuad); + smoothFlipRotation->setEasingCurve(QEasingCurve::InOutQuad); + smoothFlipXRotation->setEasingCurve(QEasingCurve::InOutQuad); + smoothFlipYRotation->setEasingCurve(QEasingCurve::InOutQuad); + smoothFlipScale->setKeyValueAt(0, qVariantValue<qreal>(1.0)); + smoothFlipScale->setKeyValueAt(0.5, qVariantValue<qreal>(0.7)); + smoothFlipScale->setKeyValueAt(1, qVariantValue<qreal>(1.0)); + flipAnimation->addAnimation(smoothFlipRotation); + flipAnimation->addAnimation(smoothFlipScale); + flipAnimation->addAnimation(smoothFlipXRotation); + flipAnimation->addAnimation(smoothFlipYRotation); +//! [7] + +//! [8] + // Flip animation delayed property assignment + QSequentialAnimationGroup *setVariablesSequence = new QSequentialAnimationGroup; + QPropertyAnimation *setFillAnimation = new QPropertyAnimation(pad, "fill"); + QPropertyAnimation *setBackItemVisibleAnimation = new QPropertyAnimation(backItem, "visible"); + QPropertyAnimation *setSelectionItemVisibleAnimation = new QPropertyAnimation(selectionItem, "visible"); + setFillAnimation->setDuration(0); + setBackItemVisibleAnimation->setDuration(0); + setSelectionItemVisibleAnimation->setDuration(0); + setVariablesSequence->addPause(250); + setVariablesSequence->addAnimation(setBackItemVisibleAnimation); + setVariablesSequence->addAnimation(setSelectionItemVisibleAnimation); + setVariablesSequence->addAnimation(setFillAnimation); + flipAnimation->addAnimation(setVariablesSequence); +//! [8] + +//! [9] + // Build the state machine + QStateMachine *stateMachine = new QStateMachine(this); + QState *splashState = new QState(stateMachine); + QState *frontState = new QState(stateMachine); + QHistoryState *historyState = new QHistoryState(frontState); + QState *backState = new QState(stateMachine); +//! [9] +//! [10] + frontState->assignProperty(pad, "fill", false); + frontState->assignProperty(splash, "opacity", 0.0); + frontState->assignProperty(backItem, "visible", false); + frontState->assignProperty(flipRotation, "angle", qVariantValue<qreal>(0.0)); + frontState->assignProperty(selectionItem, "visible", true); + backState->assignProperty(pad, "fill", true); + backState->assignProperty(backItem, "visible", true); + backState->assignProperty(xRotation, "angle", qVariantValue<qreal>(0.0)); + backState->assignProperty(yRotation, "angle", qVariantValue<qreal>(0.0)); + backState->assignProperty(flipRotation, "angle", qVariantValue<qreal>(180.0)); + backState->assignProperty(selectionItem, "visible", false); + stateMachine->addDefaultAnimation(smoothXRotation); + stateMachine->addDefaultAnimation(smoothYRotation); + stateMachine->addDefaultAnimation(smoothXSelection); + stateMachine->addDefaultAnimation(smoothYSelection); + stateMachine->setInitialState(splashState); +//! [10] + +//! [11] + // Transitions + QEventTransition *anyKeyTransition = new QEventTransition(this, QEvent::KeyPress, splashState); + anyKeyTransition->setTargetState(frontState); + anyKeyTransition->addAnimation(smoothSplashMove); + anyKeyTransition->addAnimation(smoothSplashOpacity); +//! [11] + +//! [12] + QKeyEventTransition *enterTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Enter, backState); + QKeyEventTransition *returnTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Return, backState); + QKeyEventTransition *backEnterTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Enter, frontState); + QKeyEventTransition *backReturnTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Return, frontState); + enterTransition->setTargetState(historyState); + returnTransition->setTargetState(historyState); + backEnterTransition->setTargetState(backState); + backReturnTransition->setTargetState(backState); + enterTransition->addAnimation(flipAnimation); + returnTransition->addAnimation(flipAnimation); + backEnterTransition->addAnimation(flipAnimation); + backReturnTransition->addAnimation(flipAnimation); +//! [12] + +//! [13] + // Create substates for each icon; store in temporary grid. + int columns = size.width(); + int rows = size.height(); + QVector< QVector< QState * > > stateGrid; + stateGrid.resize(rows); + for (int y = 0; y < rows; ++y) { + stateGrid[y].resize(columns); + for (int x = 0; x < columns; ++x) + stateGrid[y][x] = new QState(frontState); + } + frontState->setInitialState(stateGrid[0][0]); + selectionItem->setPos(pad->iconAt(0, 0)->pos()); +//! [13] + +//! [14] + // Enable key navigation using state transitions + for (int y = 0; y < rows; ++y) { + for (int x = 0; x < columns; ++x) { + QState *state = stateGrid[y][x]; + QKeyEventTransition *rightTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Right, state); + QKeyEventTransition *leftTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Left, state); + QKeyEventTransition *downTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Down, state); + QKeyEventTransition *upTransition = new QKeyEventTransition(this, QEvent::KeyPress, + Qt::Key_Up, state); + rightTransition->setTargetState(stateGrid[y][(x + 1) % columns]); + leftTransition->setTargetState(stateGrid[y][((x - 1) + columns) % columns]); + downTransition->setTargetState(stateGrid[(y + 1) % rows][x]); + upTransition->setTargetState(stateGrid[((y - 1) + rows) % rows][x]); +//! [14] +//! [15] + RoundRectItem *icon = pad->iconAt(x, y); + state->assignProperty(xRotation, "angle", -icon->x() / 6.0); + state->assignProperty(yRotation, "angle", icon->y() / 6.0); + state->assignProperty(selectionItem, "x", icon->x()); + state->assignProperty(selectionItem, "y", icon->y()); + frontState->assignProperty(icon, "visible", true); + backState->assignProperty(icon, "visible", false); + + QPropertyAnimation *setIconVisibleAnimation = new QPropertyAnimation(icon, "visible"); + setIconVisibleAnimation->setDuration(0); + setVariablesSequence->addAnimation(setIconVisibleAnimation); + } + } +//! [15] + +//! [16] + // Scene + QGraphicsScene *scene = new QGraphicsScene(this); + scene->setBackgroundBrush(QPixmap(":/images/blue_angle_swirl.jpg")); + scene->setItemIndexMethod(QGraphicsScene::NoIndex); + scene->addItem(pad); + scene->setSceneRect(scene->itemsBoundingRect()); + setScene(scene); +//! [16] + +//! [17] + // Adjust splash item to scene contents + const QRectF sbr = splash->boundingRect(); + splash->setPos(-sbr.width() / 2, scene->sceneRect().top() - 2); + frontState->assignProperty(splash, "y", splash->y() - 100.0); + scene->addItem(splash); +//! [17] + +//! [18] + // View + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setMinimumSize(50, 50); + setViewportUpdateMode(FullViewportUpdate); + setCacheMode(CacheBackground); + setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); +#ifndef QT_NO_OPENGL + setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); +#endif + + stateMachine->start(); +//! [18] +} + +//! [19] +void PadNavigator::resizeEvent(QResizeEvent *event) +{ + QGraphicsView::resizeEvent(event); + fitInView(scene()->sceneRect(), Qt::KeepAspectRatio); +} +//! [19] |