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