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