summaryrefslogtreecommitdiffstats
path: root/src/datavisualizationqml/declarativetheme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualizationqml/declarativetheme.cpp')
-rw-r--r--src/datavisualizationqml/declarativetheme.cpp388
1 files changed, 388 insertions, 0 deletions
diff --git a/src/datavisualizationqml/declarativetheme.cpp b/src/datavisualizationqml/declarativetheme.cpp
new file mode 100644
index 00000000..02f3becc
--- /dev/null
+++ b/src/datavisualizationqml/declarativetheme.cpp
@@ -0,0 +1,388 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
+
+#include "declarativetheme_p.h"
+
+QT_BEGIN_NAMESPACE
+
+DeclarativeTheme3D::DeclarativeTheme3D(QObject *parent)
+ : Q3DTheme(parent),
+ m_colors(QList<DeclarativeColor *>()),
+ m_gradients(QList<ColorGradient *>()),
+ m_singleHLGradient(0),
+ m_multiHLGradient(0),
+ m_dummyGradients(false),
+ m_dummyColors(false)
+{
+ connect(this, &Q3DTheme::typeChanged, this, &DeclarativeTheme3D::handleTypeChange);
+}
+
+DeclarativeTheme3D::~DeclarativeTheme3D()
+{
+}
+
+QQmlListProperty<QObject> DeclarativeTheme3D::themeChildren()
+{
+ return QQmlListProperty<QObject>(this, this, &DeclarativeTheme3D::appendThemeChildren,
+ 0, 0, 0);
+}
+
+void DeclarativeTheme3D::appendThemeChildren(QQmlListProperty<QObject> *list, QObject *element)
+{
+ Q_UNUSED(list);
+ Q_UNUSED(element);
+ // Nothing to do, themeChildren is there only to enable scoping gradient items in Theme3D item.
+}
+
+void DeclarativeTheme3D::handleTypeChange(Theme themeType)
+{
+ Q_UNUSED(themeType);
+
+ // Theme changed, disconnect base color/gradient connections
+ if (!m_colors.isEmpty()) {
+ foreach (DeclarativeColor *item, m_colors)
+ disconnect(item, 0, this, 0);
+ m_colors.clear();
+ }
+ if (!m_gradients.isEmpty()) {
+ foreach (ColorGradient *item, m_gradients)
+ disconnect(item, 0, this, 0);
+ m_gradients.clear();
+ }
+}
+
+void DeclarativeTheme3D::handleBaseColorUpdate()
+{
+ int colorCount = m_colors.size();
+ int changed = 0;
+ // Check which one changed
+ DeclarativeColor *color = qobject_cast<DeclarativeColor *>(QObject::sender());
+ for (int i = 0; i < colorCount; i++) {
+ if (color == m_colors.at(i)) {
+ changed = i;
+ break;
+ }
+ }
+ // Update the changed one from the list
+ QList<QColor> list = Q3DTheme::baseColors();
+ list[changed] = m_colors.at(changed)->color();
+ // Set the changed list
+ Q3DTheme::setBaseColors(list);
+}
+
+void DeclarativeTheme3D::handleBaseGradientUpdate()
+{
+ int gradientCount = m_gradients.size();
+ int changed = 0;
+ // Check which one changed
+ ColorGradient *gradient = qobject_cast<ColorGradient *>(QObject::sender());
+ for (int i = 0; i < gradientCount; i++) {
+ if (gradient == m_gradients.at(i)) {
+ changed = i;
+ break;
+ }
+ }
+ // Update the changed one from the list
+ QList<QLinearGradient> list = Q3DTheme::baseGradients();
+ list[changed] = convertGradient(gradient);
+ // Set the changed list
+ Q3DTheme::setBaseGradients(list);
+}
+
+void DeclarativeTheme3D::handleSingleHLGradientUpdate()
+{
+ if (m_singleHLGradient)
+ setThemeGradient(m_singleHLGradient, GradientTypeSingleHL);
+}
+
+void DeclarativeTheme3D::handleMultiHLGradientUpdate()
+{
+ if (m_multiHLGradient)
+ setThemeGradient(m_multiHLGradient, GradientTypeMultiHL);
+}
+
+void DeclarativeTheme3D::setSingleHighlightGradient(ColorGradient *gradient)
+{
+ // connect new / disconnect old
+ if (gradient != m_singleHLGradient) {
+ if (m_singleHLGradient)
+ QObject::disconnect(m_singleHLGradient, 0, this, 0);
+
+ m_singleHLGradient = gradient;
+
+ if (m_singleHLGradient) {
+ QObject::connect(m_singleHLGradient, &ColorGradient::updated, this,
+ &DeclarativeTheme3D::handleSingleHLGradientUpdate);
+ }
+
+ emit singleHighlightGradientChanged(m_singleHLGradient);
+ }
+
+ if (m_singleHLGradient)
+ setThemeGradient(m_singleHLGradient, GradientTypeSingleHL);
+}
+
+ColorGradient *DeclarativeTheme3D::singleHighlightGradient() const
+{
+ return m_singleHLGradient;
+}
+
+void DeclarativeTheme3D::setMultiHighlightGradient(ColorGradient *gradient)
+{
+ // connect new / disconnect old
+ if (gradient != m_multiHLGradient) {
+ if (m_multiHLGradient)
+ QObject::disconnect(m_multiHLGradient, 0, this, 0);
+
+ m_multiHLGradient = gradient;
+
+ if (m_multiHLGradient) {
+ QObject::connect(m_multiHLGradient, &ColorGradient::updated, this,
+ &DeclarativeTheme3D::handleMultiHLGradientUpdate);
+ }
+
+ emit multiHighlightGradientChanged(m_multiHLGradient);
+ }
+
+ if (m_multiHLGradient)
+ setThemeGradient(m_multiHLGradient, GradientTypeMultiHL);
+}
+
+ColorGradient *DeclarativeTheme3D::multiHighlightGradient() const
+{
+ return m_multiHLGradient;
+}
+
+void DeclarativeTheme3D::classBegin()
+{
+ // Turn off predefined type forcing for the duration of initial class construction
+ // so that predefined type customization can be done.
+ d_ptr->setForcePredefinedType(false);
+}
+
+void DeclarativeTheme3D::componentComplete()
+{
+ d_ptr->setForcePredefinedType(true);
+}
+
+
+void DeclarativeTheme3D::setThemeGradient(ColorGradient *gradient, GradientType type)
+{
+ QLinearGradient newGradient = convertGradient(gradient);
+
+ switch (type) {
+ case GradientTypeSingleHL:
+ Q3DTheme::setSingleHighlightGradient(newGradient);
+ break;
+ case GradientTypeMultiHL:
+ Q3DTheme::setMultiHighlightGradient(newGradient);
+ break;
+ default:
+ qWarning("Incorrect usage. Type may be GradientTypeSingleHL or GradientTypeMultiHL.");
+ break;
+ }
+}
+
+QLinearGradient DeclarativeTheme3D::convertGradient(ColorGradient *gradient)
+{
+ QLinearGradient newGradient;
+ QGradientStops stops;
+ QList<ColorGradientStop *> qmlstops = gradient->m_stops;
+
+ // Get sorted gradient stops
+ for (int i = 0; i < qmlstops.size(); i++) {
+ int j = 0;
+ while (j < stops.size() && stops.at(j).first < qmlstops[i]->position())
+ j++;
+ stops.insert(j, QGradientStop(qmlstops.at(i)->position(), qmlstops.at(i)->color()));
+ }
+
+ newGradient.setStops(stops);
+
+ return newGradient;
+}
+
+ColorGradient *DeclarativeTheme3D::convertGradient(const QLinearGradient &gradient)
+{
+ ColorGradient *newGradient = new ColorGradient(this);
+ QGradientStops stops = gradient.stops();
+ ColorGradientStop *qmlstop;
+
+ // Convert stops
+ for (int i = 0; i < stops.size(); i++) {
+ qmlstop = new ColorGradientStop(newGradient);
+ qmlstop->setColor(stops.at(i).second);
+ qmlstop->setPosition(stops.at(i).first);
+ newGradient->m_stops.append(qmlstop);
+ }
+
+ return newGradient;
+}
+
+void DeclarativeTheme3D::addColor(DeclarativeColor *color)
+{
+ if (!color) {
+ qWarning("Color is invalid, use ThemeColor");
+ return;
+ }
+ clearDummyColors();
+ m_colors.append(color);
+ connect(color, &DeclarativeColor::colorChanged,
+ this, &DeclarativeTheme3D::handleBaseColorUpdate);
+ QList<QColor> list = Q3DTheme::baseColors();
+ list.append(color->color());
+ Q3DTheme::setBaseColors(list);
+}
+
+QList<DeclarativeColor *> DeclarativeTheme3D::colorList()
+{
+ if (m_colors.isEmpty()) {
+ // Create dummy ThemeColors from theme's colors
+ m_dummyColors = true;
+ QList<QColor> list = Q3DTheme::baseColors();
+ foreach (QColor item, list) {
+ DeclarativeColor *color = new DeclarativeColor(this);
+ color->setColor(item);
+ m_colors.append(color);
+ connect(color, &DeclarativeColor::colorChanged,
+ this, &DeclarativeTheme3D::handleBaseColorUpdate);
+ }
+ }
+ return m_colors;
+}
+
+void DeclarativeTheme3D::clearColors()
+{
+ clearDummyColors();
+ foreach (DeclarativeColor *item, m_colors)
+ disconnect(item, 0, this, 0);
+ m_colors.clear();
+ Q3DTheme::setBaseColors(QList<QColor>());
+}
+
+void DeclarativeTheme3D::clearDummyColors()
+{
+ if (m_dummyColors) {
+ foreach (DeclarativeColor *item, m_colors)
+ delete item;
+ m_colors.clear();
+ m_dummyColors = false;
+ }
+}
+
+void DeclarativeTheme3D::addGradient(ColorGradient *gradient)
+{
+ if (!gradient) {
+ qWarning("Gradient is invalid, use ColorGradient");
+ return;
+ }
+ clearDummyGradients();
+ m_gradients.append(gradient);
+ connect(gradient, &ColorGradient::updated,
+ this, &DeclarativeTheme3D::handleBaseGradientUpdate);
+ QList<QLinearGradient> list = Q3DTheme::baseGradients();
+ list.append(convertGradient(gradient));
+ Q3DTheme::setBaseGradients(list);
+}
+
+QList<ColorGradient *> DeclarativeTheme3D::gradientList()
+{
+ if (m_gradients.isEmpty()) {
+ // Create dummy ColorGradients from theme's gradients
+ m_dummyGradients = true;
+ QList<QLinearGradient> list = Q3DTheme::baseGradients();
+ foreach (QLinearGradient item, list) {
+ ColorGradient *gradient = convertGradient(item);
+ m_gradients.append(gradient);
+ connect(gradient, &ColorGradient::updated,
+ this, &DeclarativeTheme3D::handleBaseGradientUpdate);
+ }
+ }
+
+ return m_gradients;
+}
+
+void DeclarativeTheme3D::clearGradients()
+{
+ clearDummyGradients();
+ foreach (ColorGradient *item, m_gradients)
+ disconnect(item, 0, this, 0);
+ m_gradients.clear();
+ Q3DTheme::setBaseGradients(QList<QLinearGradient>());
+}
+
+void DeclarativeTheme3D::clearDummyGradients()
+{
+ if (m_dummyGradients) {
+ foreach (ColorGradient *item, m_gradients)
+ delete item;
+ m_gradients.clear();
+ m_dummyGradients = false;
+ }
+}
+
+QQmlListProperty<DeclarativeColor> DeclarativeTheme3D::baseColors()
+{
+ return QQmlListProperty<DeclarativeColor>(this, this,
+ &DeclarativeTheme3D::appendBaseColorsFunc,
+ &DeclarativeTheme3D::countBaseColorsFunc,
+ &DeclarativeTheme3D::atBaseColorsFunc,
+ &DeclarativeTheme3D::clearBaseColorsFunc);
+}
+
+void DeclarativeTheme3D::appendBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list,
+ DeclarativeColor *color)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->addColor(color);
+}
+
+qsizetype DeclarativeTheme3D::countBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->colorList().size();
+}
+
+DeclarativeColor *DeclarativeTheme3D::atBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list,
+ qsizetype index)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->colorList().at(index);
+}
+
+void DeclarativeTheme3D::clearBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->clearColors();
+}
+
+QQmlListProperty<ColorGradient> DeclarativeTheme3D::baseGradients()
+{
+ return QQmlListProperty<ColorGradient>(this, this,
+ &DeclarativeTheme3D::appendBaseGradientsFunc,
+ &DeclarativeTheme3D::countBaseGradientsFunc,
+ &DeclarativeTheme3D::atBaseGradientsFunc,
+ &DeclarativeTheme3D::clearBaseGradientsFunc);
+}
+
+void DeclarativeTheme3D::appendBaseGradientsFunc(QQmlListProperty<ColorGradient> *list,
+ ColorGradient *gradient)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->addGradient(gradient);
+}
+
+qsizetype DeclarativeTheme3D::countBaseGradientsFunc(QQmlListProperty<ColorGradient> *list)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->gradientList().size();
+}
+
+ColorGradient *DeclarativeTheme3D::atBaseGradientsFunc(QQmlListProperty<ColorGradient> *list,
+ qsizetype index)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->gradientList().at(index);
+}
+
+void DeclarativeTheme3D::clearBaseGradientsFunc(QQmlListProperty<ColorGradient> *list)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->clearGradients();
+}
+
+QT_END_NAMESPACE