Update copyright headers
[qt:qt.git] / doc / src / examples / charactermap.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 widgets/charactermap
30 \title Character Map Example
31
32 \brief The Character Map example shows how to create a custom widget that can
33 both display its own content and respond to user input.
34
35 The example displays an array of characters which the user can click on
36 to enter text in a line edit. The contents of the line edit can then be
37 copied into the clipboard, and pasted into other applications. The
38 purpose behind this sort of tool is to allow users to enter characters
39 that may be unavailable or difficult to locate on their keyboards.
40
41 \image charactermap-example.png Screenshot of the Character Map example
42
43 The example consists of the following classes:
44
45 \list
46 \i \c CharacterWidget displays the available characters in the current
47    font and style.
48 \i \c MainWindow provides a standard main window that contains font and
49    style information, a view onto the characters, a line edit, and a push
50    button for submitting text to the clipboard.
51 \endlist
52
53 \section1 CharacterWidget Class Definition
54
55 The \c CharacterWidget class is used to display an array of characters in
56 a user-specified font and style. For flexibility, we subclass QWidget and
57 reimplement only the functions that we need to provide basic rendering
58 and interaction features.
59
60 The class definition looks like this:
61
62 \snippet examples/widgets/charactermap/characterwidget.h 0
63
64 The widget does not contain any other widgets, so it must provide its own
65 size hint to allow its contents to be displayed correctly.
66 We reimplement \l{QWidget::paintEvent()} to draw custom content. We also
67 reimplement \l{QWidget::mousePressEvent()} to allow the user to interact
68 with the widget.
69
70 The updateFont() and updateStyle() slots are used to update the font and
71 style of the characters in the widget whenever the user changes the
72 settings in the application.
73 The class defines the characterSelected() signal so that other parts
74 of the application are informed whenever the user selects a character in
75 the widget.
76 As a courtesy, the widget provides a tooltip that shows the current
77 character value. We reimplement the \l{QWidget::mouseMoveEvent()} event
78 handler and define showToolTip() to enable this feature.
79
80 The \c columns, \c displayFont and \c currentKey private data members
81 are used to record the number of columns to be shown, the current font,
82 and the currently highlighted character in the widget.
83
84 \section1 CharacterWidget Class Implementation
85
86 Since the widget is to be used as a simple canvas, the constructor just
87 calls the base class constructor and defines some default values for
88 private data members.
89
90 \snippet examples/widgets/charactermap/characterwidget.cpp 0
91
92 We initialize \c currentKey with a value of -1 to indicate
93 that no character is initially selected. We enable mouse tracking to
94 allow us to follow the movement of the cursor across the widget.
95
96 The class provides two functions to allow the font and style to be set up.
97 Each of these modify the widget's display font and call update():
98
99 \snippet examples/widgets/charactermap/characterwidget.cpp 1
100 \codeline
101 \snippet examples/widgets/charactermap/characterwidget.cpp 2
102
103 We use a fixed size font for the display. Similarly, a fixed size hint is
104 provided by the sizeHint() function:
105
106 \snippet examples/widgets/charactermap/characterwidget.cpp 3
107
108 Three standard event functions are implemented so that the widget
109 can respond to clicks, provide tooltips, and render the available
110 characters. The paintEvent() shows how the contents of the widget are
111 arranged and displayed:
112
113 \snippet examples/widgets/charactermap/characterwidget.cpp 6
114
115 A QPainter is created for the widget and, in all cases, we ensure that the
116 widget's background is painted. The painter's font is set to the
117 user-specified display font.
118
119 The area of the widget that needs to be redrawn is used to determine which
120 characters need to be displayed:
121
122 \snippet examples/widgets/charactermap/characterwidget.cpp 7
123
124 Using integer division, we obtain the row and column numbers of each
125 characters that should be displayed, and we draw a square on the widget
126 for each character displayed.
127
128 \snippet examples/widgets/charactermap/characterwidget.cpp 8
129 \snippet examples/widgets/charactermap/characterwidget.cpp 9
130
131 The symbols for each character in the array are drawn within each square,
132 with the symbol for the most recently selected character displayed in red:
133
134 \snippet examples/widgets/charactermap/characterwidget.cpp 10
135
136 We do not need to take into account the difference between the area
137 displayed in the viewport and the area we are drawing on because
138 everything outside the visible area will be clipped.
139
140 The mousePressEvent() defines how the widget responds to mouse clicks.
141
142 \snippet examples/widgets/charactermap/characterwidget.cpp 5
143
144 We are only interested when the user clicks with the left mouse button
145 over the widget. When this happens, we calculate which character was
146 selected and emit the characterSelected() signal.
147 The character's number is found by dividing the x and y-coordinates of
148 the click by the size of each character's grid square. Since the number
149 of columns in the widget is defined by the \c columns variable, we
150 simply multiply the row index by that value and add the column number
151 to obtain the character number.
152
153 If any other mouse button is pressed, the event is passed on to the
154 QWidget base class. This ensures that the event can be handled properly
155 by any other interested widgets.
156
157 The mouseMoveEvent() maps the mouse cursor's position in global
158 coordinates to widget coordinates, and determines the character that
159 was clicked by performing the calculation
160
161 \snippet examples/widgets/charactermap/characterwidget.cpp 4
162
163 The tooltip is given a position defined in global coordinates.
164
165 \section1 MainWindow Class Definition
166
167 The \c MainWindow class provides a minimal user interface for the example,
168 with only a constructor, slots that respond to signals emitted by standard
169 widgets, and some convenience functions that are used to set up the user
170 interface.
171
172 The class definition looks like this:
173
174 \snippet examples/widgets/charactermap/mainwindow.h 0
175
176 The main window contains various widgets that are used to control how
177 the characters will be displayed, and defines the findFonts() function
178 for clarity and convenience. The findStyles() slot is used by the widgets
179 to determine the styles that are available, insertCharacter() inserts
180 a user-selected character into the window's line edit, and
181 updateClipboard() synchronizes the clipboard with the contents of the
182 line edit.
183
184 \section1 MainWindow Class Implementation
185
186 In the constructor, we set up the window's central widget and fill it with
187 some standard widgets (two comboboxes, a line edit, and a push button).
188 We also construct a CharacterWidget custom widget, and add a QScrollArea
189 so that we can view its contents:
190
191 \snippet examples/widgets/charactermap/mainwindow.cpp 0
192
193 QScrollArea provides a viewport onto the \c CharacterWidget when we set
194 its widget and handles much of the work needed to provide a scrolling
195 viewport.
196
197 The font combo box is automatically popuplated with a list of available
198 fonts. We list the available styles for the current font in the style
199 combobox using the following function:
200
201 \snippet examples/widgets/charactermap/mainwindow.cpp 1
202
203 The line edit and push button are used to supply text to the clipboard:
204
205 \snippet examples/widgets/charactermap/mainwindow.cpp 2
206
207 We also obtain a clipboard object so that we can send text entered by the
208 user to other applications.
209
210 Most of the signals emitted in the example come from standard widgets.
211 We connect these signals to slots in this class, and to the slots provided
212 by other widgets.
213
214 \snippet examples/widgets/charactermap/mainwindow.cpp 4
215
216 The font combobox's
217 \l{QFontComboBox::currentFontChanged()}{currentFontChanged()} signal is
218 connected to the findStyles() function so that the list of available styles
219 can be shown for each font that is used. Since both the font and the style
220 can be changed by the user, the font combobox's currentFontChanged() signal
221 and the style combobox's
222 \l{QComboBox::currentIndexChanged()}{currentIndexChanged()} are connected
223 directly to the character widget.
224
225 The final two connections allow characters to be selected in the character
226 widget, and text to be inserted into the clipboard:
227
228 \snippet examples/widgets/charactermap/mainwindow.cpp 5
229
230 The character widget emits the characterSelected() custom signal when
231 the user clicks on a character, and this is handled by the insertCharacter()
232 function in this class. The clipboard is changed when the push button emits
233 the clicked() signal, and we handle this with the updateClipboard() function.
234
235 The remaining code in the constructor sets up the layout of the central widget,
236 and provides a window title:
237
238 \snippet examples/widgets/charactermap/mainwindow.cpp 6
239
240 The font combobox is automatically populated with a list of available font
241 families. The styles that can be used with each font are found by the
242 findStyles() function. This function is called whenever the user selects a
243 different font in the font combobox.
244
245 \snippet examples/widgets/charactermap/mainwindow.cpp 7
246
247 We begin by recording the currently selected style, and we clear the
248 style combobox so that we can insert the styles associated with the
249 current font family.
250
251 \snippet examples/widgets/charactermap/mainwindow.cpp 8
252
253 We use the font database to collect the styles that are available for the
254 current font, and insert them into the style combobox. The current item is
255 reset if the original style is not available for this font.
256
257 The last two functions are slots that respond to signals from the character
258 widget and the main window's push button. The insertCharacter() function is
259 used to insert characters from the character widget when the user clicks a
260 character:
261
262 \snippet examples/widgets/charactermap/mainwindow.cpp 9
263
264 The character is inserted into the line edit at the current cursor position.
265
266 The main window's "To clipboard" push button is connected to the
267 updateClipboard() function so that, when it is clicked, the clipboard is
268 updated to contain the contents of the line edit:
269
270 \snippet examples/widgets/charactermap/mainwindow.cpp 10
271
272 We copy all the text from the line edit to the clipboard, but we do not clear
273 the line edit.
274 */