summaryrefslogtreecommitdiffstats
path: root/doc/src/examples/dragdroprobot.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/examples/dragdroprobot.qdoc')
-rw-r--r--doc/src/examples/dragdroprobot.qdoc365
1 files changed, 0 insertions, 365 deletions
diff --git a/doc/src/examples/dragdroprobot.qdoc b/doc/src/examples/dragdroprobot.qdoc
deleted file mode 100644
index c6563a5286..0000000000
--- a/doc/src/examples/dragdroprobot.qdoc
+++ /dev/null
@@ -1,365 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** GNU Free Documentation License
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms
-** and conditions contained in a signed written agreement between you
-** and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example graphicsview/dragdroprobot
- \title Drag and Drop Robot Example
-
- The Drag and Drop Robot example shows how to implement Drag and Drop in a
- QGraphicsItem subclass, as well as how to animate items using Qt's
- \l{Animation Framework}.
-
- \image dragdroprobot-example.png
-
- Graphics View provides the QGraphicsScene class for managing and
- interacting with a large number of custom-made 2D graphical items derived
- from the QGraphicsItem class, and a QGraphicsView widget for visualizing
- the items, with support for zooming and rotation.
-
- This example consists of a \c Robot class, a \c ColorItem class, and a main
- function: the \c Robot class describes a simple robot consisting of several
- \c RobotPart derived limbs, including \c RobotHead and \c RobotLimb, the \c
- ColorItem class provides a draggable colored ellipse, and the \c main()
- function provides the main application window.
-
- We will first review the \c Robot class to see how to assemble the
- different parts so that they can be individually rotated and animated using
- QPropertyAnimation, and we will then review the \c ColorItem class to
- demonstrate how to implement Drag and Drop between items. Finally we will
- review the main() function to see how we can put all the pieces together,
- to form the final application.
-
- \section1 Robot Class Definition
-
- The robot consists of three main classes: the \c RobotHead, the \c
- RobotTorso, and the \c RobotLimb, which is used for the upper and lower
- arms and legs. All parts derive from the \c RobotPart class, which in turn
- inherits \c QGraphicsObject. The \c Robot class itself has no visual
- appearance and serves only as a root node for the robot.
-
- Let's start with the \c RobotPart class declaration.
-
- \snippet examples/graphicsview/dragdroprobot/robot.h 0
-
- This base class inherits QGraphicsObject. QGraphicsObject provides signals
- and slots through inheriting QObject, and it also declares QGraphicsItem's
- properties using Q_PROPERTY, which makes the properties accessible for
- QPropertyAnimation.
-
- RobotPart also implements the three most important event handlers for
- accepting drop events:
- \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()},
- \l{QGraphicsItem::dragLeaveEvent()}{dragLeaveEvent()}, and
- \l{QGraphicsItem::dropEvent()}{dropEvent()}.
-
- The color is stored as a member variable, along with the \c dragOver
- variable, which we will use later to indicate visually that the limb can
- accept colors that are is dragged onto it.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 0
-
- \c RobotPart's constructor initializes the dragOver member and sets the
- color to Qt::lightGray. In the constructor body we enable support for
- accepting drop events by calling
- \l{QGraphicsItem::setAcceptDrops()}{setAcceptDrops(true)}.
-
- The rest of this class's implementation is to support Drag and Drop.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 1
-
- The \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()} handler is called
- when a Drag and Drop element is dragged into the robot part's area.
-
- The handler implementation determines whether or not this item as a whole
- can accept the mime data assiciated with the incoming drag object. \c
- RobotPart provides a base behavior for all parts that accepts color drops.
- So if the incoming drag object contains a color, the event is accepted, we
- set \c dragOver to \c true and call update() to help provide positive
- visual feedback to the user; otherwise the event is ignored, which in turn
- allows the event to propagate to parent elements.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 2
-
- The \l{QGraphicsItem::dragLeaveEvent()}{dragLeaveEvent()} handler is called
- when a Drag and Drop element is dragged away from the robot part's area.
- Our implementation simply resets \e dragOver to false and calls
- \l{QGraphicsItem::update()}{update()} to help provide visual feedback that
- the drag has left this item.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 3
-
- The \l{QGraphicsItem::dropEvent()}{dropEvent()} handler is called when a
- Drag and Drop element is dropped onto an item (i.e., when the mouse button
- is released over the item while dragging).
-
- We reset \c dragOver to false, assign the item's new color, and call
- \l{QGraphicsItem::update()}{update()}.
-
- The declaration and implementation of \c RobotHead, \c RobotTorso, and \c
- RobotLimb are practically identical. We will review \c RobotHead in detail,
- as this class has one minor difference, and leave the other classes as an
- exercise for the reader.
-
- \snippet examples/graphicsview/dragdroprobot/robot.h 1
-
- The \c RobotHead class inherits \c RobotPart and provides the necessary
- implementations of \l{QGraphicsItem::boundingRect()}{boundingRect()} and
- \l{QGraphicsItem::paint()}{paint()}. It also reimplements
- \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()} and dropEvent() to
- provide special handling of image drops.
-
- The class contains a private pixmap member that we can use to implement
- support for accepting image drops.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 4
-
- \c RobotHead has a rather plain constructor that simply forwards to
- \c RobotPart's constructor.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 5
-
- The \l{QGraphicsItem::boundingRect()}{boundingRect()} reimplementation
- returns the extents for the head. Because we want the center of rotation to
- be the bottom center of the item, we have chosen a bounding rectangle that
- starts at (-15, -50) and extends to 30 units wide and 50 units tall. When
- rotating the head, the "neck" will stay still while the top of the head
- tilts from side to side.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 6
-
- In \l{QGraphicsItem::paint()}{paint()} we draw the actual head. The
- implementation is split into two sections; if an image has been dropped
- onto the head, we draw the image, otherwise we draw a round rectangular
- robot head with simple vector graphics.
-
- For performance reasons, depending on the complexity of what is painted, it
- can often be faster to draw the head as an image rather than using a
- sequence of vector operations.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 7
-
- The robot head can accept image drops. In order to support this, its
- reimplementation of \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()}
- checks if the drag object contains image data, and if it does, then the
- event is accepted. Otherwise we fall back to the base \c RobotPart
- implementation.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 8
-
- To follow up on image support, we must also implement
- \l{QGraphicsItem::dropEvent()}{dropEvent()}. We check if the drag object
- contains image data, and if it does, we store this data as a member pixmap
- and call \l{QGraphicsItem::update()}{update()}. This pixmap is used inside
- the \l{QGraphicsItem::paint()}{paint()} implementation that we reviewed
- before.
-
- \c RobotTorso and \c RobotLimb are similar to \c RobotHead, so let's
- skip directly to the \c Robot class.
-
- \snippet examples/graphicsview/dragdroprobot/robot.h 4
-
- The \c Robot class also inherits \c RobotPart, and like the other parts it
- also implements \l{QGraphicsItem::boundingRect()}{boundingRect()} and
- \l{QGraphicsItem::paint()}{paint()}. It provides a rather special
- implementation, though:
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 9
-
- Because the \c Robot class is only used as a base node for the rest of the
- robot, it has no visual representation. Its
- \l{QGraphicsItem::boundingRect()}{boundingRect()} implementation can
- therefore return a null QRectF, and its paint() function does nothing.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 10
-
- The constructor starts by setting the flag
- \l{QGraphicsItem::ItemHasNoContents}{ItemHasNoContents}, which is a minor
- optimization for items that have no visual appearance.
-
- We then construct all the robot parts (head, torso, and upper/lower arms
- and legs). The stacking order is very important, and we use the
- parent-child hierarchy to ensure the elements rotate and move properly. We
- construct the torso first, as this is the root element. We then construct
- the head and pass the torso to \c HeadItem's constructor. This will make
- the head a child of the torso; if you rotate the torso, the head will
- follow. The same pattern is applied to the rest of the limbs.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 11
-
- Each robot part is carefully positioned. For example, the upper left arm is
- moved precisely to the top-left area of the torso, and the upper right arm
- is moved to the top-right area.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 12
-
- The next section creates all animation objects. This snippet shows the two
- animations that operate on the head's scale and rotation. The two
- QPropertyAnimation instances simply set the object, property, and
- respective start and end values.
-
- All animations are controlled by one top-level parallel animation group.
- The scale and rotation animations are added to this group.
-
- The rest of the animations are defined in a similar way.
-
- \snippet examples/graphicsview/dragdroprobot/robot.cpp 13
-
- Finally we set an easing curve and duration on each animation, ensure the
- toplevel animation group loops forever, and start the toplevel animation.
-
- \section1 ColorItem Class Definition
-
- The \c ColorItem class represents a circular item that can be pressed to
- drag colors onto robot parts.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.h 0
-
- This class is very simple. It does not use animations, and has no need for
- properties nor signals and slots, so to save resources, it's most natural
- that it inherits QGraphicsItem (as opposed to QGraphicsObject).
-
- It declares the mandatory \l{QGraphicsItem::boundingRect()}{boundingRect()}
- and \l{QGraphicsItem::paint()}{paint()} functions, and adds
- reimplementations of
- \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()},
- \l{QGraphicsItem::mouseMoveEvent()}{mouseMoveEvent()}, and
- \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()}. It contains a
- single private color member.
-
- Let's take a look at its implementation.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 0
-
- \c ColorItem's constructor assigns an opaque random color to its color
- member by making use of qrand(). For improved usability, it assigns a
- tooltip that provides a useful hint to the user, and it also sets a
- suitable cursor. This ensures that the cursor will chance to
- Qt::OpenHandCursor when the mouse pointer hovers over the item.
-
- Finally, we call
- \l{QGraphicsItem::setAcceptedMouseButtons()}{setAcceptedMouseButtons()} to
- ensure that this item can only process Qt::LeftButton. This simplifies the
- mouse event handlers greatly, as we can always assume that only the left
- mouse button is pressed and released.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 1
-
- The item's bounding rect is a fixed 30x30 units centered around the item's
- origin (0, 0), and adjusted by 0.5 units in all directions to allow a
- scalable pen to draw its outline. For a final visual touch the bounds
- also compensate with a few units down and to the right to make room
- for a simple dropshadow.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 2
-
- The \l{QGraphicsItem::paint()}{paint()} implementation draws an ellipse
- with a 1-unit black outline, a plain color fill, and a dark gray
- dropshadow.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 3
-
- The \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()} handler is
- called when you press the mouse button inside the item's area. Our
- implementation simply sets the cursor to Qt::ClosedHandCursor.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 4
-
- The \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()} handler is
- called when you release the mouse button after having pressed it inside an
- item's area. Our implementation sets the cursor back to Qt::OpenHandCursor.
- The mouse press and release event handlers together provide useful visual
- feedback to the user: when you move the mouse pointer over a \c CircleItem,
- the cursor changes to an open hand. Pressing the item will show a closed
- hand cursor. Releasing will restore to an open hand cursor again.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 5
-
- The \l{QGraphicsItem::mouseMoveEvent()}{mouseMoveEvent()} handler is called
- when you move the mouse around after pressing the mouse button inside the
- \c ColorItem's area. This implementation provides the most important piece
- of logic for \c CircleItem: the code that starts and manages drags.
-
- The implementation starts by checking if the mouse has been dragged far
- enough to eliminate mouse jitter noise. We only want to start a drag if the
- mouse has been dragged farther than the application start drag distance.
-
- Continuing, we create a QDrag object, passing the event
- \l{QGraphicsSceneEvent::widget()}{widget} (i.e., the QGraphicsView
- viewport) to its constructor. Qt will ensure that this object is deleted at
- the right time. We also create a QMimeData instance that can contain our
- color or image data, and assign this to the drag object.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 6
-
- This snippet has a somewhat random outcome: once in a while, a special
- image is assigned to the drag object's mime data. The pixmap is also
- assiged as the drag object's pixmap. This will ensure that you can see the
- image that is being dragged as a pixmap under the mouse cursor.
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 7
-
- Otherwise, and this is the most common outcome, a simple color is assigned
- to the drag object's mime data. We render this \c ColorItem into a new
- pixmap to give the user visual feedback that the color is being "dragged".
-
- \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 8
-
- Finally we execute the drag. QDrag::exec() will reenter the event loop, and
- only exit if the drag has either been dropped, or canceled. In any case we
- reset the cursor to Qt::OpenHandCursor.
-
- \section1 The main() Function
-
- Now that the \c Robot and \c ColorItem classes are complete, we can put all
- the pieces together inside the main() function.
-
- \snippet examples/graphicsview/dragdroprobot/main.cpp 0
-
- We start off by constructing QApplication, and initializing the random
- number generator. This ensures that the color items have different colors
- every time the application starts.
-
- \snippet examples/graphicsview/dragdroprobot/main.cpp 1
-
- We construct a fixed size scene, and create 10 \c ColorItem instances
- arranged in a circle. Each item is added to the scene.
-
- In the center of this circle we create one \c Robot instance. The
- robot is scaled and moved up a few units. It is then added to the scene.
-
- \snippet examples/graphicsview/dragdroprobot/main.cpp 2
-
- Finally we create a QGraphicsView window, and assign the scene to it.
-
- For increased visual quality, we enable antialiasing. We also choose to use
- bounding rectangle updates to simplify visual update handling.
- The view is given a fixed sand-colored background, and a window title.
-
- We then show the view. The animations start immediately after
- control enters the event loop.
-*/
-