From aa842c39480aa5b95f704c97b8b3acc821144883 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 20 Dec 2013 10:56:59 +0200 Subject: Fix theme ownership Theme ownership now uses similar model as axis and inputhandler ownership: Graph can own multiple themes, but only one is active at the time. Task-number: QTRD-2623 Change-Id: I7134384df6f8cc465cc28fbebb454b7d2e254f83 Reviewed-by: Miikka Heikkinen --- src/datavisualization/theme/q3dtheme.cpp | 12 +- src/datavisualization/theme/q3dtheme_p.h | 4 + src/datavisualization/theme/thememanager.cpp | 193 +++++++++++++++++---------- src/datavisualization/theme/thememanager_p.h | 10 +- 4 files changed, 140 insertions(+), 79 deletions(-) (limited to 'src/datavisualization/theme') diff --git a/src/datavisualization/theme/q3dtheme.cpp b/src/datavisualization/theme/q3dtheme.cpp index 3d85b9fa..11773940 100644 --- a/src/datavisualization/theme/q3dtheme.cpp +++ b/src/datavisualization/theme/q3dtheme.cpp @@ -377,6 +377,10 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * \qmlproperty Theme3D.Theme Theme3D::type * * The type of the theme. If no type is set, the type is \c Theme3D.ThemeUserDefined. + * \note Changing the type to one of the predefined types doesn't reset the properties + * that have been explicitly set since the last render cycle. This is done to allow + * customization of predefined types also from QML. It is not recommended + * changing the type of an existing Theme3D item via this property. */ /*! @@ -862,8 +866,11 @@ Q3DTheme::ColorStyle Q3DTheme::colorStyle() const /*! * \property Q3DTheme::type * - * The type of the theme. Type is automatically set when constructing a theme. User should not - * need to use this when using C++ API. + * The type of the theme. Type is automatically set when constructing a theme. + * \note Changing the type to one of the predefined types doesn't reset the properties + * that have been explicitly set since the last render cycle. This is done to allow + * customization of predefined types also from QML. It is not recommended + * changing the type of an existing Q3DTheme object via this property. */ void Q3DTheme::setType(Theme themeType) { @@ -907,6 +914,7 @@ Q3DThemePrivate::Q3DThemePrivate(Q3DTheme *q, Q3DTheme::Theme theme_id) m_backgoundEnabled(true), m_gridEnabled(true), m_labelBackground(true), + m_isDefaultTheme(false), q_ptr(q) { m_baseColors.append(QColor(Qt::black)); diff --git a/src/datavisualization/theme/q3dtheme_p.h b/src/datavisualization/theme/q3dtheme_p.h index c9f59d99..24994854 100644 --- a/src/datavisualization/theme/q3dtheme_p.h +++ b/src/datavisualization/theme/q3dtheme_p.h @@ -97,6 +97,9 @@ public: bool sync(Q3DThemePrivate &other); + inline bool isDefaultTheme() { return m_isDefaultTheme; } + inline void setDefaultTheme(bool isDefault) { m_isDefaultTheme = isDefault; } + signals: void needRender(); @@ -126,6 +129,7 @@ public: bool m_backgoundEnabled; bool m_gridEnabled; bool m_labelBackground; + bool m_isDefaultTheme; protected: Q3DTheme *q_ptr; diff --git a/src/datavisualization/theme/thememanager.cpp b/src/datavisualization/theme/thememanager.cpp index cc5362ef..82e7bb53 100644 --- a/src/datavisualization/theme/thememanager.cpp +++ b/src/datavisualization/theme/thememanager.cpp @@ -25,7 +25,7 @@ const float defaultBuiltInColorLevel = 0.7f; // for built-in gradient themes const float defaultColorLevel = 0.5f; // for built-in uniform themes ThemeManager::ThemeManager(Abstract3DController *controller) - : m_theme(0), + : m_activeTheme(0), m_controller(controller) { } @@ -34,60 +34,105 @@ ThemeManager::~ThemeManager() { } -void ThemeManager::setTheme(Q3DTheme *theme) +void ThemeManager::addTheme(Q3DTheme *theme) { - if (!theme) - return; - - if (m_theme.data() != theme) { - // Disconnect old theme signal connections - if (m_theme) { - disconnect(m_theme->d_ptr.data(), 0, m_controller, 0); - disconnect(m_theme.data(), 0, m_controller, 0); - disconnect(m_theme.data(), 0, this, 0); - } + Q_ASSERT(theme); + ThemeManager *owner = qobject_cast(theme->parent()); + if (owner != this) { + Q_ASSERT_X(!owner, "addTheme", "Theme already attached to a graph."); + theme->setParent(this); + } + if (!m_themes.contains(theme)) + m_themes.append(theme); +} - m_theme.reset(theme); +void ThemeManager::releaseTheme(Q3DTheme *theme) +{ + if (theme && m_themes.contains(theme)) { + // Clear the default status from released default theme + if (theme->d_ptr->isDefaultTheme()) + theme->d_ptr->setDefaultTheme(false); - Q3DTheme::Theme type = m_theme->type(); + // If the axis is in use, replace it with a temporary one + if (theme == m_activeTheme) + setActiveTheme(0); - if (type != Q3DTheme::ThemeUserDefined) { - useTheme(type); - // Reset all bits to dirty for sync - m_theme->d_ptr->resetDirtyBits(); - } + m_themes.removeAll(theme); + theme->setParent(0); + } +} + +void ThemeManager::setActiveTheme(Q3DTheme *theme) +{ + // Setting null theme indicates using default theme + if (!theme) { + theme = new Q3DTheme; + theme->d_ptr->setDefaultTheme(true); + } - // Connect signals from new one - connectThemeSignals(); + // If the old theme is default theme, delete it + Q3DTheme *oldTheme = m_activeTheme; + if (oldTheme) { + if (oldTheme->d_ptr->isDefaultTheme()) { + m_themes.removeAll(oldTheme); + delete oldTheme; + oldTheme = 0; + } else { + // Disconnect the old theme from use + disconnect(m_activeTheme->d_ptr.data(), 0, m_controller, 0); + disconnect(m_activeTheme, 0, m_controller, 0); + disconnect(m_activeTheme, 0, this, 0); + } } + + // Assume ownership + addTheme(theme); + + m_activeTheme = theme; + + Q3DTheme::Theme type = m_activeTheme->type(); + + if (type != Q3DTheme::ThemeUserDefined) + useTheme(type); + + // Reset all bits to dirty for sync + m_activeTheme->d_ptr->resetDirtyBits(); + + // Connect signals from new one + connectThemeSignals(); +} + +Q3DTheme *ThemeManager::activeTheme() const +{ + return m_activeTheme; } -Q3DTheme *ThemeManager::theme() const +QList ThemeManager::themes() const { - return m_theme.data(); + return m_themes; } void ThemeManager::connectThemeSignals() { - connect(m_theme.data(), &Q3DTheme::colorStyleChanged, + connect(m_activeTheme, &Q3DTheme::colorStyleChanged, m_controller, &Abstract3DController::handleThemeColorStyleChanged); - connect(m_theme.data(), &Q3DTheme::baseColorsChanged, + connect(m_activeTheme, &Q3DTheme::baseColorsChanged, m_controller, &Abstract3DController::handleThemeBaseColorsChanged); - connect(m_theme.data(), &Q3DTheme::singleHighlightColorChanged, + connect(m_activeTheme, &Q3DTheme::singleHighlightColorChanged, m_controller, &Abstract3DController::handleThemeSingleHighlightColorChanged); - connect(m_theme.data(), &Q3DTheme::multiHighlightColorChanged, + connect(m_activeTheme, &Q3DTheme::multiHighlightColorChanged, m_controller, &Abstract3DController::handleThemeMultiHighlightColorChanged); - connect(m_theme.data(), &Q3DTheme::baseGradientsChanged, + connect(m_activeTheme, &Q3DTheme::baseGradientsChanged, m_controller, &Abstract3DController::handleThemeBaseGradientsChanged); - connect(m_theme.data(), &Q3DTheme::singleHighlightGradientChanged, + connect(m_activeTheme, &Q3DTheme::singleHighlightGradientChanged, m_controller, &Abstract3DController::handleThemeSingleHighlightGradientChanged); - connect(m_theme.data(), &Q3DTheme::multiHighlightGradientChanged, + connect(m_activeTheme, &Q3DTheme::multiHighlightGradientChanged, m_controller, &Abstract3DController::handleThemeMultiHighlightGradientChanged); - connect(m_theme->d_ptr.data(), &Q3DThemePrivate::needRender, + connect(m_activeTheme->d_ptr.data(), &Q3DThemePrivate::needRender, m_controller, &Abstract3DController::needRender); - connect(m_theme.data(), &Q3DTheme::typeChanged, this, &ThemeManager::useTheme); + connect(m_activeTheme, &Q3DTheme::typeChanged, this, &ThemeManager::useTheme); } void ThemeManager::useTheme(Q3DTheme::Theme type) @@ -425,128 +470,128 @@ QLinearGradient ThemeManager::createGradient(const QColor &color, float colorLev void ThemeManager::setBaseColors(const QList &colors) { - if (!m_theme->d_ptr->m_dirtyBits.baseColorDirty) - m_theme->setBaseColors(colors); + if (!m_activeTheme->d_ptr->m_dirtyBits.baseColorDirty) + m_activeTheme->setBaseColors(colors); } void ThemeManager::setBackgroundColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.backgroundColorDirty) - m_theme->setBackgroundColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.backgroundColorDirty) + m_activeTheme->setBackgroundColor(color); } void ThemeManager::setWindowColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.windowColorDirty) - m_theme->setWindowColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.windowColorDirty) + m_activeTheme->setWindowColor(color); } void ThemeManager::setTextColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.labelTextColorDirty) - m_theme->setLabelTextColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.labelTextColorDirty) + m_activeTheme->setLabelTextColor(color); } void ThemeManager::setTextBackgroundColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.labelBackgroundColorDirty) - m_theme->setLabelBackgroundColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.labelBackgroundColorDirty) + m_activeTheme->setLabelBackgroundColor(color); } void ThemeManager::setGridLineColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.gridLineColorDirty) - m_theme->setGridLineColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.gridLineColorDirty) + m_activeTheme->setGridLineColor(color); } void ThemeManager::setSingleHighlightColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.singleHighlightColorDirty) - m_theme->setSingleHighlightColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.singleHighlightColorDirty) + m_activeTheme->setSingleHighlightColor(color); } void ThemeManager::setMultiHighlightColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.multiHighlightColorDirty) - m_theme->setMultiHighlightColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.multiHighlightColorDirty) + m_activeTheme->setMultiHighlightColor(color); } void ThemeManager::setLightColor(const QColor &color) { - if (!m_theme->d_ptr->m_dirtyBits.lightColorDirty) - m_theme->setLightColor(color); + if (!m_activeTheme->d_ptr->m_dirtyBits.lightColorDirty) + m_activeTheme->setLightColor(color); } void ThemeManager::setBaseGradients(const QList &gradients) { - if (!m_theme->d_ptr->m_dirtyBits.baseGradientDirty) - m_theme->setBaseGradients(gradients); + if (!m_activeTheme->d_ptr->m_dirtyBits.baseGradientDirty) + m_activeTheme->setBaseGradients(gradients); } void ThemeManager::setSingleHighlightGradient(const QLinearGradient &gradient) { - if (!m_theme->d_ptr->m_dirtyBits.singleHighlightGradientDirty) - m_theme->setSingleHighlightGradient(gradient); + if (!m_activeTheme->d_ptr->m_dirtyBits.singleHighlightGradientDirty) + m_activeTheme->setSingleHighlightGradient(gradient); } void ThemeManager::setMultiHighlightGradient(const QLinearGradient &gradient) { - if (!m_theme->d_ptr->m_dirtyBits.multiHighlightGradientDirty) - m_theme->setMultiHighlightGradient(gradient); + if (!m_activeTheme->d_ptr->m_dirtyBits.multiHighlightGradientDirty) + m_activeTheme->setMultiHighlightGradient(gradient); } void ThemeManager::setLightStrength(float strength) { - if (!m_theme->d_ptr->m_dirtyBits.lightStrengthDirty) - m_theme->setLightStrength(strength); + if (!m_activeTheme->d_ptr->m_dirtyBits.lightStrengthDirty) + m_activeTheme->setLightStrength(strength); } void ThemeManager::setAmbientLightStrength(float strength) { - if (!m_theme->d_ptr->m_dirtyBits.ambientLightStrengthDirty) - m_theme->setAmbientLightStrength(strength); + if (!m_activeTheme->d_ptr->m_dirtyBits.ambientLightStrengthDirty) + m_activeTheme->setAmbientLightStrength(strength); } void ThemeManager::setHighlightLightStrength(float strength) { - if (!m_theme->d_ptr->m_dirtyBits.highlightLightStrengthDirty) - m_theme->setHighlightLightStrength(strength); + if (!m_activeTheme->d_ptr->m_dirtyBits.highlightLightStrengthDirty) + m_activeTheme->setHighlightLightStrength(strength); } void ThemeManager::setLabelBorderEnabled(bool enabled) { - if (!m_theme->d_ptr->m_dirtyBits.labelBorderEnabledDirty) - m_theme->setLabelBorderEnabled(enabled); + if (!m_activeTheme->d_ptr->m_dirtyBits.labelBorderEnabledDirty) + m_activeTheme->setLabelBorderEnabled(enabled); } void ThemeManager::setFont(const QFont &font) { - if (!m_theme->d_ptr->m_dirtyBits.fontDirty) - m_theme->setFont(font); + if (!m_activeTheme->d_ptr->m_dirtyBits.fontDirty) + m_activeTheme->setFont(font); } void ThemeManager::setBackgroundEnabled(bool enabled) { - if (!m_theme->d_ptr->m_dirtyBits.backgroundEnabledDirty) - m_theme->setBackgroundEnabled(enabled); + if (!m_activeTheme->d_ptr->m_dirtyBits.backgroundEnabledDirty) + m_activeTheme->setBackgroundEnabled(enabled); } void ThemeManager::setGridEnabled(bool enabled) { - if (!m_theme->d_ptr->m_dirtyBits.gridEnabledDirty) - m_theme->setGridEnabled(enabled); + if (!m_activeTheme->d_ptr->m_dirtyBits.gridEnabledDirty) + m_activeTheme->setGridEnabled(enabled); } void ThemeManager::setLabelBackgroundEnabled(bool enabled) { - if (!m_theme->d_ptr->m_dirtyBits.labelBackgroundEnabledDirty) - m_theme->setLabelBackgroundEnabled(enabled); + if (!m_activeTheme->d_ptr->m_dirtyBits.labelBackgroundEnabledDirty) + m_activeTheme->setLabelBackgroundEnabled(enabled); } void ThemeManager::setColorStyle(Q3DTheme::ColorStyle style) { - if (!m_theme->d_ptr->m_dirtyBits.colorStyleDirty) - m_theme->setColorStyle(style); + if (!m_activeTheme->d_ptr->m_dirtyBits.colorStyleDirty) + m_activeTheme->setColorStyle(style); } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/theme/thememanager_p.h b/src/datavisualization/theme/thememanager_p.h index c6e6a107..254bb7bf 100644 --- a/src/datavisualization/theme/thememanager_p.h +++ b/src/datavisualization/theme/thememanager_p.h @@ -42,8 +42,11 @@ public: ThemeManager(Abstract3DController *controller); ~ThemeManager(); - void setTheme(Q3DTheme *theme); - Q3DTheme *theme() const; + void addTheme(Q3DTheme *theme); + void releaseTheme(Q3DTheme *theme); + void setActiveTheme(Q3DTheme *theme); + Q3DTheme *activeTheme() const; + QList themes() const; protected: void connectThemeSignals(); @@ -72,7 +75,8 @@ protected: void setColorStyle(Q3DTheme::ColorStyle style); private: - QScopedPointer m_theme; + Q3DTheme *m_activeTheme; + QList m_themes; // List of all added themes Abstract3DController *m_controller; }; -- cgit v1.2.3