1 | // Copyright (C) 2023 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include "qabstract3dseries_p.h" |
5 | #include "qabstractdataproxy_p.h" |
6 | #include "abstract3dcontroller_p.h" |
7 | #include "utils_p.h" |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | /*! |
12 | * \class QAbstract3DSeries |
13 | * \inmodule QtGraphs |
14 | * \brief The QAbstract3DSeries class is a base class for all data series. |
15 | * |
16 | * There are inherited classes for each supported series type: QBar3DSeries, |
17 | * QScatter3DSeries, and QSurface3DSeries. |
18 | * |
19 | * For more information, see \l{Qt Graphs Data Handling}. |
20 | */ |
21 | |
22 | /*! |
23 | * \class QAbstract3DSeriesChangeBitField |
24 | * \internal |
25 | */ |
26 | |
27 | /*! |
28 | * \class QAbstract3DSeriesThemeOverrideBitField |
29 | * \internal |
30 | */ |
31 | |
32 | /*! |
33 | * \qmltype Abstract3DSeries |
34 | * \inqmlmodule QtGraphs |
35 | * \ingroup graphs_qml |
36 | * \instantiates QAbstract3DSeries |
37 | * \brief A base type for all data series. |
38 | * |
39 | * This type is uncreatable, but contains properties that are exposed via the |
40 | * following subtypes: Bar3DSeries, Scatter3DSeries, and Surface3DSeries. |
41 | * |
42 | * For more information, see \l{Qt Graphs Data Handling}. |
43 | */ |
44 | |
45 | /*! |
46 | * \enum QAbstract3DSeries::SeriesType |
47 | * |
48 | * Type of the series. |
49 | * |
50 | * \value SeriesTypeNone |
51 | * No series type. |
52 | * \value SeriesTypeBar |
53 | * Series type for Q3DBars. |
54 | * \value SeriesTypeScatter |
55 | * Series type for Q3DScatter. |
56 | * \value SeriesTypeSurface |
57 | * Series type for Q3DSurface. |
58 | */ |
59 | |
60 | /*! |
61 | * \enum QAbstract3DSeries::Mesh |
62 | * |
63 | * Predefined mesh types. All styles are not usable with all graphs types. |
64 | * |
65 | * \value MeshUserDefined |
66 | * User defined mesh, set via QAbstract3DSeries::userDefinedMesh property. |
67 | * \value MeshBar |
68 | * Basic rectangular bar. |
69 | * \value MeshCube |
70 | * Basic cube. |
71 | * \value MeshPyramid |
72 | * Four-sided pyramid. |
73 | * \value MeshCone |
74 | * Basic cone. |
75 | * \value MeshCylinder |
76 | * Basic cylinder. |
77 | * \value MeshBevelBar |
78 | * Slightly beveled (rounded) rectangular bar. |
79 | * \value MeshBevelCube |
80 | * Slightly beveled (rounded) cube. |
81 | * \value MeshSphere |
82 | * Sphere. |
83 | * \value MeshMinimal |
84 | * The minimal 3D mesh: a triangular pyramid. Usable only with Q3DScatter. |
85 | * \value MeshArrow |
86 | * Arrow pointing upwards. |
87 | * \value MeshPoint |
88 | * 2D point. Usable only with Q3DScatter. |
89 | * Shadows do not affect this style. Color style Q3DTheme::ColorStyleObjectGradient |
90 | * is not supported by this style. |
91 | */ |
92 | |
93 | /*! |
94 | * \qmlproperty Abstract3DSeries.SeriesType Abstract3DSeries::type |
95 | * The type of the series. One of the QAbstract3DSeries::SeriesType values. |
96 | * |
97 | */ |
98 | |
99 | /*! |
100 | * \qmlproperty string Abstract3DSeries::itemLabelFormat |
101 | * |
102 | * The label format for data items in this series. This format is used for single item labels, |
103 | * for example, when an item is selected. How the format is interpreted depends |
104 | * on series type: Bar3DSeries, Scatter3DSeries, Surface3DSeries. |
105 | */ |
106 | |
107 | /*! |
108 | * \qmlproperty bool Abstract3DSeries::visible |
109 | * Sets the visibility of the series. If \c false, the series is not rendered. |
110 | */ |
111 | |
112 | /*! |
113 | * \qmlproperty Abstract3DSeries.Mesh Abstract3DSeries::mesh |
114 | * |
115 | * Sets the mesh of the items in the series, or the selection pointer in case of |
116 | * Surface3DSeries. If the mesh is \l{QAbstract3DSeries::MeshUserDefined}{Abstract3DSeries.MeshUserDefined}, |
117 | * then the userDefinedMesh property must also be set for items to render properly. |
118 | * The default value depends on the graph type. |
119 | * |
120 | * \sa QAbstract3DSeries::Mesh |
121 | */ |
122 | |
123 | /*! |
124 | * \qmlproperty bool Abstract3DSeries::meshSmooth |
125 | * |
126 | * If \c true, smooth versions of predefined meshes set via the \l mesh property are used. |
127 | * This property does not affect custom meshes used when the mesh is set to |
128 | * \l{QAbstract3DSeries::MeshUserDefined}{Abstract3DSeries.MeshUserDefined}. |
129 | * Defaults to \c{false}. |
130 | */ |
131 | |
132 | /*! |
133 | * \qmlproperty quaternion Abstract3DSeries::meshRotation |
134 | * |
135 | * Sets the mesh rotation that is applied to all items of the series. |
136 | * The rotation should be a normalized quaternion. |
137 | * For those series types that support item specific rotation, the rotations are |
138 | * multiplied together. |
139 | * Bar3DSeries ignores any rotation that is not around the y-axis. |
140 | * Surface3DSeries applies the rotation only to the selection pointer. |
141 | * Defaults to no rotation. |
142 | */ |
143 | |
144 | /*! |
145 | * \qmlproperty string Abstract3DSeries::userDefinedMesh |
146 | * |
147 | * Sets the filename for a user defined custom mesh for objects that is used when \l mesh |
148 | * is \l{QAbstract3DSeries::MeshUserDefined}{Abstract3DSeries.MeshUserDefined}. |
149 | * \note The file needs to be in the Wavefront OBJ format and include |
150 | * vertices, normals, and UVs. It also needs to be in triangles. |
151 | */ |
152 | |
153 | /*! |
154 | * \qmlproperty Theme3D.ColorStyle Abstract3DSeries::colorStyle |
155 | * |
156 | * Sets the color style for the series. |
157 | * |
158 | * \sa {Theme3D::colorStyle}{Theme3D.colorStyle} |
159 | */ |
160 | |
161 | /*! |
162 | * \qmlproperty color Abstract3DSeries::baseColor |
163 | * |
164 | * Sets the base color of the series. |
165 | * |
166 | * \sa colorStyle, {Theme3D::baseColors}{Theme3D.baseColors} |
167 | */ |
168 | |
169 | /*! |
170 | * \qmlproperty ColorGradient Abstract3DSeries::baseGradient |
171 | * |
172 | * Sets the base gradient of the series. |
173 | * |
174 | * \sa colorStyle, {Theme3D::baseGradients}{Theme3D.baseGradients} |
175 | */ |
176 | |
177 | /*! |
178 | * \qmlproperty color Abstract3DSeries::singleHighlightColor |
179 | * |
180 | * Sets the single item highlight color of the series. |
181 | * |
182 | * \sa colorStyle, {Theme3D::singleHighlightColor}{Theme3D.singleHighlightColor} |
183 | */ |
184 | |
185 | /*! |
186 | * \qmlproperty ColorGradient Abstract3DSeries::singleHighlightGradient |
187 | * |
188 | * Sets the single item highlight gradient of the series. |
189 | * |
190 | * \sa colorStyle, {Theme3D::singleHighlightGradient}{Theme3D.singleHighlightGradient} |
191 | */ |
192 | |
193 | /*! |
194 | * \qmlproperty color Abstract3DSeries::multiHighlightColor |
195 | * |
196 | * Sets the multiple item highlight color of the series. |
197 | * |
198 | * \sa colorStyle, {Theme3D::multiHighlightColor}{Theme3D.multiHighlightColor} |
199 | */ |
200 | |
201 | /*! |
202 | * \qmlproperty ColorGradient Abstract3DSeries::multiHighlightGradient |
203 | * |
204 | * Sets the multiple item highlight gradient of the series. |
205 | * |
206 | * \sa colorStyle, {Theme3D::multiHighlightGradient}{Theme3D.multiHighlightGradient} |
207 | */ |
208 | |
209 | /*! |
210 | * \qmlproperty string Abstract3DSeries::name |
211 | * |
212 | * The series name. |
213 | * It can be used in item label format with the tag \c{@seriesName}. |
214 | * |
215 | * \sa itemLabelFormat |
216 | */ |
217 | |
218 | /*! |
219 | * \qmlproperty string Abstract3DSeries::itemLabel |
220 | * |
221 | * The formatted item label. If there is no selected item or the selected item is not |
222 | * visible, returns an empty string. |
223 | * |
224 | * \sa itemLabelFormat |
225 | */ |
226 | |
227 | /*! |
228 | * \qmlproperty bool Abstract3DSeries::itemLabelVisible |
229 | * |
230 | * If \c true, item labels are drawn as floating labels in the graph. Otherwise, |
231 | * item labels are not drawn. To show the item label in an external control, |
232 | * this property is set to \c false. Defaults to \c true. |
233 | * |
234 | * \sa itemLabelFormat, itemLabel |
235 | */ |
236 | |
237 | /*! |
238 | * \qmlmethod void Abstract3DSeries::setMeshAxisAndAngle(vector3d axis, real angle) |
239 | * |
240 | * A convenience function to construct a mesh rotation quaternion from \a axis |
241 | * and \a angle. |
242 | * |
243 | * \sa meshRotation |
244 | */ |
245 | |
246 | /*! |
247 | * \internal |
248 | */ |
249 | QAbstract3DSeries::QAbstract3DSeries(QAbstract3DSeriesPrivate *d, QObject *parent) : |
250 | QObject(parent), |
251 | d_ptr(d) |
252 | { |
253 | } |
254 | |
255 | /*! |
256 | * Deletes the abstract 3D series. |
257 | */ |
258 | QAbstract3DSeries::~QAbstract3DSeries() |
259 | { |
260 | } |
261 | |
262 | /*! |
263 | * \property QAbstract3DSeries::type |
264 | * |
265 | * \brief The type of the series. |
266 | */ |
267 | QAbstract3DSeries::SeriesType QAbstract3DSeries::type() const |
268 | { |
269 | const Q_D(QAbstract3DSeries); |
270 | return d->m_type; |
271 | } |
272 | |
273 | /*! |
274 | * \property QAbstract3DSeries::itemLabelFormat |
275 | * |
276 | * \brief The label format for data items in this series. |
277 | * |
278 | * This format is used for single item labels, |
279 | * for example, when an item is selected. How the format is interpreted depends |
280 | * on series type: QBar3DSeries, QScatter3DSeries, QSurface3DSeries. |
281 | */ |
282 | void QAbstract3DSeries::setItemLabelFormat(const QString &format) |
283 | { |
284 | Q_D(QAbstract3DSeries); |
285 | if (d->m_itemLabelFormat != format) { |
286 | d->setItemLabelFormat(format); |
287 | emit itemLabelFormatChanged(format); |
288 | } |
289 | } |
290 | |
291 | QString QAbstract3DSeries::itemLabelFormat() const |
292 | { |
293 | const Q_D(QAbstract3DSeries); |
294 | return d->m_itemLabelFormat; |
295 | } |
296 | |
297 | /*! |
298 | * \property QAbstract3DSeries::visible |
299 | * |
300 | * \brief The visibility of the series. |
301 | * |
302 | * If this property is \c false, the series is not rendered. |
303 | * Defaults to \c{true}. |
304 | */ |
305 | void QAbstract3DSeries::setVisible(bool visible) |
306 | { |
307 | Q_D(QAbstract3DSeries); |
308 | if (d->m_visible != visible) { |
309 | d->setVisible(visible); |
310 | emit visibilityChanged(visible); |
311 | } |
312 | } |
313 | |
314 | bool QAbstract3DSeries::isVisible() const |
315 | { |
316 | const Q_D(QAbstract3DSeries); |
317 | return d->m_visible; |
318 | } |
319 | |
320 | /*! |
321 | * \property QAbstract3DSeries::mesh |
322 | * |
323 | * \brief The mesh of the items in the series. |
324 | * |
325 | * For QSurface3DSeries, this property holds the selection pointer. |
326 | * |
327 | * If the mesh is MeshUserDefined, then the userDefinedMesh property |
328 | * must also be set for items to render properly. The default value depends on the graph type. |
329 | */ |
330 | void QAbstract3DSeries::setMesh(QAbstract3DSeries::Mesh mesh) |
331 | { |
332 | Q_D(QAbstract3DSeries); |
333 | if ((mesh == QAbstract3DSeries::MeshPoint || mesh == QAbstract3DSeries::MeshMinimal |
334 | || mesh == QAbstract3DSeries::MeshArrow) |
335 | && type() != QAbstract3DSeries::SeriesTypeScatter) { |
336 | qWarning() << "Specified style is only supported for QScatter3DSeries." ; |
337 | } else if (d->m_mesh != mesh) { |
338 | d->setMesh(mesh); |
339 | emit meshChanged(mesh); |
340 | } |
341 | } |
342 | |
343 | QAbstract3DSeries::Mesh QAbstract3DSeries::mesh() const |
344 | { |
345 | const Q_D(QAbstract3DSeries); |
346 | return d->m_mesh; |
347 | } |
348 | |
349 | /*! |
350 | * \property QAbstract3DSeries::meshSmooth |
351 | * |
352 | * \brief Whether smooth versions of predefined meshes are used. |
353 | * |
354 | * If \c true, smooth versions set via the \l mesh property are used. |
355 | * This property does not affect custom meshes used when the mesh is set to |
356 | * MeshUserDefined. Defaults to \c{false}. |
357 | */ |
358 | void QAbstract3DSeries::setMeshSmooth(bool enable) |
359 | { |
360 | Q_D(QAbstract3DSeries); |
361 | if (d->m_meshSmooth != enable) { |
362 | d->setMeshSmooth(enable); |
363 | emit meshSmoothChanged(enabled: enable); |
364 | } |
365 | } |
366 | |
367 | bool QAbstract3DSeries::isMeshSmooth() const |
368 | { |
369 | const Q_D(QAbstract3DSeries); |
370 | return d->m_meshSmooth; |
371 | } |
372 | |
373 | /*! |
374 | * \property QAbstract3DSeries::meshRotation |
375 | * |
376 | * \brief The mesh rotation that is applied to all items of the series. |
377 | * |
378 | * The rotation should be a normalized QQuaternion. |
379 | * For those series types that support item specific rotation, the rotations are |
380 | * multiplied together. |
381 | * QBar3DSeries ignores any rotation that is not around the y-axis. |
382 | * QSurface3DSeries applies the rotation only to the selection pointer. |
383 | * Defaults to no rotation. |
384 | */ |
385 | void QAbstract3DSeries::setMeshRotation(const QQuaternion &rotation) |
386 | { |
387 | Q_D(QAbstract3DSeries); |
388 | if (d->m_meshRotation != rotation) { |
389 | d->setMeshRotation(rotation); |
390 | emit meshRotationChanged(rotation); |
391 | } |
392 | } |
393 | |
394 | QQuaternion QAbstract3DSeries::meshRotation() const |
395 | { |
396 | const Q_D(QAbstract3DSeries); |
397 | return d->m_meshRotation; |
398 | } |
399 | |
400 | /*! |
401 | * A convenience function to construct a mesh rotation quaternion from |
402 | * \a axis and \a angle. |
403 | * |
404 | * \sa meshRotation |
405 | */ |
406 | void QAbstract3DSeries::setMeshAxisAndAngle(const QVector3D &axis, float angle) |
407 | { |
408 | setMeshRotation(QQuaternion::fromAxisAndAngle(axis, angle)); |
409 | } |
410 | |
411 | /*! |
412 | * \property QAbstract3DSeries::userDefinedMesh |
413 | * |
414 | * \brief The filename for a user defined custom mesh for objects. |
415 | * |
416 | * The custom mesh is used when \l mesh is MeshUserDefined. |
417 | * \note The file needs to be in the Wavefront OBJ format and include |
418 | * vertices, normals, and UVs. It also needs to be in triangles. |
419 | */ |
420 | void QAbstract3DSeries::setUserDefinedMesh(const QString &fileName) |
421 | { |
422 | Q_D(QAbstract3DSeries); |
423 | if (d->m_userDefinedMesh != fileName) { |
424 | d->setUserDefinedMesh(fileName); |
425 | emit userDefinedMeshChanged(fileName); |
426 | } |
427 | } |
428 | |
429 | QString QAbstract3DSeries::userDefinedMesh() const |
430 | { |
431 | const Q_D(QAbstract3DSeries); |
432 | return d->m_userDefinedMesh; |
433 | } |
434 | |
435 | /*! |
436 | * \property QAbstract3DSeries::colorStyle |
437 | * |
438 | * \brief The color style for the series. |
439 | * |
440 | * \sa Q3DTheme::ColorStyle |
441 | */ |
442 | void QAbstract3DSeries::setColorStyle(Q3DTheme::ColorStyle style) |
443 | { |
444 | Q_D(QAbstract3DSeries); |
445 | if (d->m_colorStyle != style) { |
446 | d->setColorStyle(style); |
447 | emit colorStyleChanged(style); |
448 | } |
449 | d->m_themeTracker.colorStyleOverride = true; |
450 | } |
451 | |
452 | Q3DTheme::ColorStyle QAbstract3DSeries::colorStyle() const |
453 | { |
454 | const Q_D(QAbstract3DSeries); |
455 | return d->m_colorStyle; |
456 | } |
457 | |
458 | /*! |
459 | * \property QAbstract3DSeries::baseColor |
460 | * |
461 | * \brief The base color of the series. |
462 | * |
463 | * \sa colorStyle, Q3DTheme::baseColors |
464 | */ |
465 | void QAbstract3DSeries::setBaseColor(const QColor &color) |
466 | { |
467 | Q_D(QAbstract3DSeries); |
468 | if (d->m_baseColor != color) { |
469 | d->setBaseColor(color); |
470 | emit baseColorChanged(color); |
471 | } |
472 | d->m_themeTracker.baseColorOverride = true; |
473 | } |
474 | |
475 | QColor QAbstract3DSeries::baseColor() const |
476 | { |
477 | const Q_D(QAbstract3DSeries); |
478 | return d->m_baseColor; |
479 | } |
480 | |
481 | /*! |
482 | * \property QAbstract3DSeries::baseGradient |
483 | * |
484 | * \brief The base gradient of the series. |
485 | * |
486 | * \sa colorStyle, Q3DTheme::baseGradients |
487 | */ |
488 | void QAbstract3DSeries::setBaseGradient(const QLinearGradient &gradient) |
489 | { |
490 | Q_D(QAbstract3DSeries); |
491 | if (d->m_baseGradient != gradient) { |
492 | d->setBaseGradient(gradient); |
493 | emit baseGradientChanged(gradient); |
494 | } |
495 | d->m_themeTracker.baseGradientOverride = true; |
496 | } |
497 | |
498 | QLinearGradient QAbstract3DSeries::baseGradient() const |
499 | { |
500 | const Q_D(QAbstract3DSeries); |
501 | return d->m_baseGradient; |
502 | } |
503 | |
504 | /*! |
505 | * \property QAbstract3DSeries::singleHighlightColor |
506 | * |
507 | * \brief The single item highlight color of the series. |
508 | * |
509 | * \sa colorStyle, Q3DTheme::singleHighlightColor |
510 | */ |
511 | void QAbstract3DSeries::setSingleHighlightColor(const QColor &color) |
512 | { |
513 | Q_D(QAbstract3DSeries); |
514 | if (d->m_singleHighlightColor != color) { |
515 | d->setSingleHighlightColor(color); |
516 | emit singleHighlightColorChanged(color); |
517 | } |
518 | d->m_themeTracker.singleHighlightColorOverride = true; |
519 | } |
520 | |
521 | QColor QAbstract3DSeries::singleHighlightColor() const |
522 | { |
523 | const Q_D(QAbstract3DSeries); |
524 | return d->m_singleHighlightColor; |
525 | } |
526 | |
527 | /*! |
528 | * \property QAbstract3DSeries::singleHighlightGradient |
529 | * |
530 | * \brief The single item highlight gradient of the series. |
531 | * |
532 | * \sa colorStyle, Q3DTheme::singleHighlightGradient |
533 | */ |
534 | void QAbstract3DSeries::setSingleHighlightGradient(const QLinearGradient &gradient) |
535 | { |
536 | Q_D(QAbstract3DSeries); |
537 | if (d->m_singleHighlightGradient != gradient) { |
538 | d->setSingleHighlightGradient(gradient); |
539 | emit singleHighlightGradientChanged(gradient); |
540 | } |
541 | d->m_themeTracker.singleHighlightGradientOverride = true; |
542 | } |
543 | |
544 | QLinearGradient QAbstract3DSeries::singleHighlightGradient() const |
545 | { |
546 | const Q_D(QAbstract3DSeries); |
547 | return d->m_singleHighlightGradient; |
548 | } |
549 | |
550 | /*! |
551 | * \property QAbstract3DSeries::multiHighlightColor |
552 | * |
553 | * \brief The multiple item highlight color of the series. |
554 | * |
555 | * \sa colorStyle, Q3DTheme::multiHighlightColor |
556 | */ |
557 | void QAbstract3DSeries::setMultiHighlightColor(const QColor &color) |
558 | { |
559 | Q_D(QAbstract3DSeries); |
560 | if (d->m_multiHighlightColor != color) { |
561 | d->setMultiHighlightColor(color); |
562 | emit multiHighlightColorChanged(color); |
563 | } |
564 | d->m_themeTracker.multiHighlightColorOverride = true; |
565 | } |
566 | |
567 | QColor QAbstract3DSeries::multiHighlightColor() const |
568 | { |
569 | const Q_D(QAbstract3DSeries); |
570 | return d->m_multiHighlightColor; |
571 | } |
572 | |
573 | /*! |
574 | * \property QAbstract3DSeries::multiHighlightGradient |
575 | * |
576 | * \brief The multiple item highlight gradient of the series. |
577 | * |
578 | * \sa colorStyle, Q3DTheme::multiHighlightGradient |
579 | */ |
580 | void QAbstract3DSeries::setMultiHighlightGradient(const QLinearGradient &gradient) |
581 | { |
582 | Q_D(QAbstract3DSeries); |
583 | if (d->m_multiHighlightGradient != gradient) { |
584 | d->setMultiHighlightGradient(gradient); |
585 | emit multiHighlightGradientChanged(gradient); |
586 | } |
587 | d->m_themeTracker.multiHighlightGradientOverride = true; |
588 | } |
589 | |
590 | QLinearGradient QAbstract3DSeries::multiHighlightGradient() const |
591 | { |
592 | const Q_D(QAbstract3DSeries); |
593 | return d->m_multiHighlightGradient; |
594 | } |
595 | |
596 | /*! |
597 | * \property QAbstract3DSeries::name |
598 | * |
599 | * \brief The series name. |
600 | * |
601 | * The series name can be used in item label format with the tag \c{@seriesName}. |
602 | * |
603 | * \sa itemLabelFormat |
604 | */ |
605 | void QAbstract3DSeries::setName(const QString &name) |
606 | { |
607 | Q_D(QAbstract3DSeries); |
608 | if (d->m_name != name) { |
609 | d->setName(name); |
610 | emit nameChanged(name); |
611 | } |
612 | } |
613 | |
614 | QString QAbstract3DSeries::name() const |
615 | { |
616 | const Q_D(QAbstract3DSeries); |
617 | return d->m_name; |
618 | } |
619 | |
620 | /*! |
621 | * \property QAbstract3DSeries::itemLabel |
622 | * |
623 | * \brief The formatted item label. |
624 | * |
625 | * If there is no selected item or the selected item is not |
626 | * visible, returns an empty string. |
627 | * |
628 | * \sa itemLabelFormat |
629 | */ |
630 | QString QAbstract3DSeries::itemLabel() |
631 | { |
632 | Q_D(QAbstract3DSeries); |
633 | return d->itemLabel(); |
634 | } |
635 | |
636 | /*! |
637 | * \property QAbstract3DSeries::itemLabelVisible |
638 | * |
639 | * \brief The visibility of item labels in the graph. |
640 | * |
641 | * If \c true, item labels are drawn as floating labels in the graph. Otherwise, |
642 | * item labels are not drawn. To show the item label in an external control, |
643 | * this property is set to \c false. Defaults to \c true. |
644 | * |
645 | * \sa itemLabelFormat, itemLabel |
646 | */ |
647 | void QAbstract3DSeries::setItemLabelVisible(bool visible) |
648 | { |
649 | Q_D(QAbstract3DSeries); |
650 | if (d->m_itemLabelVisible != visible) { |
651 | d->setItemLabelVisible(visible); |
652 | emit itemLabelVisibilityChanged(visible); |
653 | } |
654 | } |
655 | |
656 | bool QAbstract3DSeries::isItemLabelVisible() const |
657 | { |
658 | const Q_D(QAbstract3DSeries); |
659 | return d->m_itemLabelVisible; |
660 | } |
661 | |
662 | // QAbstract3DSeriesPrivate |
663 | |
664 | QAbstract3DSeriesPrivate::QAbstract3DSeriesPrivate(QAbstract3DSeries *q, |
665 | QAbstract3DSeries::SeriesType type) |
666 | : q_ptr(q), |
667 | m_type(type), |
668 | m_dataProxy(0), |
669 | m_visible(true), |
670 | m_controller(0), |
671 | m_mesh(QAbstract3DSeries::MeshCube), |
672 | m_meshSmooth(false), |
673 | m_colorStyle(Q3DTheme::ColorStyleUniform), |
674 | m_baseColor(Qt::black), |
675 | m_singleHighlightColor(Qt::black), |
676 | m_multiHighlightColor(Qt::black), |
677 | m_itemLabelDirty(true), |
678 | m_itemLabelVisible(true) |
679 | { |
680 | } |
681 | |
682 | QAbstract3DSeriesPrivate::~QAbstract3DSeriesPrivate() |
683 | { |
684 | } |
685 | |
686 | QAbstractDataProxy *QAbstract3DSeriesPrivate::dataProxy() const |
687 | { |
688 | return m_dataProxy; |
689 | } |
690 | |
691 | void QAbstract3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy) |
692 | { |
693 | Q_Q(QAbstract3DSeries); |
694 | Q_ASSERT(proxy && proxy != m_dataProxy && !proxy->d_func()->series()); |
695 | |
696 | delete m_dataProxy; |
697 | m_dataProxy = proxy; |
698 | |
699 | proxy->d_func()->setSeries(q); // also sets parent |
700 | |
701 | if (m_controller) { |
702 | connectControllerAndProxy(newController: m_controller); |
703 | m_controller->markDataDirty(); |
704 | } |
705 | } |
706 | |
707 | void QAbstract3DSeriesPrivate::setController(Abstract3DController *controller) |
708 | { |
709 | Q_Q(QAbstract3DSeries); |
710 | connectControllerAndProxy(newController: controller); |
711 | m_controller = controller; |
712 | q->setParent(controller); |
713 | markItemLabelDirty(); |
714 | } |
715 | |
716 | void QAbstract3DSeriesPrivate::setItemLabelFormat(const QString &format) |
717 | { |
718 | m_itemLabelFormat = format; |
719 | markItemLabelDirty(); |
720 | } |
721 | |
722 | void QAbstract3DSeriesPrivate::setVisible(bool visible) |
723 | { |
724 | m_visible = visible; |
725 | markItemLabelDirty(); |
726 | } |
727 | |
728 | void QAbstract3DSeriesPrivate::setMesh(QAbstract3DSeries::Mesh mesh) |
729 | { |
730 | m_mesh = mesh; |
731 | m_changeTracker.meshChanged = true; |
732 | if (m_controller) { |
733 | m_controller->markSeriesVisualsDirty(); |
734 | |
735 | if (m_controller->optimizationHints().testFlag(flag: QAbstract3DGraph::OptimizationDefault)) |
736 | m_controller->markDataDirty(); |
737 | } |
738 | } |
739 | |
740 | void QAbstract3DSeriesPrivate::setMeshSmooth(bool enable) |
741 | { |
742 | m_meshSmooth = enable; |
743 | m_changeTracker.meshSmoothChanged = true; |
744 | if (m_controller) { |
745 | m_controller->markSeriesVisualsDirty(); |
746 | |
747 | if (m_controller->optimizationHints().testFlag(flag: QAbstract3DGraph::OptimizationDefault)) |
748 | m_controller->markDataDirty(); |
749 | } |
750 | } |
751 | |
752 | void QAbstract3DSeriesPrivate::setMeshRotation(const QQuaternion &rotation) |
753 | { |
754 | m_meshRotation = rotation; |
755 | m_changeTracker.meshRotationChanged = true; |
756 | if (m_controller) { |
757 | m_controller->markSeriesVisualsDirty(); |
758 | |
759 | if (m_controller->optimizationHints().testFlag(flag: QAbstract3DGraph::OptimizationDefault)) |
760 | m_controller->markDataDirty(); |
761 | } |
762 | } |
763 | |
764 | void QAbstract3DSeriesPrivate::setUserDefinedMesh(const QString &meshFile) |
765 | { |
766 | m_userDefinedMesh = meshFile; |
767 | m_changeTracker.userDefinedMeshChanged = true; |
768 | if (m_controller) { |
769 | m_controller->markSeriesVisualsDirty(); |
770 | |
771 | if (m_controller->optimizationHints().testFlag(flag: QAbstract3DGraph::OptimizationDefault)) |
772 | m_controller->markDataDirty(); |
773 | } |
774 | } |
775 | |
776 | void QAbstract3DSeriesPrivate::setColorStyle(Q3DTheme::ColorStyle style) |
777 | { |
778 | m_colorStyle = style; |
779 | m_changeTracker.colorStyleChanged = true; |
780 | if (m_controller) |
781 | m_controller->markSeriesVisualsDirty(); |
782 | } |
783 | |
784 | void QAbstract3DSeriesPrivate::setBaseColor(const QColor &color) |
785 | { |
786 | m_baseColor = color; |
787 | m_changeTracker.baseColorChanged = true; |
788 | if (m_controller) |
789 | m_controller->markSeriesVisualsDirty(); |
790 | } |
791 | |
792 | void QAbstract3DSeriesPrivate::setBaseGradient(const QLinearGradient &gradient) |
793 | { |
794 | m_baseGradient = gradient; |
795 | Utils::verifyGradientCompleteness(gradient&: m_baseGradient); |
796 | m_changeTracker.baseGradientChanged = true; |
797 | if (m_controller) |
798 | m_controller->markSeriesVisualsDirty(); |
799 | } |
800 | |
801 | void QAbstract3DSeriesPrivate::setSingleHighlightColor(const QColor &color) |
802 | { |
803 | m_singleHighlightColor = color; |
804 | m_changeTracker.singleHighlightColorChanged = true; |
805 | if (m_controller) |
806 | m_controller->markSeriesVisualsDirty(); |
807 | } |
808 | |
809 | void QAbstract3DSeriesPrivate::setSingleHighlightGradient(const QLinearGradient &gradient) |
810 | { |
811 | m_singleHighlightGradient = gradient; |
812 | Utils::verifyGradientCompleteness(gradient&: m_singleHighlightGradient); |
813 | m_changeTracker.singleHighlightGradientChanged = true; |
814 | if (m_controller) |
815 | m_controller->markSeriesVisualsDirty(); |
816 | } |
817 | |
818 | void QAbstract3DSeriesPrivate::setMultiHighlightColor(const QColor &color) |
819 | { |
820 | m_multiHighlightColor = color; |
821 | m_changeTracker.multiHighlightColorChanged = true; |
822 | if (m_controller) |
823 | m_controller->markSeriesVisualsDirty(); |
824 | } |
825 | |
826 | void QAbstract3DSeriesPrivate::setMultiHighlightGradient(const QLinearGradient &gradient) |
827 | { |
828 | m_multiHighlightGradient = gradient; |
829 | Utils::verifyGradientCompleteness(gradient&: m_multiHighlightGradient); |
830 | m_changeTracker.multiHighlightGradientChanged = true; |
831 | if (m_controller) |
832 | m_controller->markSeriesVisualsDirty(); |
833 | } |
834 | |
835 | void QAbstract3DSeriesPrivate::setName(const QString &name) |
836 | { |
837 | m_name = name; |
838 | markItemLabelDirty(); |
839 | m_changeTracker.nameChanged = true; |
840 | } |
841 | |
842 | void QAbstract3DSeriesPrivate::resetToTheme(const Q3DTheme &theme, int seriesIndex, bool force) |
843 | { |
844 | Q_Q(QAbstract3DSeries); |
845 | int themeIndex = seriesIndex; |
846 | if (force || !m_themeTracker.colorStyleOverride) { |
847 | q->setColorStyle(theme.colorStyle()); |
848 | m_themeTracker.colorStyleOverride = false; |
849 | } |
850 | if (force || !m_themeTracker.baseColorOverride) { |
851 | if (theme.baseColors().size() <= seriesIndex) |
852 | themeIndex = seriesIndex % theme.baseColors().size(); |
853 | q->setBaseColor(theme.baseColors().at(i: themeIndex)); |
854 | m_themeTracker.baseColorOverride = false; |
855 | } |
856 | if (force || !m_themeTracker.baseGradientOverride) { |
857 | if (theme.baseGradients().size() <= seriesIndex) |
858 | themeIndex = seriesIndex % theme.baseGradients().size(); |
859 | q->setBaseGradient(theme.baseGradients().at(i: themeIndex)); |
860 | m_themeTracker.baseGradientOverride = false; |
861 | } |
862 | if (force || !m_themeTracker.singleHighlightColorOverride) { |
863 | q->setSingleHighlightColor(theme.singleHighlightColor()); |
864 | m_themeTracker.singleHighlightColorOverride = false; |
865 | } |
866 | if (force || !m_themeTracker.singleHighlightGradientOverride) { |
867 | q->setSingleHighlightGradient(theme.singleHighlightGradient()); |
868 | m_themeTracker.singleHighlightGradientOverride = false; |
869 | } |
870 | if (force || !m_themeTracker.multiHighlightColorOverride) { |
871 | q->setMultiHighlightColor(theme.multiHighlightColor()); |
872 | m_themeTracker.multiHighlightColorOverride = false; |
873 | } |
874 | if (force || !m_themeTracker.multiHighlightGradientOverride) { |
875 | q->setMultiHighlightGradient(theme.multiHighlightGradient()); |
876 | m_themeTracker.multiHighlightGradientOverride = false; |
877 | } |
878 | } |
879 | |
880 | QString QAbstract3DSeriesPrivate::itemLabel() |
881 | { |
882 | Q_Q(QAbstract3DSeries); |
883 | if (m_itemLabelDirty) { |
884 | QString oldLabel = m_itemLabel; |
885 | if (m_controller && m_visible) |
886 | createItemLabel(); |
887 | else |
888 | m_itemLabel = QString(); |
889 | m_itemLabelDirty = false; |
890 | |
891 | if (oldLabel != m_itemLabel) |
892 | emit q->itemLabelChanged(label: m_itemLabel); |
893 | } |
894 | |
895 | return m_itemLabel; |
896 | } |
897 | |
898 | void QAbstract3DSeriesPrivate::markItemLabelDirty() |
899 | { |
900 | m_itemLabelDirty = true; |
901 | m_changeTracker.itemLabelChanged = true; |
902 | } |
903 | |
904 | void QAbstract3DSeriesPrivate::setItemLabelVisible(bool visible) |
905 | { |
906 | m_itemLabelVisible = visible; |
907 | markItemLabelDirty(); |
908 | m_changeTracker.itemLabelVisibilityChanged = true; |
909 | } |
910 | |
911 | bool QAbstract3DSeriesPrivate::isUsingGradient() |
912 | { |
913 | return m_colorStyle != Q3DTheme::ColorStyleUniform ? true : false; |
914 | } |
915 | |
916 | QT_END_NAMESPACE |
917 | |