Update copyright headers
[qt:qt.git] / doc / src / examples / concentriccircles.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 painting/concentriccircles
30     \title Concentric Circles Example
31
32     \brief The Concentric Circles example shows the improved rendering
33     quality that can be obtained using floating point precision and
34     anti-aliasing when drawing custom widgets. The example also shows
35     how to do simple animations.
36
37     The application's main window displays several widgets which are
38     drawn using the various combinations of precision and
39     anti-aliasing.
40
41     \image concentriccircles-example.png
42
43     Anti-aliasing is one of QPainter's render hints. The
44     QPainter::RenderHints are used to specify flags to QPainter that
45     may, or may not, be respected by any given
46     engine. QPainter::Antialiasing indicates that the engine should
47     anti-alias the edges of primitives if possible, i.e. put
48     additional pixels around the original ones to smooth the edges.
49
50     The difference between floating point precision and integer
51     precision is a matter of accuracy, and is visible in the
52     application's main window: Even though the logic that is
53     calculating the circles' geometry is the same, floating points
54     ensure that the white spaces between each circle are of the same
55     size, while integers make two and two circles appear as if they
56     belong together. The reason is that the integer based precision
57     rely on rounding off non-integer calculations.
58
59     The example consists of two classes:
60
61     \list
62     \o \c CircleWidget is a custom widget which renders several animated
63        concentric circles.
64     \o \c Window is the application's main window displaying four \c
65        {CircleWidget}s drawn using different combinations of precision
66        and aliasing.
67     \endlist
68
69     First we will review the CircleWidget class, then we will take a
70     look at the Window class.
71
72     \section1 CircleWidget Class Definition
73
74     The CircleWidget class inherits QWidget, and is a custom widget
75     which renders several animated concentric circles.
76
77     \snippet examples/painting/concentriccircles/circlewidget.h 0
78
79     We declare the \c floatBased and \c antialiased variables to hold
80     whether an instance of the class should be rendered with integer
81     or float based precision, and whether the rendering should be
82     anti-aliased or not. We also declare functions setting each of
83     these variables.
84
85     In addition we reimplement the QWidget::paintEvent() function to
86     apply the various combinations of precision and anti-aliasing when
87     rendering, and to support the animation. We reimplement the
88     QWidget::minimumSizeHint() and QWidget::sizeHint() functions to
89     give the widget a reasonable size within our application.
90
91     We declare the private \c nextAnimationFrame() slot, and the
92     associated \c frameNo variable holding the number of "animation
93     frames" for the widget, to facilitate the animation.
94
95     \section1 CircleWidget Class Implementation
96
97     In the constructor we make the widget's rendering integer based
98     and aliased by default:
99
100     \snippet examples/painting/concentriccircles/circlewidget.cpp 0
101
102     We initialize the widget's \c frameNo variable, and set the
103     widget's background color using the QWidget::setBackgroundColor()
104     function which takes a \l {QPalette::ColorRole}{color role} as
105     argument; the QPalette::Base color role is typically white.
106
107     Then we set the widgets size policy using the
108     QWidget::setSizePolicy() function. QSizePolicy::Expanding means
109     that the widget's \l {QWidget::sizeHint()}{sizeHint()} is a
110     sensible size, but that the widget can be shrunk and still be
111     useful. The widget can also make use of extra space, so it should
112     get as much space as possible.
113
114     \snippet examples/painting/concentriccircles/circlewidget.cpp 1
115     \codeline
116     \snippet examples/painting/concentriccircles/circlewidget.cpp 2
117
118     The public \c setFloatBased() and \c setAntialiased() functions
119     update the widget's rendering preferences, i.e. whether the widget
120     should be rendered with integer or float based precision, and
121     whether the rendering should be anti-aliased or not.
122
123     The functions also generate a paint event by calling the
124     QWidget::update() function, forcing a repaint of the widget with
125     the new rendering preferences.
126
127     \snippet examples/painting/concentriccircles/circlewidget.cpp 3
128     \codeline
129     \snippet examples/painting/concentriccircles/circlewidget.cpp 4
130
131     The default implementations of the QWidget::minimumSizeHint() and
132     QWidget::sizeHint() functions return invalid sizes if there is no
133     layout for the widget, otherwise they return the layout's minimum and
134     preferred size, respectively.
135
136     We reimplement the functions to give the widget minimum and
137     preferred sizes which are reasonable within our application.
138
139     \snippet examples/painting/concentriccircles/circlewidget.cpp 5
140
141     The nextAnimationFrame() slot simply increments the \c frameNo
142     variable's value, and calls the QWidget::update() function which
143     schedules a paint event for processing when Qt returns to the main
144     event loop.
145
146     \snippet examples/painting/concentriccircles/circlewidget.cpp 6
147
148     A paint event is a request to repaint all or part of the
149     widget. The \c paintEvent() function is an event handler that can
150     be reimplemented to receive the widget's paint events. We
151     reimplement the event handler to apply the various combinations of
152     precision and anti-aliasing when rendering the widget, and to
153     support the animation.
154
155     First, we create a QPainter for the widget, and set its
156     antialiased flag to the widget's preferred aliasing. We also
157     translate the painters coordinate system, preparing to draw the
158     widget's cocentric circles. The translation ensures that the
159     center of the circles will be equivalent to the widget's center.
160
161     \snippet examples/painting/concentriccircles/circlewidget.cpp 7
162
163     When painting a circle, we use the number of "animation frames" to
164     determine the alpha channel of the circle's color. The alpha
165     channel specifies the color's transparency effect, 0 represents a
166     fully transparent color, while 255 represents a fully opaque
167     color.
168
169     \snippet examples/painting/concentriccircles/circlewidget.cpp 8
170
171     If the calculated alpha channel is fully transparent, we don't
172     draw anything since that would be equivalent to drawing a white
173     circle on a white background. Instead we skip to the next circle
174     still creating a white space. If the calculated alpha channel is
175     fully opaque, we set the pen (the QColor passed to the QPen
176     constructor is converted into the required QBrush by default) and
177     draw the circle. If the widget's preferred precision is float
178     based, we specify the circle's bounding rectangle using QRectF and
179     double values, otherwise we use QRect and integers.
180
181     The animation is controlled by the public \c nextAnimationFrame()
182     slot: Whenever the \c nextAnimationFrame() slot is called the
183     number of frames is incremented and a paint event is
184     scheduled. Then, when the widget is repainted, the alpha-blending
185     of the circles' colors change and the circles appear as animated.
186
187     \section1 Window Class Definition
188
189     The Window class inherits QWidget, and is the application's main
190     window rendering four \c {CircleWidget}s using different
191     combinations of precision and aliasing.
192
193     \snippet examples/painting/concentriccircles/window.h 0
194
195     We declare the various components of the main window, i.e., the text
196     labels and a double array that will hold reference to the four \c
197     {CircleWidget}s. In addition we declare the private \c
198     createLabel() function to simplify the constructor.
199
200     \section1 Window Class Implementation
201
202     \snippet examples/painting/concentriccircles/window.cpp 0
203
204     In the constructor, we first create the various labels and put
205     them in a QGridLayout.
206
207     \snippet examples/painting/concentriccircles/window.cpp 1
208
209     Then we create a QTimer. The QTimer class is a high-level
210     programming interface for timers, and provides repetitive and
211     single-shot timers.
212
213     We create a timer to facilitate the animation of our concentric
214     circles; when we create the four CircleWidget instances (and add
215     them to the layout), we connect the QTimer::timeout() signal to
216     each of the widgets' \c nextAnimationFrame() slots.
217
218     \snippet examples/painting/concentriccircles/window.cpp 2
219
220     Before we set the layout and window title for our main window, we
221     make the timer start with a timeout interval of 100 milliseconds,
222     using the QTimer::start() function. That means that the
223     QTimer::timeout() signal will be emitted, forcing a repaint of the
224     four \c {CircleWidget}s, every 100 millisecond which is the reason
225     the circles appear as animated.
226
227     \snippet examples/painting/concentriccircles/window.cpp 3
228
229     The private \c createLabel() function is implemented to simlify
230     the constructor.
231 */