source: trunk/doc/src/examples/simpledecoration.qdoc@ 763

Last change on this file since 763 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 12.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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*/
Note: See TracBrowser for help on using the repository browser.