doc/src/examples/pixelator.qdoc
changeset 7 f7bc934e204c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/examples/pixelator.qdoc	Wed Mar 31 11:06:36 2010 +0300
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** 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 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 itemviews/pixelator
+    \title Pixelator Example
+
+    The Pixelator example shows how delegates can be used to customize the way that
+    items are rendered in standard item views.
+
+    \image pixelator-example.png
+
+    By default, QTreeView, QTableView, and QListView use a standard item delegate
+    to display and edit a set of common data types that are sufficient for many
+    applications. However, an application may need to represent items of data in a
+    particular way, or provide support for rendering more specialized data types,
+    and this often requires the use of a custom delegate.
+
+    In this example, we show how to use custom delegates to modify the appearance
+    of standard views. To do this, we implement the following components:
+
+    \list
+    \i A model which represents each pixel in an image as an item of data, where each
+       item contains a value for the brightness of the corresponding pixel.
+    \i A custom delegate that uses the information supplied by the model to represent
+       each pixel as a black circle on a white background, where the radius of the
+       circle corresponds to the darkness of the pixel.
+    \endlist
+
+    This example may be useful for developers who want to implement their own table
+    models or custom delegates. The process of creating custom delegates for editing
+    item data is covered in the \l{Spin Box Delegate Example}{Spin Box Delegate}
+    example.
+
+    \section1 ImageModel Class Definition
+
+    The \c ImageModel class is defined as follows:
+
+    \snippet examples/itemviews/pixelator/imagemodel.h 0
+
+    Since we only require a simple, read-only table model, we only need to implement
+    functions to indicate the dimensions of the image and supply data to other
+    components.
+
+    For convenience, the image to be used is passed in the constructor.
+
+    \section1 ImageModel Class Implementation
+
+    The constructor is trivial:
+
+    \snippet examples/itemviews/pixelator/imagemodel.cpp 0
+
+    The \c setImage() function sets the image that will be used by the model:
+   
+    \snippet examples/itemviews/pixelator/imagemodel.cpp 1
+
+    The QAbstractItemModel::reset() call tells the view(s) that the model
+    has changed.
+
+    The \c rowCount() and \c columnCount() functions return the height and width of
+    the image respectively:
+
+    \snippet examples/itemviews/pixelator/imagemodel.cpp 2
+    \snippet examples/itemviews/pixelator/imagemodel.cpp 3
+
+    Since the image is a simple two-dimensional structure, the \c parent arguments
+    to these functions are unused. They both simply return the relevant size from
+    the underlying image object.
+
+    The \c data() function returns data for the item that corresponds to a given
+    model index in a format that is suitable for a particular role:
+
+    \snippet examples/itemviews/pixelator/imagemodel.cpp 4
+
+    In this implementation, we only check that the model index is valid, and that
+    the role requested is the \l{Qt::ItemDataRole}{DisplayRole}. If so, the function
+    returns the grayscale value of the relevant pixel in the image; otherwise, a null
+    model index is returned.
+
+    This model can be used with QTableView to display the integer brightness values
+    for the pixels in the image. However, we will implement a custom delegate to
+    display this information in a more artistic way.
+
+    The \c headerData() function is also reimplemented:
+
+    \snippet examples/itemviews/pixelator/imagemodel.cpp 5
+
+    We return (1, 1) as the size hint for a header item. If we
+    didn't, the headers would default to a larger size, preventing
+    us from displaying really small items (which can be specified
+    using the \gui{Pixel size} combobox).
+
+    \section1 PixelDelegate Class Definition
+
+    The \c PixelDelegate class is defined as follows:
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.h 0
+
+    This class provides only basic features for a delegate so, unlike the
+    \l{Spin Box Delegate Example}{Spin Box Delegate} example, we subclass
+    QAbstractItemDelegate instead of QItemDelegate.
+
+    We only need to reimplement \l{QAbstractItemDelegate::paint()}{paint()} and
+    \l{QAbstractItemDelegate::sizeHint()}{sizeHint()} in this class.
+    However, we also provide a delegate-specific \c setPixelSize() function so
+    that we can change the delegate's behavior via the signals and slots mechanism.
+
+    \section1 PixelDelegate Class Implementation
+
+    The \c PixelDelegate constructor is used to set up a default value for
+    the size of each "pixel" that it renders. The base class constructor is
+    also called to ensure that the delegate is set up with a parent object,
+    if one is supplied:
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 0
+
+    Each item is rendered by the delegate's
+    \l{QAbstractItemDelegate::paint()}{paint()} function. The view calls this
+    function with a ready-to-use QPainter object, style information that the
+    delegate should use to correctly draw the item, and an index to the item in
+    the model:
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 1
+
+    The first task the delegate has to perform is to draw the item's background
+    correctly. Usually, selected items appear differently to non-selected items,
+    so we begin by testing the state passed in the style option and filling the
+    background if necessary.
+
+    The radius of each circle is calculated in the following lines of code:
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 3
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 4
+
+    First, the largest possible radius of the circle is determined by taking the
+    smallest dimension of the style option's \c rect attribute.
+    Using the model index supplied, we obtain a value for the brightness of the
+    relevant pixel in the image. The radius of the circle is calculated by
+    scaling the brightness to fit within the item and subtracting it from the
+    largest possible radius.
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 5
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 6
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 7
+
+    We save the painter's state, turn on antialiasing (to obtain smoother
+    curves), and turn off the pen.
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 8
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 9
+
+    The foreground of the item (the circle representing a pixel) must be
+    rendered using an appropriate brush. For unselected items, we will use a
+    solid black brush; selected items are drawn using a predefined brush from
+    the style option's palette.
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 10
+
+    Finally, we paint the circle within the rectangle specified by the style
+    option and we call \l{QPainter::}{restore()} on the painter.
+
+    The \c paint() function does not have to be particularly complicated; it is
+    only necessary to ensure that the state of the painter when the function
+    returns is the same as it was when it was called. This usually
+    means that any transformations applied to the painter must be preceded by
+    a call to QPainter::save() and followed by a call to QPainter::restore().
+
+    The delegate's \l{QAbstractItemDelegate::}{sizeHint()} function
+    returns a size for the item based on the predefined pixel size, initially set
+    up in the constructor:
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 11
+
+    The delegate's size is updated whenever the pixel size is changed.
+    We provide a custom slot to do this:
+
+    \snippet examples/itemviews/pixelator/pixeldelegate.cpp 12
+
+    \section1 Using The Custom Delegate
+
+    In this example, we use a main window to display a table of data, using the
+    custom delegate to render each cell in a particular way. Much of the
+    \c MainWindow class performs tasks that are not related to item views. Here,
+    we only quote the parts that are relevant. You can look at the rest of the
+    implementation by following the links to the code at the top of this
+    document.
+
+    In the constructor, we set up a table view, turn off its grid, and hide its
+    headers:
+
+    \snippet examples/itemviews/pixelator/mainwindow.cpp 0
+    \dots
+    \snippet examples/itemviews/pixelator/mainwindow.cpp 1
+
+    This enables the items to be drawn without any gaps between them. Removing
+    the headers also prevents the user from adjusting the sizes of individual
+    rows and columns. 
+    
+    We also set the minimum section size to 1 on the headers. If we
+    didn't, the headers would default to a larger size, preventing
+    us from displaying really small items (which can be specified
+    using the \gui{Pixel size} combobox).
+
+    The custom delegate is constructed with the main window as its parent, so
+    that it will be deleted correctly later, and we set it on the table view.
+
+    \snippet examples/itemviews/pixelator/mainwindow.cpp 2
+
+    Each item in the table view will be rendered by the \c PixelDelegate
+    instance.
+
+    We construct a spin box to allow the user to change the size of each "pixel"
+    drawn by the delegate:
+
+    \snippet examples/itemviews/pixelator/mainwindow.cpp 3
+
+    This spin box is connected to the custom slot we implemented in the
+    \c PixelDelegate class. This ensures that the delegate always draws each
+    pixel at the currently specified size:
+
+    \snippet examples/itemviews/pixelator/mainwindow.cpp 4
+    \dots
+    \snippet examples/itemviews/pixelator/mainwindow.cpp 5
+
+    We also connect the spin box to a slot in the \c MainWindow class. This
+    forces the view to take into account the new size hints for each item;
+    these are provided by the delegate in its \c sizeHint() function.
+
+    \snippet examples/itemviews/pixelator/mainwindow.cpp 6
+
+    We explicitly resize the columns and rows to match the
+    \gui{Pixel size} combobox.
+*/