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 --- .../doc/snippets/doc_src_q3dtheme.cpp | 6 +- ...tdatavisualization-qml-abstractdeclarative.qdoc | 2 +- .../engine/abstract3dcontroller.cpp | 41 +++-- .../engine/abstract3dcontroller_p.h | 9 +- src/datavisualization/engine/bars3dcontroller.cpp | 2 +- src/datavisualization/engine/q3dbars.cpp | 19 -- src/datavisualization/engine/q3dbars.h | 6 - src/datavisualization/engine/q3dscatter.cpp | 19 -- src/datavisualization/engine/q3dscatter.h | 7 - src/datavisualization/engine/q3dsurface.cpp | 19 -- src/datavisualization/engine/q3dsurface.h | 6 - src/datavisualization/engine/q3dwindow.cpp | 60 +++++++ src/datavisualization/engine/q3dwindow.h | 11 ++ 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 +- 17 files changed, 253 insertions(+), 173 deletions(-) (limited to 'src/datavisualization') diff --git a/src/datavisualization/doc/snippets/doc_src_q3dtheme.cpp b/src/datavisualization/doc/snippets/doc_src_q3dtheme.cpp index 5a539e62..aa0ee859 100644 --- a/src/datavisualization/doc/snippets/doc_src_q3dtheme.cpp +++ b/src/datavisualization/doc/snippets/doc_src_q3dtheme.cpp @@ -57,9 +57,9 @@ int main(int argc, char **argv) //! [3] Q3DBars *graph = new Q3DBars(); - graph->setTheme(new Q3DTheme(Q3DTheme::ThemePrimaryColors)); - graph->theme()->setBaseColor(Qt::red); - graph->theme()->setSingleHighlightColor(Qt::yellow); + graph->setActiveTheme(new Q3DTheme(Q3DTheme::ThemePrimaryColors)); + graph->activeTheme()->setBaseColor(Qt::red); + graph->activeTheme()->setSingleHighlightColor(Qt::yellow); //! [3] } diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc index 7493709f..21dabf66 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc @@ -48,5 +48,5 @@ /*! \qmlproperty Theme3D AbstractGraph3D::theme - Theme of the graph. + The active theme of the graph. */ diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 9835dbe4..500ce9dc 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -52,7 +52,7 @@ Abstract3DController::Abstract3DController(QRect initialViewport, QObject *paren m_renderPending(false) { // Set initial theme - setTheme(new Q3DTheme(Q3DTheme::ThemeQt)); + setActiveTheme(new Q3DTheme(Q3DTheme::ThemeQt)); m_scene->d_ptr->setViewport(initialViewport); @@ -102,7 +102,7 @@ void Abstract3DController::addSeries(QAbstract3DSeries *series) this, &Abstract3DController::handleSeriesVisibilityChanged); if (series->isVisible()) handleSeriesVisibilityChangedBySender(series); - series->d_ptr->resetToTheme(*m_themeManager->theme(), oldSize, false); + series->d_ptr->resetToTheme(*m_themeManager->activeTheme(), oldSize, false); } } @@ -135,7 +135,7 @@ void Abstract3DController::synchDataToRenderer() m_renderer->updateScene(m_scene); - m_renderer->updateTheme(m_themeManager->theme()); + m_renderer->updateTheme(m_themeManager->activeTheme()); if (m_changeTracker.shadowQualityChanged) { m_renderer->updateShadowQuality(m_shadowQuality); @@ -595,22 +595,43 @@ void Abstract3DController::setZoomLevel(int zoomLevel) emitNeedRender(); } -void Abstract3DController::setTheme(Q3DTheme *theme) +void Abstract3DController::addTheme(Q3DTheme *theme) { - if (theme != m_themeManager->theme()) { - m_themeManager->setTheme(theme); + m_themeManager->addTheme(theme); +} + +void Abstract3DController::releaseTheme(Q3DTheme *theme) +{ + Q3DTheme *oldTheme = m_themeManager->activeTheme(); + + m_themeManager->releaseTheme(theme); + + if (oldTheme != m_themeManager->activeTheme()) + emit activeThemeChanged(m_themeManager->activeTheme()); +} +QList Abstract3DController::themes() const +{ + return m_themeManager->themes(); +} + +void Abstract3DController::setActiveTheme(Q3DTheme *theme) +{ + if (theme != m_themeManager->activeTheme()) { + m_themeManager->setActiveTheme(theme); m_changeTracker.themeChanged = true; + // Default theme can be created by theme manager, so ensure we have correct theme + Q3DTheme *newActiveTheme = m_themeManager->activeTheme(); // Reset all attached series to the new theme for (int i = 0; i < m_seriesList.size(); i++) - m_seriesList.at(i)->d_ptr->resetToTheme(*theme, i, true); + m_seriesList.at(i)->d_ptr->resetToTheme(*newActiveTheme, i, true); markSeriesVisualsDirty(); - emit themeChanged(theme); + emit activeThemeChanged(newActiveTheme); } } -Q3DTheme *Abstract3DController::theme() const +Q3DTheme *Abstract3DController::activeTheme() const { - return m_themeManager->theme(); + return m_themeManager->activeTheme(); } void Abstract3DController::setSelectionMode(QDataVis::SelectionFlags mode) diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index c56b8a72..a862a961 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -191,8 +191,11 @@ public: virtual int zoomLevel(); virtual void setZoomLevel(int zoomLevel); - virtual void setTheme(Q3DTheme *theme); - virtual Q3DTheme *theme() const; + virtual void addTheme(Q3DTheme *theme); + virtual void releaseTheme(Q3DTheme *theme); + virtual void setActiveTheme(Q3DTheme *theme); + virtual Q3DTheme *activeTheme() const; + virtual QList themes() const; virtual void setSelectionMode(QDataVis::SelectionFlags mode); virtual QDataVis::SelectionFlags selectionMode() const; @@ -253,7 +256,7 @@ public slots: signals: void shadowQualityChanged(QDataVis::ShadowQuality quality); void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler); - void themeChanged(Q3DTheme *theme); + void activeThemeChanged(Q3DTheme *activeTheme); void selectionModeChanged(QDataVis::SelectionFlags mode); void needRender(); diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 5232a566..007fdffc 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -72,7 +72,7 @@ void Bars3DController::initializeOpenGL() void Bars3DController::synchDataToRenderer() { // Background change requires reloading the meshes in bar graphs, so dirty the series visuals - if (m_themeManager->theme()->d_ptr->m_dirtyBits.backgroundEnabledDirty) { + if (m_themeManager->activeTheme()->d_ptr->m_dirtyBits.backgroundEnabledDirty) { m_isSeriesVisualsDirty = true; foreach (QAbstract3DSeries *series, m_seriesList) series->d_ptr->m_changeTracker.meshChanged = true; diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp index d4e97519..530235f2 100644 --- a/src/datavisualization/engine/q3dbars.cpp +++ b/src/datavisualization/engine/q3dbars.cpp @@ -108,8 +108,6 @@ Q3DBars::Q3DBars(QWindow *parent) &Q3DBars::selectionModeChanged); QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, this, &Q3DBars::shadowQualityChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::themeChanged, this, - &Q3DBars::themeChanged); QObject::connect(dptr()->m_shared, &Abstract3DController::needRender, d_ptr.data(), &Q3DWindowPrivate::renderLater); QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, dptr(), @@ -271,23 +269,6 @@ bool Q3DBars::isBarSpacingRelative() return dptr()->m_shared->isBarSpecRelative(); } -/*! - * \property Q3DBars::theme - * - * A \a theme to be used for the graph. Ownership of the \a theme is transferred. Previous theme - * is deleted when a new one is set. Properties of the \a theme can be modified even after setting - * it, and the modifications take effect immediately. - */ -void Q3DBars::setTheme(Q3DTheme *theme) -{ - dptr()->m_shared->setTheme(theme); -} - -Q3DTheme *Q3DBars::theme() const -{ - return dptrc()->m_shared->theme(); -} - /*! * \property Q3DBars::selectionMode * diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h index add3b11b..fac9558f 100644 --- a/src/datavisualization/engine/q3dbars.h +++ b/src/datavisualization/engine/q3dbars.h @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -42,7 +41,6 @@ class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow Q_PROPERTY(float barThickness READ barThickness WRITE setBarThickness NOTIFY barThicknessChanged) Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing NOTIFY barSpacingChanged) Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative NOTIFY barSpacingRelativeChanged) - Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(Q3DScene* scene READ scene) public: @@ -53,9 +51,6 @@ public: void removeSeries(QBar3DSeries *series); QList seriesList(); - void setTheme(Q3DTheme *theme); - Q3DTheme *theme() const; - void setBarThickness(float thicknessRatio); float barThickness(); @@ -89,7 +84,6 @@ signals: void barThicknessChanged(float thicknessRatio); void barSpacingChanged(QSizeF spacing); void barSpacingRelativeChanged(bool relative); - void themeChanged(Q3DTheme *theme); protected: diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp index 3c28b4a5..13b22df4 100644 --- a/src/datavisualization/engine/q3dscatter.cpp +++ b/src/datavisualization/engine/q3dscatter.cpp @@ -92,8 +92,6 @@ Q3DScatter::Q3DScatter(QWindow *parent) &Q3DScatter::selectionModeChanged); QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, this, &Q3DScatter::shadowQualityChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::themeChanged, this, - &Q3DScatter::themeChanged); QObject::connect(dptr()->m_shared, &Abstract3DController::needRender, d_ptr.data(), &Q3DWindowPrivate::renderLater); QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, dptr(), @@ -191,23 +189,6 @@ const Q3DScatterPrivate *Q3DScatter::dptrc() const return static_cast(d_ptr.data()); } -/*! - * \property Q3DScatter::theme - * - * A \a theme to be used for the graph. Ownership of the \a theme is transferred. Previous theme - * is deleted when a new one is set. Properties of the \a theme can be modified even after setting - * it, and the modifications take effect immediately. - */ -void Q3DScatter::setTheme(Q3DTheme *theme) -{ - dptr()->m_shared->setTheme(theme); -} - -Q3DTheme *Q3DScatter::theme() const -{ - return dptrc()->m_shared->theme(); -} - /*! * \property Q3DScatter::selectionMode * diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h index e58146a1..f71b469e 100644 --- a/src/datavisualization/engine/q3dscatter.h +++ b/src/datavisualization/engine/q3dscatter.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -33,14 +32,12 @@ class LabelItem; class Q3DValueAxis; class Q3DCategoryAxis; class QScatter3DSeries; -class Q3DTheme; class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow { Q_OBJECT Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) - Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(Q3DScene* scene READ scene) public: @@ -51,9 +48,6 @@ public: void removeSeries(QScatter3DSeries *series); QList seriesList(); - void setTheme(Q3DTheme *theme); - Q3DTheme *theme() const; - void setSelectionMode(QDataVis::SelectionFlags mode); QDataVis::SelectionFlags selectionMode() const; @@ -75,7 +69,6 @@ public: signals: void selectionModeChanged(QDataVis::SelectionFlags mode); void shadowQualityChanged(QDataVis::ShadowQuality quality); - void themeChanged(Q3DTheme* theme); protected: void mouseDoubleClickEvent(QMouseEvent *event); diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp index ce738685..feb2ef22 100644 --- a/src/datavisualization/engine/q3dsurface.cpp +++ b/src/datavisualization/engine/q3dsurface.cpp @@ -103,8 +103,6 @@ Q3DSurface::Q3DSurface(QWindow *parent) dptr()->m_shared->initializeOpenGL(); QObject::connect(dptr()->m_shared, &Abstract3DController::selectionModeChanged, this, &Q3DSurface::selectionModeChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::themeChanged, this, - &Q3DSurface::themeChanged); QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, this, &Q3DSurface::shadowQualityChanged); QObject::connect(dptr()->m_shared, &Abstract3DController::needRender, d_ptr.data(), @@ -204,23 +202,6 @@ const Q3DSurfacePrivate *Q3DSurface::dptrc() const return static_cast(d_ptr.data()); } -/*! - * \property Q3DSurface::theme - * - * A \a theme to be used for the graph. Ownership of the \a theme is transferred. Previous theme - * is deleted when a new one is set. Properties of the \a theme can be modified even after setting - * it, and the modifications take effect immediately. - */ -void Q3DSurface::setTheme(Q3DTheme *theme) -{ - dptr()->m_shared->setTheme(theme); -} - -Q3DTheme *Q3DSurface::theme() const -{ - return dptrc()->m_shared->theme(); -} - /*! * \property Q3DSurface::shadowQuality * diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h index bdbe65f5..b91854d5 100644 --- a/src/datavisualization/engine/q3dsurface.h +++ b/src/datavisualization/engine/q3dsurface.h @@ -29,13 +29,11 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class Q3DSurfacePrivate; class Q3DValueAxis; class QSurface3DSeries; -class Q3DTheme; class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow { Q_OBJECT Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged) - Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) Q_PROPERTY(Q3DScene* scene READ scene) @@ -47,9 +45,6 @@ public: void removeSeries(QSurface3DSeries *series); QList seriesList(); - void setTheme(Q3DTheme *theme); - Q3DTheme *theme() const; - void setShadowQuality(QDataVis::ShadowQuality quality); QDataVis::ShadowQuality shadowQuality() const; @@ -71,7 +66,6 @@ public: signals: void selectionModeChanged(QDataVis::SelectionFlags mode); - void themeChanged(Q3DTheme *theme); void shadowQualityChanged(QDataVis::ShadowQuality quality); protected: diff --git a/src/datavisualization/engine/q3dwindow.cpp b/src/datavisualization/engine/q3dwindow.cpp index 5285b585..6bf7da5e 100644 --- a/src/datavisualization/engine/q3dwindow.cpp +++ b/src/datavisualization/engine/q3dwindow.cpp @@ -92,6 +92,10 @@ Q3DWindow::Q3DWindow(Q3DWindowPrivate *d, QWindow *parent) if (splitversionstr[0].toFloat() < 1.2) qFatal("GLSL version must be 1.20 or higher. Try installing latest display drivers."); #endif + + QObject::connect(d_ptr->m_visualController, &Abstract3DController::activeThemeChanged, this, + &Q3DWindow::activeThemeChanged); + d_ptr->renderLater(); } @@ -148,6 +152,62 @@ QAbstract3DInputHandler *Q3DWindow::activeInputHandler() return d_ptr->m_visualController->activeInputHandler(); } +/*! + * Adds the given \a theme to the graph. The themes added via addTheme are not taken in to use + * directly. Only the ownership of the a\ theme is given to the graph. + * The \a theme must not be null or already added to another graph. + * + * \sa releaseTheme(), setActiveTheme() + */ +void Q3DWindow::addTheme(Q3DTheme *theme) +{ + d_ptr->m_visualController->addTheme(theme); +} + +/*! + * Releases the ownership of the \a theme back to the caller, if it was added to this graph. + * If the released \a theme is in use, a new default theme will be created and set active. + * + * If the default theme is released and added back later, it behaves as any other theme would. + * + * \sa addTheme(), setActiveTheme() + */ +void Q3DWindow::releaseTheme(Q3DTheme *theme) +{ + d_ptr->m_visualController->releaseTheme(theme); +} + +/*! + * \property Q3DWindow::activeTheme + * + * The active \a theme to be used for the graph. Implicitly calls addTheme() to transfer ownership + * of the \a theme to this graph. + * If the \a theme is null, a temporary default theme is created. This temporary theme is destroyed + * if any theme is explicitly set later. + * Properties of the \a theme can be modified even after setting it, and the modifications take + * effect immediately. + */ +void Q3DWindow::setActiveTheme(Q3DTheme *theme) +{ + d_ptr->m_visualController->setActiveTheme(theme); +} + + +Q3DTheme *Q3DWindow::activeTheme() const +{ + return d_ptr->m_visualController->activeTheme(); +} + +/*! + * \return list of all added themes. + * + * \sa addTheme() + */ +QList Q3DWindow::themes() const +{ + return d_ptr->m_visualController->themes(); +} + /*! * \internal */ diff --git a/src/datavisualization/engine/q3dwindow.h b/src/datavisualization/engine/q3dwindow.h index cdffc6b9..18542868 100644 --- a/src/datavisualization/engine/q3dwindow.h +++ b/src/datavisualization/engine/q3dwindow.h @@ -32,10 +32,12 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class Q3DWindowPrivate; class Abstract3DController; class QAbstract3DInputHandler; +class Q3DTheme; class QT_DATAVISUALIZATION_EXPORT Q3DWindow : public QWindow, protected QOpenGLFunctions { Q_OBJECT + Q_PROPERTY(Q3DTheme* activeTheme READ activeTheme WRITE setActiveTheme NOTIFY activeThemeChanged) protected: explicit Q3DWindow(Q3DWindowPrivate *d, QWindow *parent = 0); @@ -47,11 +49,20 @@ public: void setActiveInputHandler(QAbstract3DInputHandler *inputHandler); QAbstract3DInputHandler *activeInputHandler(); + void addTheme(Q3DTheme *theme); + void releaseTheme(Q3DTheme *theme); + void setActiveTheme(Q3DTheme *theme); + Q3DTheme *activeTheme() const; + QList themes() const; + protected: bool event(QEvent *event); void resizeEvent(QResizeEvent *event); void exposeEvent(QExposeEvent *event); +signals: + void activeThemeChanged(Q3DTheme *theme); + private: QScopedPointer d_ptr; 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