1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 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 "q3dtheme_p.h"
31 #include "thememanager_p.h"
32 
33 QT_BEGIN_NAMESPACE_DATAVISUALIZATION
34 
35 /*!
36  * \class Q3DTheme
37  * \inmodule QtDataVisualization
38  * \brief Q3DTheme class provides a visual style for graphs.
39  * \since QtDataVisualization 1.0
40  *
41  * Specifies visual properties that affect the whole graph. There are several
42  * built-in themes that can be used as is or modified freely.
43  *
44  * The following properties can be overridden by using QAbstract3DSeries
45  * properties to set them explicitly in the series: baseColors, baseGradients,
46  * and colorStyle.
47  *
48  * Themes can be created from scratch using the ThemeUserDefined enum value.
49  * Creating a theme using the default constructor produces a new user-defined
50  * theme.
51  *
52  * \section1 Default Theme
53  *
54  * The following table lists the properties controlled by themes and the
55  * default values for ThemeUserDefined.
56  *
57  * \table
58  *   \header
59  *     \li Property
60  *     \li Default Value
61  *   \row
62  *     \li ambientLightStrength
63  *     \li 0.25
64  *   \row
65  *     \li backgroundColor
66  *     \li Qt::black
67  *   \row
68  *     \li backgroundEnabled
69  *     \li \c true
70  *   \row
71  *     \li baseColors
72  *     \li Qt::black
73  *   \row
74  *     \li baseGradients
75  *     \li QLinearGradient. Essentially fully black.
76  *   \row
77  *     \li colorStyle
78  *     \li ColorStyleUniform
79  *   \row
80  *     \li \l font
81  *     \li QFont
82  *   \row
83  *     \li gridEnabled
84  *     \li \c true
85  *   \row
86  *     \li gridLineColor
87  *     \li Qt::white
88  *   \row
89  *     \li highlightLightStrength
90  *     \li 7.5
91  *   \row
92  *     \li labelBackgroundColor
93  *     \li Qt::gray
94  *   \row
95  *     \li labelBackgroundEnabled
96  *     \li \c true
97  *   \row
98  *     \li labelBorderEnabled
99  *     \li \c true
100  *   \row
101  *     \li labelTextColor
102  *     \li Qt::white
103  *   \row
104  *     \li lightColor
105  *     \li Qt::white
106  *   \row
107  *     \li lightStrength
108  *     \li 5.0
109  *   \row
110  *     \li multiHighlightColor
111  *     \li Qt::blue
112  *   \row
113  *     \li multiHighlightGradient
114  *     \li QLinearGradient. Essentially fully black.
115  *   \row
116  *     \li singleHighlightColor
117  *     \li Qt::red
118  *   \row
119  *     \li singleHighlightGradient
120  *     \li QLinearGradient. Essentially fully black.
121  *   \row
122  *     \li windowColor
123  *     \li Qt::black
124  * \endtable
125  *
126  * \section1 Usage Examples
127  *
128  * Creating a built-in theme without any modifications:
129  *
130  * \snippet doc_src_q3dtheme.cpp 0
131  *
132  * Creating a built-in theme and modifying some properties:
133  *
134  * \snippet doc_src_q3dtheme.cpp 1
135  *
136  * Creating a user-defined theme:
137  *
138  * \snippet doc_src_q3dtheme.cpp 2
139  *
140  * Creating a built-in theme and modifying some properties after it has been set:
141  *
142  * \snippet doc_src_q3dtheme.cpp 3
143  *
144  */
145 
146 /*!
147  * \enum Q3DTheme::ColorStyle
148  *
149  * Color styles.
150  *
151  * \value ColorStyleUniform
152  *        Objects are rendered in a single color. The color used is specified in baseColors,
153  *        singleHighlightColor and multiHighlightColor properties.
154  * \value ColorStyleObjectGradient
155  *        Objects are colored using a full gradient for each object regardless of object height. The
156  *        gradient used is specified in baseGradients, singleHighlightGradient and
157  *        multiHighlightGradient properties.
158  * \value ColorStyleRangeGradient
159  *        Objects are colored using a portion of the full gradient determined by the object's
160  *        height and its position on the Y-axis. The gradient used is specified in baseGradients,
161  *        singleHighlightGradient and multiHighlightGradient properties.
162  */
163 
164 /*!
165  * \enum Q3DTheme::Theme
166  *
167  * Built-in themes.
168  *
169  * \value ThemeQt
170  *        A light theme with green as the base color.
171  * \value ThemePrimaryColors
172  *        A light theme with yellow as the base color.
173  * \value ThemeDigia
174  *        A light theme with gray as the base color.
175  * \value ThemeStoneMoss
176  *        A medium dark theme with yellow as the base color.
177  * \value ThemeArmyBlue
178  *        A medium light theme with blue as the base color.
179  * \value ThemeRetro
180  *        A medium light theme with brown as the base color.
181  * \value ThemeEbony
182  *        A dark theme with white as the base color.
183  * \value ThemeIsabelle
184  *        A dark theme with yellow as the base color.
185  * \value ThemeUserDefined
186  *        A user-defined theme. For more information, see \l {Default Theme}.
187  */
188 
189 /*!
190  * \qmltype Theme3D
191  * \inqmlmodule QtDataVisualization
192  * \since QtDataVisualization 1.0
193  * \ingroup datavisualization_qml
194  * \instantiates Q3DTheme
195  * \brief A visual style for graphs.
196  *
197  * This type is used to specify visual properties that affect the whole graph. There are several
198  * built-in themes that can be used as is or modified freely.
199  *
200  * The following properties can be overridden by using Abstract3DSeries
201  * properties to set them explicitly in the series:
202  * baseColors, baseGradients, and colorStyle.
203  *
204  * Themes can be created from scratch by using the
205  * \l{Q3DTheme::ThemeUserDefined}{Theme3D.ThemeUserDefined} enum value.
206  *
207  * \section1 Default Theme
208  *
209  * The following table lists the properties controlled by themes and the
210  * default values for \l{Q3DTheme::ThemeUserDefined}
211  * {Theme3D.ThemeUserDefined}.
212  *
213  * \table
214  *   \header
215  *     \li Property
216  *     \li Default Value
217  *   \row
218  *     \li ambientLightStrength
219  *     \li 0.25
220  *   \row
221  *     \li backgroundColor
222  *     \li "black". For more information, see \l [QtQuick] color.
223  *   \row
224  *     \li backgroundEnabled
225  *     \li \c true
226  *   \row
227  *     \li baseColors
228  *     \li "black"
229  *   \row
230  *     \li baseGradients
231  *     \li QLinearGradient. Essentially fully black.
232  *   \row
233  *     \li colorStyle
234  *     \li ColorStyleUniform
235  *   \row
236  *     \li \l font
237  *     \li \l [QtQuick] font
238  *   \row
239  *     \li gridEnabled
240  *     \li \c true
241  *   \row
242  *     \li gridLineColor
243  *     \li "white"
244  *   \row
245  *     \li highlightLightStrength
246  *     \li 7.5
247  *   \row
248  *     \li labelBackgroundColor
249  *     \li "gray"
250  *   \row
251  *     \li labelBackgroundEnabled
252  *     \li \c true
253  *   \row
254  *     \li labelBorderEnabled
255  *     \li \c true
256  *   \row
257  *     \li labelTextColor
258  *     \li "white"
259  *   \row
260  *     \li lightColor
261  *     \li "white"
262  *   \row
263  *     \li lightStrength
264  *     \li 5.0
265  *   \row
266  *     \li multiHighlightColor
267  *     \li "blue"
268  *   \row
269  *     \li multiHighlightGradient
270  *     \li QLinearGradient. Essentially fully black.
271  *   \row
272  *     \li singleHighlightColor
273  *     \li "red"
274  *   \row
275  *     \li singleHighlightGradient
276  *     \li QLinearGradient. Essentially fully black.
277  *   \row
278  *     \li windowColor
279  *     \li "black"
280  * \endtable
281  *
282  * \section1 Usage examples
283  *
284  * Using a built-in theme without any modifications:
285  *
286  * \snippet doc_src_q3dtheme.cpp 4
287  *
288  * Using a built-in theme and modifying some properties:
289  *
290  * \snippet doc_src_q3dtheme.cpp 5
291  *
292  * Using a user-defined theme:
293  *
294  * \snippet doc_src_q3dtheme.cpp 6
295  *
296  * For Theme3D enums, see \l Q3DTheme::ColorStyle and \l{Q3DTheme::Theme}.
297  */
298 
299 /*!
300  * \qmlproperty list<ThemeColor> Theme3D::baseColors
301  *
302  * The list of base colors to be used for all the objects in the graph, series by series. If there
303  * are more series than colors, color list wraps and starts again with the first color in the list.
304  * Has no immediate effect if colorStyle is not \c Theme3D.ColorStyleUniform.
305  *
306  * This can be overridden by setting \l{Abstract3DSeries::baseColor}
307  * {Abstract3DSeries.baseColor} explicitly in the series.
308  */
309 
310 /*!
311  * \qmlproperty color Theme3D::backgroundColor
312  *
313  * The color of the graph background.
314  */
315 
316 /*!
317  * \qmlproperty color Theme3D::windowColor
318  *
319  * The color of the application window the graph is drawn into.
320  */
321 
322 /*!
323  * \qmlproperty color Theme3D::labelTextColor
324  *
325  * The color of the font used for labels.
326  */
327 
328 /*!
329  * \qmlproperty color Theme3D::labelBackgroundColor
330  *
331  * The color of the label backgrounds. Has no effect if labelBackgroundEnabled is \c false.
332  */
333 
334 /*!
335  * \qmlproperty color Theme3D::gridLineColor
336  *
337  * The color of the grid lines.
338  */
339 
340 /*!
341  * \qmlproperty color Theme3D::singleHighlightColor
342  *
343  * The highlight color for a selected object. Used if
344  * \l{AbstractGraph3D::selectionMode}{selectionMode}
345  * has the \c AbstractGraph3D.SelectionItem flag set.
346  */
347 
348 /*!
349  * \qmlproperty color Theme3D::multiHighlightColor
350  *
351  * The highlight color for selected objects. Used if
352  * \l{AbstractGraph3D::selectionMode}{selectionMode}
353  * has the \c AbstractGraph3D.SelectionRow or \c AbstractGraph3D.SelectionColumn
354  * flag set.
355  */
356 
357 /*!
358  * \qmlproperty color Theme3D::lightColor
359  *
360  * The color of the ambient and specular light defined in Scene3D.
361  */
362 
363 /*!
364  * \qmlproperty list<ColorGradient> Theme3D::baseGradients
365  *
366  * The list of base gradients to be used for all the objects in the graph,
367  * series by series. If there are more series than gradients, the gradient list
368  * wraps and starts again with the first gradient in the list.
369  *
370  * Has no immediate effect if colorStyle is \l{Q3DTheme::ColorStyleUniform}
371  * {Theme3D.ColorStyleUniform}.
372  *
373  * This value can be overridden by setting \l{Abstract3DSeries::baseGradient}
374  *{Abstract3DSeries.baseGradient} explicitly in the series.
375  */
376 
377 /*!
378  * \qmlproperty ColorGradient Theme3D::singleHighlightGradient
379  *
380  * The highlight gradient for a selected object. Used if
381  * \l{AbstractGraph3D::selectionMode}{selectionMode}
382  * has the \c AbstractGraph3D.SelectionItem flag set.
383  */
384 
385 /*!
386  * \qmlproperty ColorGradient Theme3D::multiHighlightGradient
387  *
388  * The highlight gradient for selected objects. Used if
389  * \l{AbstractGraph3D::selectionMode}{selectionMode}
390  * has the \c AbstractGraph3D.SelectionRow or \c AbstractGraph3D.SelectionColumn
391  * flag set.
392  */
393 
394 /*!
395  * \qmlproperty real Theme3D::lightStrength
396  *
397  * The specular light strength for the whole graph. The value must be between
398  * \c 0.0 and \c 10.0.
399  *
400  * This value affects the light specified in Scene3D.
401  */
402 
403 /*!
404  * \qmlproperty real Theme3D::ambientLightStrength
405  *
406  * The ambient light strength for the whole graph. This value determines how
407  * evenly and brightly the colors are shown throughout the graph regardless of
408  * the light position. The value must be between \c 0.0 and \c 1.0.
409  */
410 
411 /*!
412  * \qmlproperty real Theme3D::highlightLightStrength
413  *
414  * The specular light strength for selected objects. The value must be
415  * between \c 0.0 and \c 10.0.
416  */
417 
418 /*!
419  * \qmlproperty bool Theme3D::labelBorderEnabled
420  *
421  * Defines whether label borders are drawn for labels that have a background.
422  * Has no effect if labelBackgroundEnabled is \c false.
423  */
424 
425 /*!
426  * \qmlproperty font Theme3D::font
427  *
428  * Sets the font to be used for labels.
429  */
430 
431 /*!
432  * \qmlproperty bool Theme3D::backgroundEnabled
433  *
434  * Defines whether the background is drawn by using the value of
435  * backgroundColor.
436  */
437 
438 /*!
439  * \qmlproperty bool Theme3D::gridEnabled
440  *
441  * Defines whether the grid lines are drawn. This value affects all grid lines.
442  */
443 
444 /*!
445  * \qmlproperty bool Theme3D::labelBackgroundEnabled
446  *
447  * Defines whether the label is drawn with a background that uses
448  * labelBackgroundColor (including alpha), or with a fully transparent
449  * background. Labels with a background are drawn to equal sizes per axis based
450  * on the longest label, and the text is centered in them. Labels without
451  * a background are drawn as is and are left or right aligned based on their
452  * position in the graph.
453  */
454 
455 /*!
456  * \qmlproperty Theme3D.ColorStyle Theme3D::colorStyle
457  *
458  * The style of the graph colors. One of Q3DTheme::ColorStyle enum values.
459  *
460  * This value can be overridden by setting \l{Abstract3DSeries::colorStyle}
461  * {Abstract3DSeries.colorStyle} explicitly in the series.
462  *
463  * \sa Q3DTheme::ColorStyle
464  */
465 
466 /*!
467  * \qmlproperty Theme3D.Theme Theme3D::type
468  *
469  * The type of the theme. If no type is set, the type is
470  * \l{Q3DTheme::ThemeUserDefined}{Theme3D.ThemeUserDefined}.
471  * Changing the theme type after the item has been constructed will change all other properties
472  * of the theme to what the predefined theme specifies. Changing the theme type of the active theme
473  * of the graph will also reset all attached series to use the new theme.
474  */
475 
476 /*!
477  * Constructs a new theme of type ThemeUserDefined. An optional \a parent parameter
478  * can be given and is then passed to QObject constructor.
479  */
Q3DTheme(QObject * parent)480 Q3DTheme::Q3DTheme(QObject *parent)
481     : QObject(parent),
482       d_ptr(new Q3DThemePrivate(this))
483 {
484 }
485 
486 /*!
487  * Constructs a new theme with \a themeType, which can be one of the built-in themes from
488  * \l Theme. An optional \a parent parameter can be given and is then passed to QObject
489  * constructor.
490  */
Q3DTheme(Theme themeType,QObject * parent)491 Q3DTheme::Q3DTheme(Theme themeType, QObject *parent)
492     : QObject(parent),
493       d_ptr(new Q3DThemePrivate(this))
494 {
495     setType(themeType);
496 }
497 
498 /*!
499  * \internal
500  */
Q3DTheme(Q3DThemePrivate * d,Theme themeType,QObject * parent)501 Q3DTheme::Q3DTheme(Q3DThemePrivate *d, Theme themeType,
502                    QObject *parent) :
503     QObject(parent),
504     d_ptr(d)
505 {
506     setType(themeType);
507 }
508 
509 /*!
510  * Destroys the theme.
511  */
~Q3DTheme()512 Q3DTheme::~Q3DTheme()
513 {
514 }
515 
516 /*!
517  * \property Q3DTheme::baseColors
518  *
519  * \brief The list of base colors to be used for all the objects in the graph,
520  * series by series.
521  *
522  * If there are more series than colors, the color list wraps and starts again
523  * with the first color in the list.
524  *
525  * Has no immediate effect if colorStyle is not ColorStyleUniform.
526  *
527  * This value can be overridden by setting the \l{QAbstract3DSeries::baseColor}
528  * {baseColor} explicitly in the series.
529  */
setBaseColors(const QList<QColor> & colors)530 void Q3DTheme::setBaseColors(const QList<QColor> &colors)
531 {
532     if (colors.size()) {
533         d_ptr->m_dirtyBits.baseColorDirty = true;
534         if (d_ptr->m_baseColors != colors) {
535             d_ptr->m_baseColors.clear();
536             d_ptr->m_baseColors = colors;
537             emit baseColorsChanged(colors);
538         }
539     } else {
540         d_ptr->m_baseColors.clear();
541     }
542 }
543 
baseColors() const544 QList<QColor> Q3DTheme::baseColors() const
545 {
546     return d_ptr->m_baseColors;
547 }
548 
549 /*!
550  * \property Q3DTheme::backgroundColor
551  *
552  * \brief The color of the graph background.
553  */
setBackgroundColor(const QColor & color)554 void Q3DTheme::setBackgroundColor(const QColor &color)
555 {
556     d_ptr->m_dirtyBits.backgroundColorDirty = true;
557     if (d_ptr->m_backgroundColor != color) {
558         d_ptr->m_backgroundColor = color;
559         emit backgroundColorChanged(color);
560         emit d_ptr->needRender();
561     }
562 }
563 
backgroundColor() const564 QColor Q3DTheme::backgroundColor() const
565 {
566     return d_ptr->m_backgroundColor;
567 }
568 
569 /*!
570  * \property Q3DTheme::windowColor
571  *
572  * \brief The color of the application window the graph is drawn into.
573  */
setWindowColor(const QColor & color)574 void Q3DTheme::setWindowColor(const QColor &color)
575 {
576     d_ptr->m_dirtyBits.windowColorDirty = true;
577     if (d_ptr->m_windowColor != color) {
578         d_ptr->m_windowColor = color;
579         emit windowColorChanged(color);
580         emit d_ptr->needRender();
581     }
582 }
583 
windowColor() const584 QColor Q3DTheme::windowColor() const
585 {
586     return d_ptr->m_windowColor;
587 }
588 
589 /*!
590  * \property Q3DTheme::labelTextColor
591  *
592  * \brief The color of the font used for labels.
593  */
setLabelTextColor(const QColor & color)594 void Q3DTheme::setLabelTextColor(const QColor &color)
595 {
596     d_ptr->m_dirtyBits.labelTextColorDirty = true;
597     if (d_ptr->m_textColor != color) {
598         d_ptr->m_textColor = color;
599         emit labelTextColorChanged(color);
600         emit d_ptr->needRender();
601     }
602 }
603 
labelTextColor() const604 QColor Q3DTheme::labelTextColor() const
605 {
606     return d_ptr->m_textColor;
607 }
608 
609 /*!
610  * \property Q3DTheme::labelBackgroundColor
611  *
612  * \brief The color of the label backgrounds.
613  *
614  * Has no effect if labelBackgroundEnabled is \c false.
615  */
setLabelBackgroundColor(const QColor & color)616 void Q3DTheme::setLabelBackgroundColor(const QColor &color)
617 {
618     d_ptr->m_dirtyBits.labelBackgroundColorDirty = true;
619     if (d_ptr->m_textBackgroundColor != color) {
620         d_ptr->m_textBackgroundColor = color;
621         emit labelBackgroundColorChanged(color);
622         emit d_ptr->needRender();
623     }
624 }
625 
labelBackgroundColor() const626 QColor Q3DTheme::labelBackgroundColor() const
627 {
628     return d_ptr->m_textBackgroundColor;
629 }
630 
631 /*!
632  * \property Q3DTheme::gridLineColor
633  *
634  * \brief The color of the grid lines.
635  */
setGridLineColor(const QColor & color)636 void Q3DTheme::setGridLineColor(const QColor &color)
637 {
638     d_ptr->m_dirtyBits.gridLineColorDirty = true;
639     if (d_ptr->m_gridLineColor != color) {
640         d_ptr->m_gridLineColor = color;
641         emit gridLineColorChanged(color);
642         emit d_ptr->needRender();
643     }
644 }
645 
gridLineColor() const646 QColor Q3DTheme::gridLineColor() const
647 {
648     return d_ptr->m_gridLineColor;
649 }
650 
651 /*!
652  * \property Q3DTheme::singleHighlightColor
653  *
654  * \brief The highlight color for a selected object.
655  *
656  * Used if \l{QAbstract3DGraph::selectionMode}{selectionMode} has the
657  * \c QAbstract3DGraph::SelectionItem flag set.
658  */
setSingleHighlightColor(const QColor & color)659 void Q3DTheme::setSingleHighlightColor(const QColor &color)
660 {
661     d_ptr->m_dirtyBits.singleHighlightColorDirty = true;
662     if (d_ptr->m_singleHighlightColor != color) {
663         d_ptr->m_singleHighlightColor = color;
664         emit singleHighlightColorChanged(color);
665     }
666 }
667 
singleHighlightColor() const668 QColor Q3DTheme::singleHighlightColor() const
669 {
670     return d_ptr->m_singleHighlightColor;
671 }
672 
673 /*!
674  * \property Q3DTheme::multiHighlightColor
675  *
676  * \brief The highlight color for selected objects.
677  *
678  * Used if \l{QAbstract3DGraph::selectionMode}{selectionMode} has the
679  * \c QAbstract3DGraph::SelectionRow or \c QAbstract3DGraph::SelectionColumn
680  * flag set.
681  */
setMultiHighlightColor(const QColor & color)682 void Q3DTheme::setMultiHighlightColor(const QColor &color)
683 {
684     d_ptr->m_dirtyBits.multiHighlightColorDirty = true;
685     if (d_ptr->m_multiHighlightColor != color) {
686         d_ptr->m_multiHighlightColor = color;
687         emit multiHighlightColorChanged(color);
688     }
689 }
690 
multiHighlightColor() const691 QColor Q3DTheme::multiHighlightColor() const
692 {
693     return d_ptr->m_multiHighlightColor;
694 }
695 
696 /*!
697  * \property Q3DTheme::lightColor
698  *
699  * \brief The color for the ambient and specular light.
700  *
701  * This value affects the light specified in Q3DScene.
702  */
setLightColor(const QColor & color)703 void Q3DTheme::setLightColor(const QColor &color)
704 {
705     d_ptr->m_dirtyBits.lightColorDirty = true;
706     if (d_ptr->m_lightColor != color) {
707         d_ptr->m_lightColor = color;
708         emit lightColorChanged(color);
709         emit d_ptr->needRender();
710     }
711 }
712 
lightColor() const713 QColor Q3DTheme::lightColor() const
714 {
715     return d_ptr->m_lightColor;
716 }
717 
718 /*!
719  * \property Q3DTheme::baseGradients
720  *
721  * \brief The list of base gradients to be used for all the objects in the
722  * graph, series by series.
723  *
724  * If there are more series than gradients, the gradient list wraps and starts
725  * again with the first gradient in the list
726  *
727  * Has no immediate effect if colorStyle is ColorStyleUniform.
728  *
729  * This value can be overridden by setting the
730  * \l{QAbstract3DSeries::baseGradient}{baseGradient} explicitly in the series.
731  */
setBaseGradients(const QList<QLinearGradient> & gradients)732 void Q3DTheme::setBaseGradients(const QList<QLinearGradient> &gradients)
733 {
734     if (gradients.size()) {
735         d_ptr->m_dirtyBits.baseGradientDirty = true;
736         if (d_ptr->m_baseGradients != gradients) {
737             d_ptr->m_baseGradients.clear();
738             d_ptr->m_baseGradients = gradients;
739             emit baseGradientsChanged(gradients);
740         }
741     } else {
742         d_ptr->m_baseGradients.clear();
743     }
744 }
745 
baseGradients() const746 QList<QLinearGradient> Q3DTheme::baseGradients() const
747 {
748     return d_ptr->m_baseGradients;
749 }
750 
751 /*!
752  * \property Q3DTheme::singleHighlightGradient
753  *
754  * \brief The highlight gradient for a selected object.
755  *
756  * Used if \l{QAbstract3DGraph::selectionMode}{selectionMode}
757  * has the \c QAbstract3DGraph::SelectionItem flag set.
758  */
setSingleHighlightGradient(const QLinearGradient & gradient)759 void Q3DTheme::setSingleHighlightGradient(const QLinearGradient &gradient)
760 {
761     d_ptr->m_dirtyBits.singleHighlightGradientDirty = true;
762     if (d_ptr->m_singleHighlightGradient != gradient) {
763         d_ptr->m_singleHighlightGradient = gradient;
764         emit singleHighlightGradientChanged(gradient);
765     }
766 }
767 
singleHighlightGradient() const768 QLinearGradient Q3DTheme::singleHighlightGradient() const
769 {
770     return d_ptr->m_singleHighlightGradient;
771 }
772 
773 /*!
774  * \property Q3DTheme::multiHighlightGradient
775  *
776  * \brief The highlight gradient for selected objects.
777  *
778  * Used if \l{QAbstract3DGraph::selectionMode}{selectionMode}
779  * has the \c QAbstract3DGraph::SelectionRow or
780  * \c QAbstract3DGraph::SelectionColumn flag set.
781  */
setMultiHighlightGradient(const QLinearGradient & gradient)782 void Q3DTheme::setMultiHighlightGradient(const QLinearGradient &gradient)
783 {
784     d_ptr->m_dirtyBits.multiHighlightGradientDirty = true;
785     if (d_ptr->m_multiHighlightGradient != gradient) {
786         d_ptr->m_multiHighlightGradient = gradient;
787         emit multiHighlightGradientChanged(gradient);
788     }
789 }
790 
multiHighlightGradient() const791 QLinearGradient Q3DTheme::multiHighlightGradient() const
792 {
793     return d_ptr->m_multiHighlightGradient;
794 }
795 
796 /*!
797  * \property Q3DTheme::lightStrength
798  *
799  * \brief The specular light strength for the whole graph.
800  *
801  * The value must be between \c 0.0f and \c 10.0f.
802  *
803  * This value affects the light specified in Q3DScene.
804  */
setLightStrength(float strength)805 void Q3DTheme::setLightStrength(float strength)
806 {
807     d_ptr->m_dirtyBits.lightStrengthDirty = true;
808     if (strength < 0.0f || strength > 10.0f) {
809         qWarning("Invalid value. Valid range for lightStrength is between 0.0f and 10.0f");
810     } else if (d_ptr->m_lightStrength != strength) {
811         d_ptr->m_lightStrength = strength;
812         emit lightStrengthChanged(strength);
813         emit d_ptr->needRender();
814     }
815 }
816 
lightStrength() const817 float Q3DTheme::lightStrength() const
818 {
819     return d_ptr->m_lightStrength;
820 }
821 
822 /*!
823  * \property Q3DTheme::ambientLightStrength
824  *
825  * \brief The ambient light strength for the whole graph.
826  *
827  * This value determines how evenly and brightly the colors are shown throughout
828  * the graph regardless of the light position.
829  *
830  * The value must be between \c 0.0f and \c 1.0f.
831  */
setAmbientLightStrength(float strength)832 void Q3DTheme::setAmbientLightStrength(float strength)
833 {
834     d_ptr->m_dirtyBits.ambientLightStrengthDirty = true;
835     if (strength < 0.0f || strength > 1.0f) {
836         qWarning("Invalid value. Valid range for ambientLightStrength is between 0.0f and 1.0f");
837     } else if (d_ptr->m_ambientLightStrength != strength) {
838         d_ptr->m_ambientLightStrength = strength;
839         emit ambientLightStrengthChanged(strength);
840         emit d_ptr->needRender();
841     }
842 }
843 
ambientLightStrength() const844 float Q3DTheme::ambientLightStrength() const
845 {
846     return d_ptr->m_ambientLightStrength;
847 }
848 
849 /*!
850  * \property Q3DTheme::highlightLightStrength
851  *
852  * \brief The specular light strength for selected objects.
853  *
854  * The value must be between \c 0.0f and \c 10.0f.
855  */
setHighlightLightStrength(float strength)856 void Q3DTheme::setHighlightLightStrength(float strength)
857 {
858     d_ptr->m_dirtyBits.highlightLightStrengthDirty = true;
859     if (strength < 0.0f || strength > 10.0f) {
860         qWarning("Invalid value. Valid range for highlightLightStrength is between 0.0f and 10.0f");
861     } else if (d_ptr->m_highlightLightStrength != strength) {
862         d_ptr->m_highlightLightStrength = strength;
863         emit highlightLightStrengthChanged(strength);
864         emit d_ptr->needRender();
865     }
866 }
867 
highlightLightStrength() const868 float Q3DTheme::highlightLightStrength() const
869 {
870     return d_ptr->m_highlightLightStrength;
871 }
872 
873 /*!
874  * \property Q3DTheme::labelBorderEnabled
875  *
876  * \brief Whether label borders are drawn for labels that have a background.
877  *
878  * Has no effect if labelBackgroundEnabled is \c false.
879  */
setLabelBorderEnabled(bool enabled)880 void Q3DTheme::setLabelBorderEnabled(bool enabled)
881 {
882     d_ptr->m_dirtyBits.labelBorderEnabledDirty = true;
883     if (d_ptr->m_labelBorders != enabled) {
884         d_ptr->m_labelBorders = enabled;
885         emit labelBorderEnabledChanged(enabled);
886         emit d_ptr->needRender();
887     }
888 }
889 
isLabelBorderEnabled() const890 bool Q3DTheme::isLabelBorderEnabled() const
891 {
892     return d_ptr->m_labelBorders;
893 }
894 
895 /*!
896  * \property Q3DTheme::font
897  *
898  * \brief The font to be used for labels.
899  */
setFont(const QFont & font)900 void Q3DTheme::setFont(const QFont &font)
901 {
902     d_ptr->m_dirtyBits.fontDirty = true;
903     if (d_ptr->m_font != font) {
904         d_ptr->m_font = font;
905         emit fontChanged(font);
906         emit d_ptr->needRender();
907     }
908 }
909 
font() const910 QFont Q3DTheme::font() const
911 {
912     return d_ptr->m_font;
913 }
914 
915 /*!
916  * \property Q3DTheme::backgroundEnabled
917  *
918  * \brief Whether the background is visible.
919  *
920  * The background is drawn by using the value of backgroundColor.
921  */
setBackgroundEnabled(bool enabled)922 void Q3DTheme::setBackgroundEnabled(bool enabled)
923 {
924     d_ptr->m_dirtyBits.backgroundEnabledDirty = true;
925     if (d_ptr->m_backgoundEnabled != enabled) {
926         d_ptr->m_backgoundEnabled = enabled;
927         emit backgroundEnabledChanged(enabled);
928         emit d_ptr->needRender();
929     }
930 }
931 
isBackgroundEnabled() const932 bool Q3DTheme::isBackgroundEnabled() const
933 {
934     return d_ptr->m_backgoundEnabled;
935 }
936 
937 /*!
938  * \property Q3DTheme::gridEnabled
939  *
940  * \brief Whether the grid lines are drawn.
941  *
942  * This value affects all grid lines.
943  */
setGridEnabled(bool enabled)944 void Q3DTheme::setGridEnabled(bool enabled)
945 {
946     d_ptr->m_dirtyBits.gridEnabledDirty = true;
947     if (d_ptr->m_gridEnabled != enabled) {
948         d_ptr->m_gridEnabled = enabled;
949         emit gridEnabledChanged(enabled);
950         emit d_ptr->needRender();
951     }
952 }
953 
isGridEnabled() const954 bool Q3DTheme::isGridEnabled() const
955 {
956     return d_ptr->m_gridEnabled;
957 }
958 
959 /*!
960  * \property Q3DTheme::labelBackgroundEnabled
961  *
962  *\brief Whether the label is drawn with a color background or with a fully
963  * transparent background.
964  *
965  * The labelBackgroundColor value (including alpha) is used for drawing the
966  * background.
967  *
968  * Labels with a background are drawn to equal sizes per axis based
969  * on the longest label, and the text is centered in them. Labels without a
970  * background are drawn as is and are left or right aligned based on their
971  * position in the graph.
972  */
setLabelBackgroundEnabled(bool enabled)973 void Q3DTheme::setLabelBackgroundEnabled(bool enabled)
974 {
975     d_ptr->m_dirtyBits.labelBackgroundEnabledDirty = true;
976     if (d_ptr->m_labelBackground != enabled) {
977         d_ptr->m_labelBackground = enabled;
978         emit labelBackgroundEnabledChanged(enabled);
979         emit d_ptr->needRender();
980     }
981 }
982 
isLabelBackgroundEnabled() const983 bool Q3DTheme::isLabelBackgroundEnabled() const
984 {
985     return d_ptr->m_labelBackground;
986 }
987 
988 /*!
989  * \property Q3DTheme::colorStyle
990  *
991  * \brief The style of the graph colors.
992  *
993  * One of the ColorStyle enum values.
994  *
995  * This value can be overridden by setting \l{Abstract3DSeries::colorStyle}
996  * {colorStyle} explicitly in the series.
997  */
setColorStyle(ColorStyle style)998 void Q3DTheme::setColorStyle(ColorStyle style)
999 {
1000     d_ptr->m_dirtyBits.colorStyleDirty = true;
1001     if (d_ptr->m_colorStyle != style) {
1002         d_ptr->m_colorStyle = style;
1003         emit colorStyleChanged(style);
1004     }
1005 }
1006 
colorStyle() const1007 Q3DTheme::ColorStyle Q3DTheme::colorStyle() const
1008 {
1009     return d_ptr->m_colorStyle;
1010 }
1011 
1012 /*!
1013  * \property Q3DTheme::type
1014  *
1015  * \brief The type of the theme.
1016  *
1017  * The type is automatically set when constructing a theme,
1018  * but can also be changed later. Changing the theme type will change all other
1019  * properties of the theme to what the predefined theme specifies.
1020  * Changing the theme type of the active theme of the graph will also reset all
1021  * attached series to use the new theme.
1022  */
setType(Theme themeType)1023 void Q3DTheme::setType(Theme themeType)
1024 {
1025     d_ptr->m_dirtyBits.themeIdDirty = true;
1026     if (d_ptr->m_themeId != themeType) {
1027         d_ptr->m_themeId = themeType;
1028         ThemeManager::setPredefinedPropertiesToTheme(this, themeType);
1029         emit typeChanged(themeType);
1030     }
1031 }
1032 
type() const1033 Q3DTheme::Theme Q3DTheme::type() const
1034 {
1035     return d_ptr->m_themeId;
1036 }
1037 
1038 // Q3DThemePrivate
1039 
Q3DThemePrivate(Q3DTheme * q)1040 Q3DThemePrivate::Q3DThemePrivate(Q3DTheme *q)
1041     : QObject(0),
1042       m_themeId(Q3DTheme::ThemeUserDefined),
1043       m_backgroundColor(Qt::black),
1044       m_windowColor(Qt::black),
1045       m_textColor(Qt::white),
1046       m_textBackgroundColor(Qt::gray),
1047       m_gridLineColor(Qt::white),
1048       m_singleHighlightColor(Qt::red),
1049       m_multiHighlightColor(Qt::blue),
1050       m_lightColor(Qt::white),
1051       m_singleHighlightGradient(QLinearGradient(qreal(gradientTextureWidth),
1052                                                 qreal(gradientTextureHeight),
1053                                                 0.0, 0.0)),
1054       m_multiHighlightGradient(QLinearGradient(qreal(gradientTextureWidth),
1055                                                qreal(gradientTextureHeight),
1056                                                0.0, 0.0)),
1057       m_lightStrength(5.0f),
1058       m_ambientLightStrength(0.25f),
1059       m_highlightLightStrength(7.5f),
1060       m_labelBorders(true),
1061       m_colorStyle(Q3DTheme::ColorStyleUniform),
1062       m_font(QFont()),
1063       m_backgoundEnabled(true),
1064       m_gridEnabled(true),
1065       m_labelBackground(true),
1066       m_isDefaultTheme(false),
1067       m_forcePredefinedType(true),
1068       q_ptr(q)
1069 {
1070     m_baseColors.append(QColor(Qt::black));
1071     m_baseGradients.append(QLinearGradient(qreal(gradientTextureWidth),
1072                                            qreal(gradientTextureHeight),
1073                                            0.0, 0.0));
1074 }
1075 
~Q3DThemePrivate()1076 Q3DThemePrivate::~Q3DThemePrivate()
1077 {
1078 }
1079 
resetDirtyBits()1080 void Q3DThemePrivate::resetDirtyBits()
1081 {
1082     m_dirtyBits.ambientLightStrengthDirty = true;
1083     m_dirtyBits.backgroundColorDirty = true;
1084     m_dirtyBits.backgroundEnabledDirty = true;
1085     m_dirtyBits.baseColorDirty = true;
1086     m_dirtyBits.baseGradientDirty = true;
1087     m_dirtyBits.colorStyleDirty = true;
1088     m_dirtyBits.fontDirty = true;
1089     m_dirtyBits.gridEnabledDirty = true;
1090     m_dirtyBits.gridLineColorDirty = true;
1091     m_dirtyBits.highlightLightStrengthDirty = true;
1092     m_dirtyBits.labelBackgroundColorDirty = true;
1093     m_dirtyBits.labelBackgroundEnabledDirty = true;
1094     m_dirtyBits.labelBorderEnabledDirty = true;
1095     m_dirtyBits.labelTextColorDirty = true;
1096     m_dirtyBits.lightColorDirty = true;
1097     m_dirtyBits.lightStrengthDirty = true;
1098     m_dirtyBits.multiHighlightColorDirty = true;
1099     m_dirtyBits.multiHighlightGradientDirty = true;
1100     m_dirtyBits.singleHighlightColorDirty = true;
1101     m_dirtyBits.singleHighlightGradientDirty = true;
1102     m_dirtyBits.themeIdDirty = true;
1103     m_dirtyBits.windowColorDirty = true;
1104 }
1105 
sync(Q3DThemePrivate & other)1106 bool Q3DThemePrivate::sync(Q3DThemePrivate &other)
1107 {
1108     bool updateDrawer = false;
1109     if (m_dirtyBits.ambientLightStrengthDirty) {
1110         other.q_ptr->setAmbientLightStrength(m_ambientLightStrength);
1111         m_dirtyBits.ambientLightStrengthDirty = false;
1112     }
1113     if (m_dirtyBits.backgroundColorDirty) {
1114         other.q_ptr->setBackgroundColor(m_backgroundColor);
1115         m_dirtyBits.backgroundColorDirty = false;
1116     }
1117     if (m_dirtyBits.backgroundEnabledDirty) {
1118         other.q_ptr->setBackgroundEnabled(m_backgoundEnabled);
1119         m_dirtyBits.backgroundEnabledDirty = false;
1120     }
1121     if (m_dirtyBits.baseColorDirty) {
1122         other.q_ptr->setBaseColors(m_baseColors);
1123         m_dirtyBits.baseColorDirty = false;
1124     }
1125     if (m_dirtyBits.baseGradientDirty) {
1126         other.q_ptr->setBaseGradients(m_baseGradients);
1127         m_dirtyBits.baseGradientDirty = false;
1128     }
1129     if (m_dirtyBits.colorStyleDirty) {
1130         other.q_ptr->setColorStyle(m_colorStyle);
1131         m_dirtyBits.colorStyleDirty = false;
1132     }
1133     if (m_dirtyBits.fontDirty) {
1134         other.q_ptr->setFont(m_font);
1135         m_dirtyBits.fontDirty = false;
1136         updateDrawer = true;
1137     }
1138     if (m_dirtyBits.gridEnabledDirty) {
1139         other.q_ptr->setGridEnabled(m_gridEnabled);
1140         m_dirtyBits.gridEnabledDirty = false;
1141     }
1142     if (m_dirtyBits.gridLineColorDirty) {
1143         other.q_ptr->setGridLineColor(m_gridLineColor);
1144         m_dirtyBits.gridLineColorDirty = false;
1145     }
1146     if (m_dirtyBits.highlightLightStrengthDirty) {
1147         other.q_ptr->setHighlightLightStrength(m_highlightLightStrength);
1148         m_dirtyBits.highlightLightStrengthDirty = false;
1149     }
1150     if (m_dirtyBits.labelBackgroundColorDirty) {
1151         other.q_ptr->setLabelBackgroundColor(m_textBackgroundColor);
1152         m_dirtyBits.labelBackgroundColorDirty = false;
1153         updateDrawer = true;
1154     }
1155     if (m_dirtyBits.labelBackgroundEnabledDirty) {
1156         other.q_ptr->setLabelBackgroundEnabled(m_labelBackground);
1157         m_dirtyBits.labelBackgroundEnabledDirty = false;
1158         updateDrawer = true;
1159     }
1160     if (m_dirtyBits.labelBorderEnabledDirty) {
1161         other.q_ptr->setLabelBorderEnabled(m_labelBorders);
1162         m_dirtyBits.labelBorderEnabledDirty = false;
1163         updateDrawer = true;
1164     }
1165     if (m_dirtyBits.labelTextColorDirty) {
1166         other.q_ptr->setLabelTextColor(m_textColor);
1167         m_dirtyBits.labelTextColorDirty = false;
1168         updateDrawer = true;
1169     }
1170     if (m_dirtyBits.lightColorDirty) {
1171         other.q_ptr->setLightColor(m_lightColor);
1172         m_dirtyBits.lightColorDirty = false;
1173     }
1174     if (m_dirtyBits.lightStrengthDirty) {
1175         other.q_ptr->setLightStrength(m_lightStrength);
1176         m_dirtyBits.lightStrengthDirty = false;
1177     }
1178     if (m_dirtyBits.multiHighlightColorDirty) {
1179         other.q_ptr->setMultiHighlightColor(m_multiHighlightColor);
1180         m_dirtyBits.multiHighlightColorDirty = false;
1181     }
1182     if (m_dirtyBits.multiHighlightGradientDirty) {
1183         other.q_ptr->setMultiHighlightGradient(m_multiHighlightGradient);
1184         m_dirtyBits.multiHighlightGradientDirty = false;
1185     }
1186     if (m_dirtyBits.singleHighlightColorDirty) {
1187         other.q_ptr->setSingleHighlightColor(m_singleHighlightColor);
1188         m_dirtyBits.singleHighlightColorDirty = false;
1189     }
1190     if (m_dirtyBits.singleHighlightGradientDirty) {
1191         other.q_ptr->setSingleHighlightGradient(m_singleHighlightGradient);
1192         m_dirtyBits.singleHighlightGradientDirty = false;
1193     }
1194     if (m_dirtyBits.themeIdDirty) {
1195         other.m_themeId = m_themeId; // Set directly to avoid a call to ThemeManager's useTheme()
1196         m_dirtyBits.themeIdDirty = false;
1197     }
1198     if (m_dirtyBits.windowColorDirty) {
1199         other.q_ptr->setWindowColor(m_windowColor);
1200         m_dirtyBits.windowColorDirty = false;
1201     }
1202 
1203     return updateDrawer;
1204 }
1205 
1206 QT_END_NAMESPACE_DATAVISUALIZATION
1207