|
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 widgets/shapedclock |
|
44 \title Shaped Clock Example |
|
45 |
|
46 The Shaped Clock example shows how to apply a widget mask to a top-level |
|
47 widget to produce a shaped window. |
|
48 |
|
49 \image shapedclock-example.png |
|
50 |
|
51 Widget masks are used to customize the shapes of top-level widgets by restricting |
|
52 the available area for painting. On some window systems, setting certain window flags |
|
53 will cause the window decoration (title bar, window frame, buttons) to be disabled, |
|
54 allowing specially-shaped windows to be created. In this example, we use this feature |
|
55 to create a circular window containing an analog clock. |
|
56 |
|
57 Since this example's window does not provide a \gui File menu or a close |
|
58 button, we provide a context menu with an \gui Exit entry so that the example |
|
59 can be closed. Click the right mouse button over the window to open this menu. |
|
60 |
|
61 \section1 ShapedClock Class Definition |
|
62 |
|
63 The \c ShapedClock class is based on the \c AnalogClock class defined in the |
|
64 \l{Analog Clock Example}{Analog Clock} example. The whole class definition is |
|
65 presented below: |
|
66 |
|
67 \snippet examples/widgets/shapedclock/shapedclock.h 0 |
|
68 |
|
69 The \l{QWidget::paintEvent()}{paintEvent()} implementation is the same as that found |
|
70 in the \c AnalogClock class. We implement \l{QWidget::sizeHint()}{sizeHint()} |
|
71 so that we don't have to resize the widget explicitly. We also provide an event |
|
72 handler for resize events. This allows us to update the mask if the clock is resized. |
|
73 |
|
74 Since the window containing the clock widget will have no title bar, we provide |
|
75 implementations for \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} and |
|
76 \l{QWidget::mousePressEvent()}{mousePressEvent()} to allow the clock to be dragged |
|
77 around the screen. The \c dragPosition variable lets us keep track of where the user |
|
78 last clicked on the widget. |
|
79 |
|
80 \section1 ShapedClock Class Implementation |
|
81 |
|
82 The \c ShapedClock constructor performs many of the same tasks as the \c AnalogClock |
|
83 constructor. We set up a timer and connect it to the widget's update() slot: |
|
84 |
|
85 \snippet examples/widgets/shapedclock/shapedclock.cpp 0 |
|
86 |
|
87 We inform the window manager that the widget is not to be decorated with a window |
|
88 frame by setting the Qt::FramelessWindowHint flag on the widget. As a result, we need |
|
89 to provide a way for the user to move the clock around the screen. |
|
90 |
|
91 Mouse button events are delivered to the \c mousePressEvent() handler: |
|
92 |
|
93 \snippet examples/widgets/shapedclock/shapedclock.cpp 1 |
|
94 |
|
95 If the left mouse button is pressed over the widget, we record the displacement in |
|
96 global (screen) coordinates between the top-left position of the widget's frame (even |
|
97 when hidden) and the point where the mouse click occurred. This displacement will be |
|
98 used if the user moves the mouse while holding down the left button. Since we acted |
|
99 on the event, we accept it by calling its \l{QEvent::accept()}{accept()} function. |
|
100 |
|
101 \image shapedclock-dragging.png |
|
102 |
|
103 The \c mouseMoveEvent() handler is called if the mouse is moved over the widget. |
|
104 |
|
105 \snippet examples/widgets/shapedclock/shapedclock.cpp 2 |
|
106 |
|
107 If the left button is held down while the mouse is moved, the top-left corner of the |
|
108 widget is moved to the point given by subtracting the \c dragPosition from the current |
|
109 cursor position in global coordinates. If we drag the widget, we also accept the event. |
|
110 |
|
111 The \c paintEvent() function is given for completeness. See the |
|
112 \l{Analog Clock Example}{Analog Clock} example for a description of the process used |
|
113 to render the clock. |
|
114 |
|
115 \snippet examples/widgets/shapedclock/shapedclock.cpp 3 |
|
116 |
|
117 In the \c resizeEvent() handler, we re-use some of the code from the \c paintEvent() |
|
118 to determine the region of the widget that is visible to the user: |
|
119 |
|
120 \snippet examples/widgets/shapedclock/shapedclock.cpp 4 |
|
121 |
|
122 Since the clock face is a circle drawn in the center of the widget, this is the region |
|
123 we use as the mask. |
|
124 |
|
125 Although the lack of a window frame may make it difficult for the user to resize the |
|
126 widget on some platforms, it will not necessarily be impossible. The \c resizeEvent() |
|
127 function ensures that the widget mask will always be updated if the widget's dimensions |
|
128 change, and additionally ensures that it will be set up correctly when the widget is |
|
129 first displayed. |
|
130 |
|
131 Finally, we implement the \c sizeHint() for the widget so that it is given a reasonable |
|
132 default size when it is first shown: |
|
133 |
|
134 \snippet examples/widgets/shapedclock/shapedclock.cpp 5 |
|
135 |
|
136 \section1 Notes on Widget Masks |
|
137 |
|
138 Since QRegion allows arbitrarily complex regions to be created, widget masks can be |
|
139 made to suit the most unconventionally-shaped windows, and even allow widgets to be |
|
140 displayed with holes in them. |
|
141 |
|
142 Widget masks can also be constructed by using the contents of pixmap to define the |
|
143 opaque part of the widget. For a pixmap with an alpha channel, a suitable mask can be |
|
144 obtained with QPixmap::mask(). |
|
145 */ |