doc/src/examples/simpledecoration.qdoc
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \example qws/simpledecoration
       
    44     \title Simple Decoration Example
       
    45     \ingroup qt-embedded
       
    46 
       
    47     The Simple Decoration example shows how to create a custom window decoration
       
    48     for embedded applications.
       
    49 
       
    50     \image embedded-simpledecoration-example.png
       
    51 
       
    52     By default, Qt for Embedded Linux applications display windows with one of
       
    53     the standard window decorations provided by Qt which are perfectly suitable
       
    54     for many situations. Nonetheless, for certain applications and devices, it
       
    55     is necessary to provide custom window decorations.
       
    56 
       
    57     In this document, we examine the fundamental features of custom window
       
    58     decorations, and create a simple decoration as an example.
       
    59 
       
    60     \section1 Styles and Window Decorations
       
    61 
       
    62     On many platforms, the style used for the contents of a window (including
       
    63     scroll bars) and the style used for the window decorations (the title bar,
       
    64     window borders, close, maximize and other buttons) are handled differently.
       
    65     This is usually because each application is responsible for rendering the
       
    66     contents of its own windows and the window manager renders the window
       
    67     decorations.
       
    68 
       
    69     Although the situation is not quite like this on Qt for Embedded Linux
       
    70     because QApplication automatically handles window decorations as well,
       
    71     there are still two style mechanisms at work: QStyle and its associated
       
    72     classes are responsible for rendering widgets and subclasses of QDecoration
       
    73     are responsible for rendering window decorations.
       
    74 
       
    75     \image embedded-simpledecoration-example-styles.png
       
    76 
       
    77     Three decorations are provided with Qt for Embedded Linux: \e default is
       
    78     a basic style, \e windows resembles the classic Windows look and feel,
       
    79     and \e styled uses the QStyle classes for QMdiSubWindow to draw window
       
    80     decorations. Of these, \e styled is the most useful if you want to impose
       
    81     a consistent look and feel, but the window decorations may be too large
       
    82     for some use cases.
       
    83 
       
    84     If none of these built-in decorations are suitable, a custom style can
       
    85     easily be created and used. To do this, we simply need to create a
       
    86     subclass of QDecorationDefault and apply it to a QApplication instance
       
    87     in a running application.
       
    88 
       
    89     \section1 MyDecoration Class Definition
       
    90 
       
    91     The \c MyDecoration class is a subclass of QDecorationDefault, a subclass
       
    92     of QDecoration that provides reasonable default behavior for a decoration:
       
    93 
       
    94     \snippet examples/qws/simpledecoration/mydecoration.h decoration class definition
       
    95 
       
    96     We only need to implement a constructor and reimplement the
       
    97     \l{QDecorationDefault::}{region()} and \l{QDecorationDefault::}{paint()}
       
    98     functions to provide our own custom appearance for window decorations.
       
    99 
       
   100     To make things fairly general, we provide a number of private variables
       
   101     to hold parameters which control certain aspects of the decoration's
       
   102     appearance. We also define some data structures that we will use to
       
   103     relate buttons in the window decorations to regions.
       
   104 
       
   105     \section1 MyDecoration Class Implementation
       
   106 
       
   107     In the constructor of the \c MyDecoration class, we set up some default
       
   108     values for the decoration, specifying a thin window border, a title
       
   109     bar that is just taller than the buttons it will hold, and we create a
       
   110     list of buttons that we support:
       
   111 
       
   112     \snippet examples/qws/simpledecoration/mydecoration.cpp constructor start
       
   113 
       
   114     We map each of these Qt::WindowFlags to QDecoration::DecorationRegion
       
   115     enum values to help with the implementation of the
       
   116     \l{#Finding Regions}{region() function implementation}.
       
   117 
       
   118     \snippet examples/qws/simpledecoration/mydecoration.cpp map window flags to decoration regions
       
   119 
       
   120     In this decoration, we implement the buttons used in the decoration as
       
   121     pixmaps. To help us relate regions of the window to these, we define
       
   122     mappings between each \l{QDecoration::}{DecorationRegion} and its
       
   123     corresponding pixmap for two situations: when a window is shown normally
       
   124     and when it has been maximized. This is purely for cosmetic purposes.
       
   125 
       
   126     \snippet examples/qws/simpledecoration/mydecoration.cpp map decoration regions to pixmaps
       
   127 
       
   128     We finish the constructor by defining the regions for buttons that we
       
   129     understand. This will be useful when we are asked to give regions for
       
   130     window decoration buttons.
       
   131 
       
   132     \snippet examples/qws/simpledecoration/mydecoration.cpp constructor end
       
   133 
       
   134     \section2 Finding Regions
       
   135 
       
   136     Each decoration needs to be able to describe the regions used for parts
       
   137     of the window furniture, such as the close button, window borders and
       
   138     title bar. We reimplement the \l{QDecorationDefault::}{region()} function
       
   139     to do this for our decoration. This function returns a QRegion object
       
   140     that describes an arbitrarily-shaped region of the screen that can itself
       
   141     be made up of several distinct areas.
       
   142 
       
   143     \snippet examples/qws/simpledecoration/mydecoration.cpp region start
       
   144 
       
   145     The function is called for a given \e widget, occupying a region specified
       
   146     by \e insideRect, and is expected to return a region for the collection of
       
   147     \l{QDecoration::}{DecorationRegion} enum values supplied in the
       
   148     \e decorationRegion parameter.
       
   149 
       
   150     We begin by figuring out how much space in the decoration we will need to
       
   151     allocate for buttons, and where to place them:
       
   152 
       
   153     \snippet examples/qws/simpledecoration/mydecoration.cpp calculate the positions of buttons based on the window flags used
       
   154 
       
   155     In a more sophisticated implementation, we might test the \e decorationRegion
       
   156     supplied for regions related to buttons and the title bar, and only perform
       
   157     this space allocation if asked for regions related to these.
       
   158 
       
   159     We also use the information about the area occupied by buttons to determine
       
   160     how large an area we can use for the window title:
       
   161 
       
   162     \snippet examples/qws/simpledecoration/mydecoration.cpp calculate the extent of the title
       
   163 
       
   164     With these basic calculations done, we can start to compose a region, first
       
   165     checking whether we have been asked for all of the window, and we return
       
   166     immediately if so.
       
   167 
       
   168     \snippet examples/qws/simpledecoration/mydecoration.cpp check for all regions
       
   169 
       
   170     We examine each decoration region in turn, adding the corresponding region
       
   171     to the \c region object created earlier. We take care to avoid "off by one"
       
   172     errors in the coordinate calculations.
       
   173 
       
   174     \snippet examples/qws/simpledecoration/mydecoration.cpp compose a region based on the decorations specified
       
   175 
       
   176     Unlike the window borders and title bar, the regions occupied by buttons
       
   177     many of the window decorations do not occupy fixed places in the window.
       
   178     Instead, their locations depend on which other buttons are present.
       
   179     We only add regions for buttons we can handle (defined in the \c stateRegions)
       
   180     member variable, and only for those that are present (defined in the
       
   181     \c buttons hash).
       
   182 
       
   183     \snippet examples/qws/simpledecoration/mydecoration.cpp add a region for each button only if it is present
       
   184 
       
   185     The fully composed region can then be returned:
       
   186 
       
   187     \snippet examples/qws/simpledecoration/mydecoration.cpp region end
       
   188 
       
   189     The information returned by this function is used when the decoration is
       
   190     painted. Ideally, this function should be implemented to perform all the
       
   191     calculations necessary to place elements of the decoration; this makes
       
   192     the implementation of the \c paint() function much easier.
       
   193 
       
   194     \section2 Painting the Decoration
       
   195 
       
   196     The \c paint() function is responsible for drawing each window element
       
   197     for a given widget. Information about the decoration region, its state
       
   198     and the widget itself is provided along with a QPainter object to use.
       
   199 
       
   200     The first check we make is for a call with no regions:
       
   201 
       
   202     \snippet examples/qws/simpledecoration/mydecoration.cpp paint start
       
   203 
       
   204     We return false to indicate that we have not painted anything. If we paint
       
   205     something, we must return true so that the window can be composed, if
       
   206     necessary.
       
   207 
       
   208     Just as with the \c region() function, we test the decoration region to
       
   209     determine which elements need to be drawn. If we paint anything, we set
       
   210     the \c handled variable to true so that we can return the correct value
       
   211     when we have finished.
       
   212 
       
   213     \snippet examples/qws/simpledecoration/mydecoration.cpp paint different regions
       
   214 
       
   215     Note that we use our own \c region() implementation to determine where
       
   216     to draw decorations.
       
   217 
       
   218     Since the \c region() function performs calculations to place buttons, we
       
   219     can simply test the window flags against the buttons we support (using the
       
   220     \c buttonHintMap defined in the constructor), and draw each button in the
       
   221     relevant region:
       
   222 
       
   223     \snippet examples/qws/simpledecoration/mydecoration.cpp paint buttons
       
   224 
       
   225     Finally, we return the value of \c handled to indicate whether any painting
       
   226     was performed:
       
   227 
       
   228     \snippet examples/qws/simpledecoration/mydecoration.cpp paint end
       
   229 
       
   230     We now have a decoration class that we can use in an application.
       
   231 
       
   232     \section1 Using the Decoration
       
   233 
       
   234     In the \c main.cpp file, we set up the application as usual, but we also
       
   235     create an instance of our decoration and set it as the standard decoration
       
   236     for the application:
       
   237 
       
   238     \snippet examples/qws/simpledecoration/main.cpp create application
       
   239 
       
   240     This causes all windows opened by this application to use our decoration.
       
   241     To demonstrate this, we show the analog clock widget from the
       
   242     \l{Analog Clock Example}, which we build into the application:
       
   243 
       
   244     \snippet examples/qws/simpledecoration/main.cpp start application
       
   245 
       
   246     The application can be run either
       
   247     \l{Running Qt for Embedded Linux Applications}{as a server or a client
       
   248     application}. In both cases, it will use our decoration rather than the
       
   249     default one provided with Qt.
       
   250 
       
   251     \section1 Notes
       
   252 
       
   253     This example does not cache any information about the state or buttons
       
   254     used for each window. This means that the \c region() function calculates
       
   255     the locations and regions of buttons in cases where it could re-use
       
   256     existing information.
       
   257 
       
   258     If you run the application as a window server, you may expect client
       
   259     applications to use our decoration in preference to the default Qt
       
   260     decoration. However, it is up to each application to draw its own
       
   261     decoration, so this will not happen automatically. One way to achieve
       
   262     this is to compile the decoration with each application that needs it;
       
   263     another way is to build the decoration as a plugin, using the
       
   264     QDecorationPlugin class, and load it into the server and client
       
   265     applications.
       
   266 */