Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/doc/src/examples/padnavigator.qdoc

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    77** This file is part of the documentation of the Qt Toolkit.
    88**
    9 ** $QT_BEGIN_LICENSE:LGPL$
     9** $QT_BEGIN_LICENSE:FDL$
    1010** Commercial Usage
    1111** Licensees holding valid Qt Commercial licenses may use this file in
    1212** 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.
     13** Software or, alternatively, in accordance with the terms contained in a
     14** written agreement between you and Nokia.
    1515**
    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.
     16** GNU Free Documentation License
     17** Alternatively, this file may be used under the terms of the GNU Free
     18** Documentation License version 1.3 as published by the Free Software
     19** Foundation and appearing in the file included in the packaging of this
     20** file.
    3521**
    3622** If you have questions regarding the use of this file, please contact
     
    4430    \title Pad Navigator Example
    4531
    46     The Pad Navigator Example shows how you can use Graphics View
    47     together with embedded widgets to create a simple but useful
    48     dynamic user interface for embedded devices.
     32    The Pad Navigator Example shows how you can use Graphics View together with
     33    embedded widgets and Qt's \l{State Machine Framework} to create a simple
     34    but useful, dynamic, animated user interface.
    4935
    5036    \image padnavigator-example.png
     37
     38    The interface consists of a flippable, rotating pad with icons that can be
     39    selected using the arrow keys on your keyboard or keypad. Pressing enter
     40    will flip the pad around and reveal its back side, which has a form
     41    embedded into a QGraphicsProxyWidget. You can interact with the form, and
     42    press the enter key to flip back to the front side of the pad at any time.
     43
     44    Graphics View provides the QGraphicsScene class for managing and
     45    interacting with a large number of custom-made 2D graphical items derived
     46    from the QGraphicsItem class, and a QGraphicsView widget for visualizing
     47    the items, with support for zooming and rotation.
     48
     49    This example consists of a \c RoundRectItem class, a \c FlippablePad class,
     50    a \c PadNavigator class, a \c SplashItem class, and a \c main() function.
     51
     52    \section1 RoundRectItem Class Definition
     53
     54    The \c RoundRectItem class is used by itself to diplay the icons on the
     55    pad, and as a base class for \c FlippablePad, the class for the pad itself.
     56    The role of the class is to paint a round rectangle of a specified size and
     57    gradient color, and optionally to paint a pixmap icon on top. To support \c
     58    FlippablePad it also allows filling its contents with a plain window
     59    background color.
     60
     61    Let's start by reviewing the \c RoundRectItem class declaration.
     62
     63    \snippet examples/graphicsview/padnavigator/roundrectitem.h 0
     64
     65    \c RoundRectItem inherits QGraphicsObject, which makes it easy to control
     66    its properties using QPropertyAnimation. Its constructor takes a rectangle
     67    to determine its bounds, and a color.
     68
     69    Besides implementing the mandatory \l{QGraphicsItem::paint()}{paint()} and
     70    \l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions,
     71    it also provides the \c pixmap and \c fill properties.
     72
     73    The \c pixmap property sets an optional pixmap that is drawn on top of the
     74    round rectangle. The \c fill property will, when true, fill the round
     75    rectangle contents with a fixed QPalette::Window background color.
     76    Otherwise the contents are filled using a gradient based on the color
     77    passed to \c RoundRectItem's constructor.
     78
     79    \snippet examples/graphicsview/padnavigator/roundrectitem.h 1
     80
     81    The private data members are:
     82
     83    \list
     84    \o \c pix: The optional pixmap that is drawn on top of the rectangle.
     85    \o \c fillRect: Corresponds to the \c fill property.
     86    \o \c color: The configurable gradient color fill of the rectangle.
     87    \o \c bounds: The bounds of the rectangle.
     88    \o \c gradient: A precalculated gradient used to fill the rectangle.
     89    \endlist
     90
     91    We will now review the \c RoundRectItem implementation. Let's start by
     92    looking at its constructor:
     93
     94    \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 0
     95
     96    The constructor initializes its member variables and forwards the \c parent
     97    argument to QGraphicsObject's constructor. It then constructs the linear
     98    gradient that is used in \l{QGraphicsItem::paint()}{paint()} to draw the
     99    round rectangle's gradient background. The linear gradient's starting point
     100    is at the top-left corner of the bounds, and the end is at the bottom-left
     101    corner. The start color is identical to the color passed as an argument,
     102    and a slightly darker color is chosen for the final stop.
     103
     104    We store this gradient as a member variable to avoid having to recreate the
     105    gradient every time the item is repainted.
     106
     107    Finally we set the cache mode
     108    \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}. This mode
     109    causes the item's rendering to be cached into an off-screen pixmap that
     110    remains persistent as we move and transform the item. This mode is ideal
     111    for this example, and works particularily well with OpenGL and OpenGL ES.
     112
     113    \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 1
     114
     115    The \c pixmap property implementation simple returns the member pixmap, or
     116    sets it and then calls \l{QGraphicsItem::update()}{update()}.
     117
     118    \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 2
     119
     120    As the \l{QGraphicsItem::paint()}{paint()} implementation below draws a
     121    simple drop shadow down and to the right of the item, we return a slightly
     122    adjusted rectangle from \l{QGraphicsItem::boundingRect()}{boundingRect()}.
     123
     124    \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 3
     125
     126    The \l{QGraphicsItem::paint()}{paint()} implementation starts by rendering
     127    a semi transparent black round rectangle drop shadow, two units down and to
     128    the right of the main item.
     129
     130    \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 4
     131
     132    We then draw the "foreground" round rectangle itself. The fill depends on
     133    the \c fill property; if true, we will with a plain QPalette::Window color.
     134    We get the corrent brush from QApplication::palette(). We assign a single
     135    unit wide pen for the stroke, assign the brush, and then draw the
     136    rectangle.
     137
     138    \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 5
     139
     140    If a pixmap has been assigned to the \e pixmap property, we draw this
     141    pixmap in the center of the rectangle item. The pixmaps are scaled to match
     142    the size of the icons; in arguably a better approach would have been to
     143    store the icons with the right size in the first places.
     144
     145    \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 6
     146
     147    Finally, for completeness we include the \c fill property implementation.
     148    It returns the \c fill member variable's value, and when assigned to, it
     149    calls \l{QGraphicsItem::update()}{update()}.
     150
     151    As mentioned already, \c RoundRectItem is the base class for \c
     152    FlippablePad, which is the class representing the tilting pad itself. We
     153    will proceed to reviewing \c FlippablePad.
     154
     155    \section1 FlippablePad Class Definition
     156
     157    \c FlippablePad is, in addition to its inherited \c RoundRectItem
     158    responsibilities, responsible for creating and managing a grid of icons.
     159
     160    \snippet examples/graphicsview/padnavigator/flippablepad.h 0
     161
     162    Its declaration is very simple: It inherits \c RoundRectItem and does not
     163    need any special polymorphic behavior. It's suitable to declare its own
     164    constructor, and a getter-function that allows \c PadNavigator to access
     165    the icons in the grid by (row, column).
     166
     167    The example has no "real" behavior or logic of any kind, and because of
     168    that, the icons do not need to provide any \e behavior or special
     169    interactions management. In a real application, however, it would be
     170    natural for the \c FlippablePad and its icons to handle more of the
     171    navigation logic. In this example, we have chosen to leave this to
     172    the \c PadNavigator class, which we will get back to below.
     173
     174    We will now review the \c FlippablePad implementation. This implementation
     175    starts with two helper functions: \c boundsFromSize() and \c
     176    posForLocation():
     177
     178    \snippet examples/graphicsview/padnavigator/flippablepad.cpp 0
     179
     180    \c boundsForSize() takes a QSize argument, and returns the bounding
     181    rectangle of the flippable pad item. The QSize determines how many rows and
     182    columns the icon grid should have. Each icon is given 150x150 units of
     183    space, and this determines the bounds.
     184
     185    \snippet examples/graphicsview/padnavigator/flippablepad.cpp 1
     186
     187    \c posForLocation() returns the position of an icon given its row and
     188    column position. Like \c boundsForSize(), the function assumes each icon is
     189    given 150x150 units of space, and that all icons are centered around the
     190    flippable pad item's origin (0, 0).
     191
     192    \snippet examples/graphicsview/padnavigator/flippablepad.cpp 2
     193
     194    The \c FlippablePad constructor passes suitable bounds (using \c
     195    boundsForSize()) and specific color to \c RoundRectItem's constructor.
     196
     197    \snippet examples/graphicsview/padnavigator/flippablepad.cpp 3
     198
     199    It then loads pixmaps from compiled-in resources to use for its icons.
     200    QDirIterator is very useful in this context, as it allows us to fetch all
     201    resource "*.png" files inside the \c :/images directory without explicitly
     202    naming the files.
     203
     204    We also make sure not to load more pixmaps than we need.
     205
     206    \snippet examples/graphicsview/padnavigator/flippablepad.cpp 4
     207
     208    Now that we have the pixmaps, we can create icons, position then and assign
     209    pixmaps. We start by finding a suitable size and color for the icons, and
     210    initializing a convenient grid structure for storing the icons. This \c
     211    iconGrid is also used later to find the icon for a specific (column, row)
     212    location.
     213
     214    For each row and column in our grid, we proceed to constructing each icon
     215    as an instance of \c RoundRectItem. The item is placed by using the \c
     216    posForLocation() helper function. To make room for the slip-behind
     217    selection item, we give each icon a \l{QGraphicsItem::zValue()}{Z-value} of
     218    1. The pixmaps are distributed to the icons in round-robin fasion.
     219
     220    Again, this approach is only suitable for example purposes. In a real-life
     221    application where each icon represents a specific action, it would be more
     222    natural to assign the pixmaps directly, or that the icons themselves
     223    provide suitable pixmaps.
     224
     225    \snippet examples/graphicsview/padnavigator/flippablepad.cpp 5
     226
     227    Finally, the \c iconAt() function returns a pointer to the icon at a
     228    specific row and column. It makes a somewhat bold assumption that the input
     229    is valid, which is fair because the \c PadNavigator class only calls this
     230    function with correct input.
     231
     232    We will now review the \c SplashItem class.
     233
     234    \section1 SplashItem Class Definition
     235
     236    The \c SplashItem class represents the "splash window", a semitransparent
     237    white overlay with text that appears immediately after the application has
     238    started, and disappears after pressing any key. The animation is controlled
     239    by \c PadNavigator; this class is very simple by itself.
     240
     241    \snippet examples/graphicsview/padnavigator/splashitem.h 0
     242
     243    The class declaration shows that \c SplashItem inherits QGraphicsObject to
     244    allow it to be controlled by QPropertyAnimation. It reimplements the
     245    mandatory \l{QGraphicsItem::paint()}{paint()} and
     246    \l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions,
     247    and keeps a \c text member variable which will contain the information text
     248    displayed on this splash item.
     249
     250    Let's look at its implementation.
     251
     252    \snippet examples/graphicsview/padnavigator/splashitem.cpp 0
     253
     254    The constructor forwards to QGraphicsObject as expected, assigns a text
     255    message to the \c text member variable, and enables
     256    \l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache}. This cache
     257    mode is suitable because the splash item only moves and is never
     258    transformed, and because it contains text, it's important that it has a
     259    pixel perfect visual appearance (in constrast to
     260    \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}, where the
     261    visual appearance is not as good).
     262
     263    We use caching to avoid having to relayout and rerender the text for each
     264    frame. An alterative approach would be to use the new QStaticText class.
     265
     266    \snippet examples/graphicsview/padnavigator/splashitem.cpp 1
     267
     268    \c SplashItem's bounding rectangle is fixed at (400x175).
     269
     270    \snippet examples/graphicsview/padnavigator/splashitem.cpp 2
     271
     272    The \l{QGraphicsItem::paint()}{paint()} implementation draws a clipped
     273    round rectangle with a thick 2-unit border and a semi-transparent white
     274    background. It proceeds to finding a suitable text area by adjusting the
     275    splash item's bounding rectangle with 10 units in each side. The text is
     276    rendered inside this rectangle, with top-left alignment, and with word
     277    wrapping enabled.
     278
     279    The main class now remains. We will proceed to reviewing \c PadNavigator.
     280
     281    \section1 PadNavigator Class Definition
     282
     283    \c PadNavigator represents the main window of our Pad Navigator Example
     284    application. It creates and controls a somewhat complex state machine, and
     285    several animations. Its class declaration is very simple:
     286
     287    \snippet examples/graphicsview/padnavigator/padnavigator.h 0
     288
     289    It inherits QGraphicsView and reimplements only one function:
     290    \l{QGraphicsView::resizeEvent()}{resizeEvent()}, to ensure the scene is
     291    scaled to fit inside the view when resizing the main window.
     292
     293    The \c PadNavigator constructor takes a QSize argument that determines the
     294    number or rows and columns in the grid.
     295
     296    It also keeps a private member instance, \c form, which is the generated
     297    code for the pad's back side item's QGraphicsProxyWidget-embedded form.
     298
     299    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 0
     300
     301    \c PadNavigator's constructor is a bit long. In short, its job is to create
     302    all items, including the \c FlippablePad, the \c SplashItem and the
     303    QGraphicsProxyWidget \c backItem, and then to set up all animations, states
     304    and transitions that control the behavior of the application.
     305
     306    It starts out simple, by forwarding to QGraphicsView's constructor.
     307
     308    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 1
     309
     310    The first item to be created is \c SplashItem. This is going to be a top-level
     311    item in the scene, next to \c FlippablePad, and stacked on top of it, so we
     312    assign it a \l{QGraphicsItem::zValue()}{Z-value} of 1.
     313
     314    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 2
     315
     316    Now we construct the \c FlippablePad item, passing its column-row count to
     317    its constructor.
     318
     319    The pad is constrolled by three transformations, and we create one
     320    QGraphicsRotation object for each of these.
     321
     322    \list
     323    \o \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is
     324    animated from 0 to 180, and eventually back, when enter is pressed on the
     325    keyboard, flipping the pad around.
     326    \o \c xRotation: Rotates the grid around its Qt::XAxis. This is used to
     327    tilt the pad vertically corresponding to which item is currently selected.
     328    This way, the selected item is always kept in front.
     329    \o \c yRotation: Rotates the grid around its Qt::YAxis. This is used to
     330    tilt the pad horizontally corresponding to which item is selected. This
     331    way, the selected item is always kept in front.
     332    \endlist
     333
     334    The combination of all three rotations is assigned via
     335    QGraphicsItem::setTransformations().
     336
     337    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 3
     338
     339    Now we construct the QGraphicsProxyWidget-embedded \c backItem. The proxy
     340    widget is created as a child of the pad. We create a new QWidget and
     341    populate it with the \c form member. To ensure the \c hostName line edit is
     342    the first to receive input focus when this item is shown, we call
     343    \l{QWidget::setFocus()}{setFocus()} immediately. This will not give the
     344    widget focus right away; it will only prepare the item to automatically
     345    receive focus once it is shown.
     346
     347    The QWidget based form is embedded into the proxy widget. The proxy is
     348    hidden initially; we only want to show it when the pad is rotated at least
     349    90 degrees, and we also rotate the proxy itself by 180 degrees. This way we
     350    give the impression that the proxy widget is "behind" the flipped pad, when
     351    in fact, it's actually \e{on top of it}.
     352
     353    We enable \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache} to
     354    ensure the flip animation can run smoothly.
     355
     356    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 4
     357
     358    We now create the selection item. This is simply another instance of \c
     359    RoundRectItem that is slightly larger than the icons on the pad. We create
     360    it as an immediate child of the \c FlippablePad, so the selection item is a
     361    sibling to all the icons. By giving it a
     362    \l{QGraphicsItem::zValue()}{Z-value} of 0.5 we ensure it will slide beteen
     363    the pad and its icons.
     364
     365    What follows now is a series of animation initializations.
     366
     367    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 5
     368
     369    We begin with the animations that apply to the splash item. The first
     370    animation, \c smoothSplashMove, ensures that the "y" property of \c splash
     371    will be animated with a 250-millisecond duration
     372    \l{QEasingCurve::InQuad}{InQuad} easing function. \c smoothSplashOpacity
     373    ensures the opacity of \c splash eases in and out in 250 milliseconds.
     374
     375    The values are assigned by \c PadNavigator's state machine, which is
     376    created later.
     377
     378    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 6
     379
     380    These are the animations that control the selection item's movement and the
     381    \c xRotation and \c yRotation QGraphicsRotation objects that tilt the pad.
     382    All animations have a duration of 125 milliseconds, and they all use the
     383    \l{QEasingCurve::InOutQuad}{InOutQuad} easing function.
     384
     385    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 7
     386
     387    We now create the animations that control the flip-effect when you press
     388    the enter key. The main goal is to rotate the pad by 180 degrees or back,
     389    but we also need to make sure the selection item's tilt rotations are reset
     390    back to 0 when the pad is flipped, and restored back to their original
     391    values when flipped back:
     392
     393    \list
     394    \o \c smoothFlipRotation: Animates the main 180 degree rotation of the pad.
     395    \o \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating.
     396    \o \c smoothFlipXRotation: Animates the selection item's X-tilt to 0 and back.
     397    \o \c smoothFlipYRotation: Animates the selection item's Y-tilt to 0 and back.
     398    \o \c flipAnimation: A parallel animation group that ensures all the above animations are run in parallel.
     399    \endlist
     400
     401    All animations are given a 500 millisecond duration and an
     402    \l{QEasingCurve::InOutQuad}{InOutQuad} easing function.
     403
     404    It's worth taking a close look at \c smoothFlipScale. This animation's
     405    start and end values are both 1.0, but at animation step 0.5 the
     406    animation's value is 0.7. This means that after 50% of the animation's
     407    duration, or 250 milliseconds, the pad will be scaled down to 0.7x of its
     408    original size, which gives a great visual effect while flipping.
     409
     410    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 8
     411
     412    This section uses a trick to ensure that certain properties are assigned
     413    precisely when the flip animation passes 50%, or 90 degrees, rotation. In
     414    short, the pad's icons and selection item are all hidden, the pad's \c fill
     415    property is enabled, and \c backItem is shown when flipping over. When
     416    flipping back, the reverse properties are applied.
     417
     418    The way this is achieved is by running a sequential animation in parallel
     419    to the other animations. This sequence, dubbed \c setVariablesSequence,
     420    starts with a 250 millisecond pause, and then executes several animations
     421    with a duration of 0. Each animation will ensure that properties are set
     422    immediate at this point.
     423
     424    This approach can also be used to call functions or set any other
     425    properties at a specific time while an animation is running.
     426
     427    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 9
     428
     429    We will now create the state machine. The whole \c PadNavigator state
     430    machinery is controlled by one single state machine that has a
     431    straight-forward state structure. The state engine itself is created
     432    as a child of the \c PadNavigator itself. We then create three top level
     433    states:
     434
     435    \list
     436    \o \c splashState: The initial state where the splash item is visible.
     437    \o \c frontState: The base state where the splash is gone and we can see
     438    the front side of the pad, and navigate the selection item.
     439    \o \c backState: The flipped state where the \c backItem is visible, and we
     440    can interact with the QGraphicsProxyWidget-embedded form.
     441    \endlist
     442
     443    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 10
     444
     445    Each state assigns specific properties to objects on entry. Most
     446    interesting perhaps is the assignment of the value 0.0 to the pad's \c
     447    flipRotation angle property when in \c frontState, and 180.0 when in \c
     448    backState. At the end of this section we register default animations with
     449    the state engine; these animations will apply to their respective objects
     450    and properties for any state transition. Otherwise it's common to assign
     451    animations to specific transitions.
     452
     453    The \c splashState state is set as the initial state. This is required
     454    before we start the state engine. We proceed with creating some
     455    transitions.
     456
     457    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 11
     458
     459    QEventTransition defines a very flexible transition type. You can use this
     460    class to trigger a transition based on an object receiving an event of a
     461    specific type. In this case, we would like to transition from \c
     462    splashState into \c frontState if \c PadNavigator receives any key press
     463    event (QEvent::KeyPress).
     464
     465    We register the \c splashItem's animations to this transition to ensure they
     466    are used to animate the item's movement and opacity.
     467
     468    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 12
     469
     470    We use QKeyEventTransition to capture specific key events. In this case, we
     471    detect that the user presses Qt::Key_Return or Qt::Key_Enter, and use this
     472    to trigger transitions between \c frontState and backState. We register \c
     473    flipAnimation, our complex parallel animation group, with these
     474    transitions.
     475
     476    We continue by defining the states for each of the icons in the grid.
     477
     478    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 13
     479
     480    We will use state groups to control transitions between icons. Each icon
     481    represents a \e substate of \c frontState. We will then define transitions
     482    between the states by detecting key presses, using QKeyEventTransition.
     483
     484    We start by creating all the substates, and at the same time we create a
     485    temporary grid structure for the states to make it easier to find which
     486    states represents icons that are up, down, left and to the right each
     487    other.
     488
     489    Once the first substate is known, we set this up as the initial substate of
     490    \c frontState. We will use the (0, 0), or top-left, icon for the initial
     491    substate. We initialze the selection item's position to be exactly where
     492    the top-left icon is.
     493
     494    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 14
     495
     496    We can now create four transitions for each icon. Each transition ensures
     497    that we move to the state corresponding to which arrow key has been
     498    pressed. It's clear from this techinique that we could design any other
     499    specific transitions to and from each of the sub states depending on these
     500    and other keys.
     501
     502    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 15
     503
     504    Also, for each of the icons, we assign suitable values to the \c xRotation
     505    and \c yRotation objects' "angle"-properties. If you recall, these
     506    properties "tilt" the pad corresponding to which item is currently
     507    selected. We ensure each icon is invisible when the pad is flipped, and
     508    visible when the pad is not flipped. To ensure the visible property is
     509    assigned at the right time, we add property-controlling animations to the
     510    \c setVariableSequence animation defined earlier.
     511
     512    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 16
     513
     514    We are now finished with all states, transitions, and animations. We now
     515    create the scene that will contain all our items. The scene gets a defined
     516    background pixmap, and we disable item indexing (as most items in this
     517    scene are animated). We add our \c pad item to the scene, and use its
     518    bounding rectangle to fixate the scene rectangle. This rectangle is used by
     519    the view to find a suitable size for the application window.
     520
     521    Then the scene is assigned to the view, or in our case, \c PadNavigator
     522    itself.
     523
     524    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 17
     525
     526    Now that the scene has received its final size, we can position the splash
     527    item at the very top, find its fade-out position, and add it to the scene.
     528
     529    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 18
     530
     531    The view toggles a few necessary properties:
     532
     533    \list
     534    \o It disables its scroll bars - this application has no use for scroll bars.
     535    \o It assigns a minimum size. This is necessary to avoid numerical errors
     536    in our fit-in-view \c resizeEvent() implementation.
     537    \o It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to
     538    ensure QGraphicsView doesn't spend time figuring out precisely what needs
     539    to be redrawn. This application is very simple - if anything changes,
     540    everything is updated.
     541    \o It enables background caching - this makes no performance difference
     542    with OpenGL, but without OpenGL it avoids unnecessary re-scaling of the
     543    background pixmap.
     544    \o It sets render hints that increase rendering quality.
     545    \o If OpenGL is supported, a QGLWidget viewport is assigned to the view.
     546    \endlist
     547
     548    Finally, we start the state engine.
     549
     550    \snippet examples/graphicsview/padnavigator/padnavigator.cpp 19
     551
     552    The \l{QGraphicsView::resizeEvent()}{resizeEvent()} implementation calls
     553    the base implementation, and then calls QGraphicsView::fitInView() to scale
     554    the scene so that it fits perfectly inside the view.
     555
     556    By resizing the main application window, you can see this effect yourself.
     557    The scene contents grow when you make the window larger, and shrink when
     558    you make it smaller, while keeping the aspect ratio intact.
     559
     560    \section1 The main() Function
     561
     562    \snippet examples/graphicsview/padnavigator/main.cpp 0
     563
     564    The \c main function creates the QApplication instance, uses
     565    Q_INIT_RESOURCE to ensure our compiled-in resources aren't removed by the
     566    linker, and then creates a 3x3 \c PadNavigator instance and shows it.
     567
     568    Our flippable pad shows up with a suitable splash item once control returns
     569    to the event loop.
     570
     571    \section1 Performance Notes
     572
     573    The example uses OpenGL if this is available, to achieve optimal
     574    performance; otherwise perspective tranformations can be quite costly.
     575
     576    Although this example does use QGraphicsProxyWidget to demonstrate
     577    integration of Qt widget components integrated into Graphics View, using
     578    QGraphicsProxyWidget comes with a performance penalty, and is therefore not
     579    recommended for embedded development.
     580
     581    This example uses extensive item caching to avoid rerendering of static
     582    elements, at the expense of graphics memory.
    51583*/
Note: See TracChangeset for help on using the changeset viewer.