doc/src/examples/transformations.qdoc
changeset 0 1918ee327afb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/examples/transformations.qdoc	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation 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$
+**
+****************************************************************************/
+
+/*!
+    \example painting/transformations
+    \title Transformations Example
+
+    The Transformations example shows how transformations influence
+    the way that QPainter renders graphics primitives. In particular
+    it shows how the order of transformations affect the result.
+
+    \image transformations-example.png
+
+    The application allows the user to manipulate the rendering of a
+    shape by changing the translation, rotation and scale of
+    QPainter's coordinate system.
+
+    The example consists of two classes and a global enum:
+
+    \list
+    \o The \c RenderArea class controls the rendering of a given shape.
+    \o The \c Window class is the application's main window.
+    \o The \c Operation enum describes the various transformation
+       operations available in the application.
+    \endlist
+
+    First we will take a quick look at the \c Operation enum, then we
+    will review the \c RenderArea class to see how a shape is
+    rendered. Finally, we will take a look at the Transformations
+    application's features implemented in the \c Window class.
+
+    \section1 Transformation Operations
+
+    Normally, the QPainter operates on the associated device's own
+    coordinate system, but it also has good support for coordinate
+    transformations.
+
+    The default coordinate system of a paint device has its origin at
+    the top-left corner. The x values increase to the right and the y
+    values increase downwards. You can scale the coordinate system by
+    a given offset using the QPainter::scale() function, you can
+    rotate it clockwise using the QPainter::rotate() function and you
+    can translate it (i.e. adding a given offset to the points) using
+    the QPainter::translate() function. You can also twist the
+    coordinate system around the origin (called shearing) using the
+    QPainter::shear() function.
+
+    All the tranformation operations operate on QPainter's
+    tranformation matrix that you can retrieve using the
+    QPainter::worldTransform() function. A matrix transforms a point in the
+    plane to another point. For more information about the
+    transformation matrix, see the \l {The Coordinate System} and
+    QTransform documentation.
+
+    \snippet examples/painting/transformations/renderarea.h 0
+
+    The global \c Operation enum is declared in the \c renderarea.h
+    file and describes the various transformation operations available
+    in the Transformations application.
+
+    \section1 RenderArea Class Definition
+
+    The \c RenderArea class inherits QWidget, and controls the
+    rendering of a given shape.
+
+    \snippet examples/painting/transformations/renderarea.h 1
+
+    We declare two public functions, \c setOperations() and
+    \c setShape(), to be able to specify the \c RenderArea widget's shape
+    and to transform the coordinate system the shape is rendered
+    within.
+
+    We reimplement the QWidget's \l
+    {QWidget::minimumSizeHint()}{minimumSizeHint()} and \l
+    {QWidget::sizeHint()}{sizeHint()} functions to give the \c
+    RenderArea widget a reasonable size within our application, and we
+    reimplement the QWidget::paintEvent() event handler to draw the
+    render area's shape applying the user's transformation choices.
+
+    \snippet examples/painting/transformations/renderarea.h 2
+
+    We also declare several convenience functions to draw the shape,
+    the coordinate system's outline and the coordinates, and to
+    transform the painter according to the chosen transformations.
+
+    In addition, the \c RenderArea widget keeps a list of the
+    currently applied transformation operations, a reference to its
+    shape, and a couple of convenience variables that we will use when
+    rendering the coordinates.
+
+    \section1 RenderArea Class Implementation
+
+    The \c RenderArea widget controls the rendering of a given shape,
+    including the transformations of the coordinate system, by
+    reimplementing the QWidget::paintEvent() event handler. But first
+    we will take a quick look at the constructor and at the functions
+    that provides access to the \c RenderArea widget:
+
+    \snippet examples/painting/transformations/renderarea.cpp 0
+
+    In the constructor we pass the parent parameter on to the base
+    class, and customize the font that we will use to render the
+    coordinates. The QWidget::font() funtion returns the font
+    currently set for the widget. As long as no special font has been
+    set, or after QWidget::setFont() is called, this is either a
+    special font for the widget class, the parent's font or (if this
+    widget is a top level widget) the default application font.
+
+    After ensuring that the font's size is 12 points, we extract the
+    rectangles enclosing the coordinate letters, 'x' and 'y',  using the
+    QFontMetrics class.
+
+    QFontMetrics provides functions to access the individual metrics
+    of the font, its characters, and for strings rendered in the
+    font. The QFontMetrics::boundingRect() function returns the
+    bounding rectangle of the given character relative to the
+    left-most point on the base line.
+
+    \snippet examples/painting/transformations/renderarea.cpp 1
+    \codeline
+    \snippet examples/painting/transformations/renderarea.cpp 2
+
+    In the \c setShape() and \c setOperations() functions we update
+    the \c RenderArea widget by storing the new value or values
+    followed by a call to the QWidget::update() slot which schedules a
+    paint event for processing when Qt returns to the main event loop.
+
+    \snippet examples/painting/transformations/renderarea.cpp 3
+    \codeline
+    \snippet examples/painting/transformations/renderarea.cpp 4
+
+    We reimplement the QWidget's \l
+    {QWidget::minimumSizeHint()}{minimumSizeHint()} and \l
+    {QWidget::sizeHint()}{sizeHint()} functions to give the \c
+    RenderArea widget a reasonable size within our application. The
+    default implementations of these functions returns an invalid size
+    if there is no layout for this widget, and returns the layout's
+    minimum size or preferred size, respectively, otherwise.
+
+    \snippet examples/painting/transformations/renderarea.cpp 5
+
+    The \c paintEvent() event handler recieves the \c RenderArea
+    widget's paint events. A paint event is a request to repaint all
+    or part of the widget. It can happen as a result of
+    QWidget::repaint() or QWidget::update(), or because the widget was
+    obscured and has now been uncovered, or for many other reasons.
+
+    First we create a QPainter for the \c RenderArea widget. The \l
+    {QPainter::RenderHint}{QPainter::Antialiasing} render hint
+    indicates that the engine should antialias edges of primitives if
+    possible. Then we erase the area that needs to be repainted using
+    the QPainter::fillRect() function.
+
+    We also translate the coordinate system with an constant offset to
+    ensure that the original shape is renderend with a suitable
+    margin.
+
+    \snippet examples/painting/transformations/renderarea.cpp 6
+
+    Before we start to render the shape, we call the QPainter::save()
+    function.
+
+    QPainter::save() saves the current painter state (i.e. pushes the
+    state onto a stack) including the current coordinate system. The
+    rationale for saving the painter state is that the following call
+    to the \c transformPainter() function will transform the
+    coordinate system depending on the currently chosen transformation
+    operations, and we need a way to get back to the original state to
+    draw the outline.
+
+    After transforming the coordinate system, we draw the \c
+    RenderArea's shape, and then we restore the painter state using
+    the QPainter::restore() function (i.e. popping the saved state off
+    the stack).
+
+    \snippet examples/painting/transformations/renderarea.cpp 7
+
+    Then we draw the square outline.
+
+    \snippet examples/painting/transformations/renderarea.cpp 8
+
+    Since we want the coordinates to correspond with the coordinate
+    system the shape is rendered within, we must make another call to
+    the \c transformPainter() function.
+
+    The order of the painting operations is essential with respect to
+    the shared pixels. The reason why we don't render the coordinates
+    when the coordinate system already is transformed to render the
+    shape, but instead defer their rendering to the end, is that we
+    want the coordinates to appear on top of the shape and its
+    outline.
+
+    There is no need to save the QPainter state this time since
+    drawing the coordinates is the last painting operation.
+
+    \snippet examples/painting/transformations/renderarea.cpp 9
+    \codeline
+    \snippet examples/painting/transformations/renderarea.cpp 10
+    \codeline
+    \snippet examples/painting/transformations/renderarea.cpp 11
+
+    The \c drawCoordinates(), \c drawOutline() and \c drawShape() are
+    convenience functions called from the \c paintEvent() event
+    handler. For more information about QPainter's basic drawing
+    operations and how to display basic graphics primitives, see the
+    \l {painting/basicdrawing}{Basic Drawing} example.
+
+    \snippet examples/painting/transformations/renderarea.cpp 12
+
+    The \c transformPainter() convenience function is also called from
+    the \c paintEvent() event handler, and transforms the given
+    QPainter's coordinate system according to the user's
+    transformation choices.
+
+    \section1 Window Class Definition
+
+    The \c Window class is the Transformations application's main
+    window.
+
+    The application displays four \c RenderArea widgets. The left-most
+    widget renders the shape in QPainter's default coordinate system,
+    the others render the shape with the chosen transformation in
+    addition to all the transformations applied to the \c RenderArea
+    widgets to their left.
+
+    \snippet examples/painting/transformations/window.h 0
+
+    We declare two public slots to make the application able to
+    respond to user interaction, updating the displayed \c RenderArea
+    widgets according to the user's transformation choices.
+
+    The \c operationChanged() slot updates each of the \c RenderArea
+    widgets applying the currently chosen transformation operations, and
+    is called whenever the user changes the selected operations. The
+    \c shapeSelected() slot updates the \c RenderArea widgets' shapes
+    whenever the user changes the preferred shape.
+
+    \snippet examples/painting/transformations/window.h 1
+
+    We also declare a private convenience function, \c setupShapes(),
+    that is used when constructing the \c Window widget, and we
+    declare pointers to the various components of the widget. We
+    choose to keep the available shapes in a QList of \l
+    {QPainterPath}s. In addition we declare a private enum counting
+    the number of displayed \c RenderArea widgets except the widget
+    that renders the shape in QPainter's default coordinate system.
+
+    \section1 Window Class Implementation
+
+    In the constructor we create and initialize the application's
+    components:
+
+    \snippet examples/painting/transformations/window.cpp 0
+
+    First we create the \c RenderArea widget that will render the
+    shape in the default coordinate system. We also create the
+    associated QComboBox that allows the user to choose among four
+    different shapes: A clock, a house, a text and a truck. The shapes
+    themselves are created at the end of the constructor, using the
+    \c setupShapes() convenience function.
+
+    \snippet examples/painting/transformations/window.cpp 1
+
+    Then we create the \c RenderArea widgets that will render their
+    shapes with coordinate tranformations. By default the applied
+    operation is \gui {No Transformation}, i.e. the shapes are
+    rendered within the default coordinate system. We create and
+    initialize the associated \l {QComboBox}es with items
+    corresponding to the various transformation operations decribed by
+    the global \c Operation enum.
+
+    We also connect the \l {QComboBox}es' \l
+    {QComboBox::activated()}{activated()} signal to the \c
+    operationChanged() slot to update the application whenever the
+    user changes the selected transformation operations.
+
+    \snippet examples/painting/transformations/window.cpp 2
+
+    Finally, we set the layout for the application window using the
+    QWidget::setLayout() function, construct the available shapes
+    using the private \c setupShapes() convenience function, and make
+    the application show the clock shape on startup using the public
+    \c shapeSelected() slot before we set the window title.
+
+
+    \snippet examples/painting/transformations/window.cpp 3
+    \snippet examples/painting/transformations/window.cpp 4
+    \snippet examples/painting/transformations/window.cpp 5
+    \snippet examples/painting/transformations/window.cpp 6
+    \dots
+
+    \snippet examples/painting/transformations/window.cpp 7
+
+    The \c setupShapes() function is called from the constructor and
+    create the QPainterPath objects representing the shapes that are
+    used in the application. For construction details, see the \l
+    {painting/transformations/window.cpp}{window.cpp} example
+    file. The shapes are stored in a QList. The QList::append()
+    function inserts the given shape at the end of the list.
+
+    We also connect the associated QComboBox's \l
+    {QComboBox::activated()}{activated()} signal to the \c
+    shapeSelected() slot to update the application when the user
+    changes the preferred shape.
+
+    \snippet examples/painting/transformations/window.cpp 8
+
+    The public \c operationChanged() slot is called whenever the user
+    changes the selected operations.
+
+    We retrieve the chosen transformation operation for each of the
+    transformed \c RenderArea widgets by querying the associated \l
+    {QComboBox}{QComboBoxes}. The transformed \c RenderArea widgets
+    are supposed to render the shape with the transformation specified
+    by its associated combobox \e {in addition to} all the
+    transformations applied to the \c RenderArea widgets to its
+    left. For that reason, for each widget we query, we append the
+    associated operation to a QList of transformations which we apply
+    to the widget before proceeding to the next.
+
+    \snippet examples/painting/transformations/window.cpp 9
+
+    The \c shapeSelected() slot is called whenever the user changes
+    the preferred shape, updating the \c RenderArea widgets using
+    their public \c setShape() function.
+
+    \section1 Summary
+
+    The Transformations example shows how transformations influence
+    the way that QPainter renders graphics primitives. Normally, the
+    QPainter operates on the device's own coordinate system, but it
+    also has good support for coordinate transformations. With the
+    Transformations application you can scale, rotate and translate
+    QPainter's coordinate system.  The order in which these
+    tranformations are applied is essential for the result.
+
+    All the tranformation operations operate on QPainter's
+    tranformation matrix. For more information about the
+    transformation matrix, see the \l {The Coordinate System} and
+    QTransform documentation.
+
+    The Qt reference documentation provides several painting
+    demos. Among these is the \l {demos/affine}{Affine
+    Transformations} demo that shows Qt's ability to perform
+    transformations on painting operations. The demo also allows the
+    user to experiment with the various transformation operations.
+*/