1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2017 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Data Visualization module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
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 https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include "qcustom3dlabel_p.h" |
31 | #include "utils_p.h" |
32 | |
33 | QT_BEGIN_NAMESPACE_DATAVISUALIZATION |
34 | |
35 | /*! |
36 | * \class QCustom3DLabel |
37 | * \inmodule QtDataVisualization |
38 | * \brief The QCustom3DLabel class adds a custom label to a graph. |
39 | * \since QtDataVisualization 1.1 |
40 | * |
41 | * The text, font, position, scaling, rotation, and colors of a custom label can |
42 | * be set. In addition, the visibility of the borders and background of the |
43 | * label can be toggled. Colors, borders, and background are determined by the |
44 | * active theme unless set explicitly. |
45 | * |
46 | * \note In scaling, the z-coordinate has no effect. Setting the same x- and |
47 | * y-coordinates retains the original font dimensions. |
48 | * |
49 | * \sa QAbstract3DGraph::addCustomItem() |
50 | */ |
51 | |
52 | /*! |
53 | * \qmltype Custom3DLabel |
54 | * \inqmlmodule QtDataVisualization |
55 | * \since QtDataVisualization 1.1 |
56 | * \ingroup datavisualization_qml |
57 | * \instantiates QCustom3DLabel |
58 | * \inherits Custom3DItem |
59 | * \brief Adds a custom label to a graph. |
60 | * |
61 | * The text, font, position, scaling, rotation, and colors of a custom label can |
62 | * be set. In addition, the visibility of the borders and background of the |
63 | * label can be toggled. Colors, borders, and background are determined by the |
64 | * active theme unless set explicitly. |
65 | * |
66 | * \note In scaling, the z-coordinate has no effect. Setting the same x- and |
67 | * y-coordinates retains the original font dimensions. |
68 | */ |
69 | |
70 | /*! \qmlproperty string Custom3DLabel::text |
71 | * |
72 | * The text for the label. Rich text is not supported. |
73 | */ |
74 | |
75 | /*! \qmlproperty font Custom3DLabel::font |
76 | * |
77 | * The font to be used for the label. Defaults to \c{Font {family: "Arial"; pointSize: 20}}. |
78 | * Special formatting (for example, outlined) is not supported. |
79 | */ |
80 | |
81 | /*! \qmlproperty color Custom3DLabel::textColor |
82 | * |
83 | * The color for the label text. Also affects label border, if enabled. Defaults to \c{"white"}. |
84 | * |
85 | * \sa borderEnabled |
86 | */ |
87 | |
88 | /*! \qmlproperty color Custom3DLabel::backgroundColor |
89 | * |
90 | * The color for the label background, if enabled. Defaults to \c{"gray"}. |
91 | * |
92 | * \sa backgroundEnabled |
93 | */ |
94 | |
95 | /*! \qmlproperty bool Custom3DLabel::backgroundEnabled |
96 | * |
97 | * Defines whether the label background is enabled. If set to \c{false}, |
98 | * backgroundColor has no effect. Defaults to \c{true}. |
99 | */ |
100 | |
101 | /*! \qmlproperty bool Custom3DLabel::borderEnabled |
102 | * |
103 | * Defines whether label borders are enabled. Defaults to \c{true}. |
104 | */ |
105 | |
106 | /*! \qmlproperty bool Custom3DLabel::facingCamera |
107 | * |
108 | * Defines whether the label will always face the camera. Defaults to \c{false}. |
109 | * If set to \c{true}, \l {QCustom3DItem::}{rotation} has no effect. |
110 | */ |
111 | |
112 | /*! |
113 | * Constructs a custom 3D label with the given \a parent. |
114 | */ |
115 | QCustom3DLabel::QCustom3DLabel(QObject *parent) : |
116 | QCustom3DItem(new QCustom3DLabelPrivate(this), parent) |
117 | { |
118 | } |
119 | |
120 | /*! |
121 | * Constructs a custom 3D label with the given \a text, \a font, \a position, \a scaling, |
122 | * \a rotation, and optional \a parent. |
123 | * |
124 | * \note Setting the same x- and y-coordinates for \a scaling retains the |
125 | * original font dimensions. |
126 | */ |
127 | QCustom3DLabel::QCustom3DLabel(const QString &text, const QFont &font, |
128 | const QVector3D &position, const QVector3D &scaling, |
129 | const QQuaternion &rotation, QObject *parent) : |
130 | QCustom3DItem(new QCustom3DLabelPrivate(this, text, font, position, scaling, rotation), |
131 | parent) |
132 | { |
133 | } |
134 | |
135 | /*! |
136 | * Deletes the custom 3D label. |
137 | */ |
138 | QCustom3DLabel::~QCustom3DLabel() |
139 | { |
140 | } |
141 | |
142 | /*! \property QCustom3DLabel::text |
143 | * |
144 | * \brief The text for the label. |
145 | * |
146 | * Rich text is not supported. |
147 | */ |
148 | void QCustom3DLabel::setText(const QString &text) |
149 | { |
150 | if (dptr()->m_text != text) { |
151 | dptr()->m_text = text; |
152 | dptr()->handleTextureChange(); |
153 | emit textChanged(text); |
154 | emit dptr()->needUpdate(); |
155 | } |
156 | } |
157 | |
158 | QString QCustom3DLabel::text() const |
159 | { |
160 | return dptrc()->m_text; |
161 | } |
162 | |
163 | /*! \property QCustom3DLabel::font |
164 | * |
165 | * \brief The font to be used for the label. |
166 | * |
167 | * Defaults to \c{QFont("Arial", 20)}. Special formatting |
168 | * (for example, outlined) is not supported. |
169 | */ |
170 | void QCustom3DLabel::setFont(const QFont &font) |
171 | { |
172 | if (dptr()->m_font != font) { |
173 | dptr()->m_font = font; |
174 | dptr()->handleTextureChange(); |
175 | emit fontChanged(font); |
176 | emit dptr()->needUpdate(); |
177 | } |
178 | } |
179 | |
180 | QFont QCustom3DLabel::font() const |
181 | { |
182 | return dptrc()->m_font; |
183 | } |
184 | |
185 | /*! \property QCustom3DLabel::textColor |
186 | * |
187 | * \brief The color for the label text. |
188 | * |
189 | * Also affects the label border, if enabled. Defaults to \c{Qt::white}. |
190 | * |
191 | * \sa borderEnabled |
192 | */ |
193 | void QCustom3DLabel::setTextColor(const QColor &color) |
194 | { |
195 | if (dptr()->m_txtColor != color) { |
196 | dptr()->m_txtColor = color; |
197 | dptr()->m_customVisuals = true; |
198 | dptr()->handleTextureChange(); |
199 | emit textColorChanged(color); |
200 | emit dptr()->needUpdate(); |
201 | } |
202 | } |
203 | |
204 | QColor QCustom3DLabel::textColor() const |
205 | { |
206 | return dptrc()->m_txtColor; |
207 | } |
208 | |
209 | /*! \property QCustom3DLabel::backgroundColor |
210 | * |
211 | * \brief The color for the label background, if enabled. |
212 | * |
213 | * Defaults to \c{Qt::gray}. |
214 | * |
215 | * \sa backgroundEnabled |
216 | */ |
217 | void QCustom3DLabel::setBackgroundColor(const QColor &color) |
218 | { |
219 | if (dptr()->m_bgrColor != color) { |
220 | dptr()->m_bgrColor = color; |
221 | dptr()->m_customVisuals = true; |
222 | dptr()->handleTextureChange(); |
223 | emit backgroundColorChanged(color); |
224 | emit dptr()->needUpdate(); |
225 | } |
226 | } |
227 | |
228 | QColor QCustom3DLabel::backgroundColor() const |
229 | { |
230 | return dptrc()->m_bgrColor; |
231 | } |
232 | |
233 | /*! \property QCustom3DLabel::borderEnabled |
234 | * |
235 | * \brief Whether label borders are enabled. |
236 | * |
237 | * Defaults to \c{true}. |
238 | */ |
239 | void QCustom3DLabel::setBorderEnabled(bool enabled) |
240 | { |
241 | if (dptr()->m_borders != enabled) { |
242 | dptr()->m_borders = enabled; |
243 | dptr()->m_customVisuals = true; |
244 | dptr()->handleTextureChange(); |
245 | emit borderEnabledChanged(enabled); |
246 | emit dptr()->needUpdate(); |
247 | } |
248 | } |
249 | |
250 | bool QCustom3DLabel::isBorderEnabled() const |
251 | { |
252 | return dptrc()->m_borders; |
253 | } |
254 | |
255 | /*! \property QCustom3DLabel::backgroundEnabled |
256 | * |
257 | * \brief Whether the label background is enabled. |
258 | * |
259 | * If set to \c{false}, backgroundColor() has no effect. Defaults |
260 | * to \c{true}. |
261 | */ |
262 | void QCustom3DLabel::setBackgroundEnabled(bool enabled) |
263 | { |
264 | if (dptr()->m_background != enabled) { |
265 | dptr()->m_background = enabled; |
266 | dptr()->m_customVisuals = true; |
267 | dptr()->handleTextureChange(); |
268 | emit backgroundEnabledChanged(enabled); |
269 | emit dptr()->needUpdate(); |
270 | } |
271 | } |
272 | |
273 | bool QCustom3DLabel::isBackgroundEnabled() const |
274 | { |
275 | return dptrc()->m_background; |
276 | } |
277 | |
278 | /*! \property QCustom3DLabel::facingCamera |
279 | * |
280 | * \brief Whether the label will always face the camera. |
281 | * |
282 | * Defaults to \c{false}. If set to \c{true}, rotation() |
283 | * has no effect. |
284 | */ |
285 | void QCustom3DLabel::setFacingCamera(bool enabled) |
286 | { |
287 | if (dptr()->m_facingCamera != enabled) { |
288 | dptr()->m_facingCamera = enabled; |
289 | dptr()->m_facingCameraDirty = true; |
290 | emit facingCameraChanged(enabled); |
291 | emit dptr()->needUpdate(); |
292 | } |
293 | } |
294 | |
295 | bool QCustom3DLabel::isFacingCamera() const |
296 | { |
297 | return dptrc()->m_facingCamera; |
298 | } |
299 | |
300 | /*! |
301 | * \internal |
302 | */ |
303 | QCustom3DLabelPrivate *QCustom3DLabel::dptr() |
304 | { |
305 | return static_cast<QCustom3DLabelPrivate *>(d_ptr.data()); |
306 | } |
307 | |
308 | /*! |
309 | * \internal |
310 | */ |
311 | const QCustom3DLabelPrivate *QCustom3DLabel::dptrc() const |
312 | { |
313 | return static_cast<const QCustom3DLabelPrivate *>(d_ptr.data()); |
314 | } |
315 | |
316 | QCustom3DLabelPrivate::QCustom3DLabelPrivate(QCustom3DLabel *q) : |
317 | QCustom3DItemPrivate(q), |
318 | m_font(QFont(QStringLiteral("Arial" ), 20)), |
319 | m_bgrColor(Qt::gray), |
320 | m_txtColor(Qt::white), |
321 | m_background(true), |
322 | m_borders(true), |
323 | m_facingCamera(false), |
324 | m_customVisuals(false), |
325 | m_facingCameraDirty(false) |
326 | { |
327 | m_isLabelItem = true; |
328 | m_shadowCasting = false; |
329 | m_meshFile = QStringLiteral(":/defaultMeshes/plane" ); |
330 | createTextureImage(); |
331 | } |
332 | |
333 | QCustom3DLabelPrivate::QCustom3DLabelPrivate(QCustom3DLabel *q, const QString &text, |
334 | const QFont &font, const QVector3D &position, |
335 | const QVector3D &scaling, |
336 | const QQuaternion &rotation) : |
337 | QCustom3DItemPrivate(q, QStringLiteral(":/defaultMeshes/plane" ), position, scaling, rotation), |
338 | m_text(text), |
339 | m_font(font), |
340 | m_bgrColor(Qt::gray), |
341 | m_txtColor(Qt::white), |
342 | m_background(true), |
343 | m_borders(true), |
344 | m_facingCamera(false), |
345 | m_customVisuals(false), |
346 | m_facingCameraDirty(false) |
347 | { |
348 | m_isLabelItem = true; |
349 | m_shadowCasting = false; |
350 | createTextureImage(); |
351 | } |
352 | |
353 | QCustom3DLabelPrivate::~QCustom3DLabelPrivate() |
354 | { |
355 | } |
356 | |
357 | void QCustom3DLabelPrivate::resetDirtyBits() |
358 | { |
359 | QCustom3DItemPrivate::resetDirtyBits(); |
360 | m_facingCameraDirty = false; |
361 | } |
362 | |
363 | void QCustom3DLabelPrivate::createTextureImage() |
364 | { |
365 | createTextureImage(bgrColor: m_bgrColor, txtColor: m_txtColor, background: m_background, borders: m_borders); |
366 | } |
367 | |
368 | void QCustom3DLabelPrivate::createTextureImage(const QColor &bgrColor, const QColor &txtColor, |
369 | bool background, bool borders) |
370 | { |
371 | m_textureImage = Utils::printTextToImage(font: m_font, text: m_text, bgrColor, txtColor, labelBackground: background, |
372 | borders, maxLabelWidth: 0); |
373 | } |
374 | |
375 | void QCustom3DLabelPrivate::handleTextureChange() |
376 | { |
377 | createTextureImage(); |
378 | m_dirtyBits.textureDirty = true; |
379 | if (!m_textureFile.isEmpty()) { |
380 | m_textureFile.clear(); |
381 | emit q_ptr->textureFileChanged(textureFile: m_textureFile); |
382 | } |
383 | } |
384 | |
385 | QT_END_NAMESPACE_DATAVISUALIZATION |
386 | |