diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-12-20 10:56:59 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-01-07 08:10:13 +0200 |
commit | aa842c39480aa5b95f704c97b8b3acc821144883 (patch) | |
tree | 8a1e90e1fe1d6d85054286e655cb2e1722d758eb | |
parent | 91a94a743b4cfd30ef77aa73837050d44620469b (diff) |
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 <miikka.heikkinen@digia.com>
35 files changed, 419 insertions, 289 deletions
diff --git a/examples/audiolevels/audiolevels.cpp b/examples/audiolevels/audiolevels.cpp index 3677c1f1..259274d9 100644 --- a/examples/audiolevels/audiolevels.cpp +++ b/examples/audiolevels/audiolevels.cpp @@ -46,12 +46,12 @@ AudioLevels::AudioLevels(Q3DBars *graph, QObject *parent) m_graph->setShadowQuality(QDataVis::ShadowQualityNone); m_graph->setSelectionMode(QDataVis::SelectionNone); m_graph->scene()->activeCamera()->setCameraPosition(-25.0f, 10.0f, 190.0f); - m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeIsabelle)); - m_graph->theme()->setGridEnabled(true); - m_graph->theme()->setBackgroundEnabled(false); - QFont font = m_graph->theme()->font(); + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeIsabelle)); + m_graph->activeTheme()->setGridEnabled(true); + m_graph->activeTheme()->setBackgroundEnabled(false); + QFont font = m_graph->activeTheme()->font(); font.setPointSize(10); - m_graph->theme()->setFont(font); + m_graph->activeTheme()->setFont(font); QBar3DSeries *series = new QBar3DSeries; series->setMesh(QAbstract3DSeries::MeshBar); m_graph->addSeries(series); diff --git a/examples/bars/graphmodifier.cpp b/examples/bars/graphmodifier.cpp index 13e4d3e7..09fec65d 100644 --- a/examples/bars/graphmodifier.cpp +++ b/examples/bars/graphmodifier.cpp @@ -54,9 +54,9 @@ GraphModifier::GraphModifier(Q3DBars *bargraph) { //! [2] m_graph->setShadowQuality(QDataVis::ShadowQualitySoftMedium); - m_graph->theme()->setBackgroundEnabled(false); - m_graph->theme()->setFont(QFont("Times New Roman", m_fontSize)); - m_graph->theme()->setLabelBackgroundEnabled(true); + m_graph->activeTheme()->setBackgroundEnabled(false); + m_graph->activeTheme()->setFont(QFont("Times New Roman", m_fontSize)); + m_graph->activeTheme()->setLabelBackgroundEnabled(true); //! [2] m_months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December"; @@ -185,16 +185,20 @@ void GraphModifier::changePresetCamera() void GraphModifier::changeTheme(int theme) { - m_graph->setTheme(new Q3DTheme(Q3DTheme::Theme(theme))); - emit backgroundEnabledChanged(m_graph->theme()->isBackgroundEnabled()); - emit gridEnabledChanged(m_graph->theme()->isGridEnabled()); - emit fontChanged(m_graph->theme()->font()); - emit fontSizeChanged(m_graph->theme()->font().pointSize()); + Q3DTheme *currentTheme = m_graph->activeTheme(); + m_graph->releaseTheme(currentTheme); + delete currentTheme; + currentTheme = new Q3DTheme(Q3DTheme::Theme(theme)); + m_graph->setActiveTheme(currentTheme); + emit backgroundEnabledChanged(currentTheme->isBackgroundEnabled()); + emit gridEnabledChanged(currentTheme->isGridEnabled()); + emit fontChanged(currentTheme->font()); + emit fontSizeChanged(currentTheme->font().pointSize()); } void GraphModifier::changeLabelBackground() { - m_graph->theme()->setLabelBackgroundEnabled(!m_graph->theme()->isLabelBackgroundEnabled()); + m_graph->activeTheme()->setLabelBackgroundEnabled(!m_graph->activeTheme()->isLabelBackgroundEnabled()); } void GraphModifier::changeSelectionMode(int selectionMode) @@ -209,15 +213,15 @@ void GraphModifier::changeSelectionMode(int selectionMode) void GraphModifier::changeFont(const QFont &font) { QFont newFont = font; - m_graph->theme()->setFont(newFont); + m_graph->activeTheme()->setFont(newFont); } void GraphModifier::changeFontSize(int fontsize) { m_fontSize = fontsize; - QFont font = m_graph->theme()->font(); + QFont font = m_graph->activeTheme()->font(); font.setPointSize(m_fontSize); - m_graph->theme()->setFont(font); + m_graph->activeTheme()->setFont(font); } void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq) @@ -250,12 +254,12 @@ void GraphModifier::rotateY(int rotation) void GraphModifier::setBackgroundEnabled(int enabled) { - m_graph->theme()->setBackgroundEnabled(bool(enabled)); + m_graph->activeTheme()->setBackgroundEnabled(bool(enabled)); } void GraphModifier::setGridEnabled(int enabled) { - m_graph->theme()->setGridEnabled(bool(enabled)); + m_graph->activeTheme()->setGridEnabled(bool(enabled)); } void GraphModifier::setSmoothBars(int smooth) diff --git a/examples/custominput/scatterdatamodifier.cpp b/examples/custominput/scatterdatamodifier.cpp index aabb1b3a..aeef4c98 100644 --- a/examples/custominput/scatterdatamodifier.cpp +++ b/examples/custominput/scatterdatamodifier.cpp @@ -32,7 +32,7 @@ ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter) : m_graph(scatter), m_inputHandler(new CustomInputHandler()) { - m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeDigia)); + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeDigia)); m_graph->setShadowQuality(QDataVis::ShadowQualityMedium); m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront); diff --git a/examples/customproxy/rainfallgraph.cpp b/examples/customproxy/rainfallgraph.cpp index ad45d016..57e1d0ea 100644 --- a/examples/customproxy/rainfallgraph.cpp +++ b/examples/customproxy/rainfallgraph.cpp @@ -72,10 +72,10 @@ RainfallGraph::RainfallGraph(Q3DBars *rainfall) m_graph->setSelectionMode(QDataVis::SelectionItemAndColumn | QDataVis::SelectionSlice); // Set theme - m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeArmyBlue)); + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeArmyBlue)); // Set font to theme - m_graph->theme()->setFont(QFont("Century Gothic", 30)); + m_graph->activeTheme()->setFont(QFont("Century Gothic", 30)); // Set camera position and zoom m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricRightHigh); diff --git a/examples/itemmodel/main.cpp b/examples/itemmodel/main.cpp index 46aa8bb8..015470d1 100644 --- a/examples/itemmodel/main.cpp +++ b/examples/itemmodel/main.cpp @@ -107,10 +107,10 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid //! [7] // Set theme - m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeDigia)); + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeDigia)); // Set font - m_graph->theme()->setFont(QFont("Impact", 20)); + m_graph->activeTheme()->setFont(QFont("Impact", 20)); // Set preset camera position m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront); diff --git a/examples/qmlscatter/doc/src/qmlscatter.qdoc b/examples/qmlscatter/doc/src/qmlscatter.qdoc index 0a758751..19559f4c 100644 --- a/examples/qmlscatter/doc/src/qmlscatter.qdoc +++ b/examples/qmlscatter/doc/src/qmlscatter.qdoc @@ -112,9 +112,13 @@ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 3 - We added a built-in Theme3D and changed the font in it. We also changed the shadow quality. + We added a customized theme and changed the shadow quality. We're happy with the other visual properties, so we won't change them. + The custom theme is based on a predefined theme, but we change the font in it: + + \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 13 + Then it's time to start feeding the graph some data. \section1 Adding data to the graph diff --git a/examples/qmlscatter/qml/qmlscatter/main.qml b/examples/qmlscatter/qml/qmlscatter/main.qml index e0a7f26b..50164c50 100644 --- a/examples/qmlscatter/qml/qmlscatter/main.qml +++ b/examples/qmlscatter/qml/qmlscatter/main.qml @@ -33,6 +33,21 @@ Item { id: seriesData } //! [4] + + //! [13] + Theme3D { + id: themeIsabelle + type: Theme3D.ThemeIsabelle + font.family: "Lucida Handwriting" + font.pointSize: 40 + } + //! [13] + + Theme3D { + id : themeArmyBlue + type: Theme3D.ThemeArmyBlue + } + //! [8] //! [9] Item { @@ -50,11 +65,7 @@ Item { height: dataView.height //! [2] //! [3] - theme: Theme3D { - type: Theme3D.ThemeIsabelle - font.family: "Lucida Handwriting" - font.pointSize: 40 - } + theme: themeIsabelle shadowQuality: AbstractGraph3D.ShadowQualitySoftLow //! [3] //! [6] @@ -179,14 +190,9 @@ Item { text: "Change Theme" onClicked: { if (scatterGraph.theme.type === Theme3D.ThemeArmyBlue) { - // Ownership of the theme is transferred and old theme is destroyed when setting - // a new one, so we need to create them dynamically - scatterGraph.theme = Qt.createQmlObject('import QtDataVisualization 1.0; - Theme3D {type: Theme3D.ThemeIsabelle; font.family: "Lucida Handwriting"; - font.pointSize: 40}', parent); + scatterGraph.theme = themeIsabelle } else { - scatterGraph.theme = Qt.createQmlObject('import QtDataVisualization 1.0; - Theme3D {type: Theme3D.ThemeArmyBlue}', parent); + scatterGraph.theme = themeArmyBlue } } } diff --git a/examples/scatter/scatterdatamodifier.cpp b/examples/scatter/scatterdatamodifier.cpp index 6cdb1458..964da977 100644 --- a/examples/scatter/scatterdatamodifier.cpp +++ b/examples/scatter/scatterdatamodifier.cpp @@ -39,10 +39,10 @@ ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter) m_smooth(true) { //! [0] - m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeEbony)); - QFont font = m_graph->theme()->font(); + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeEbony)); + QFont font = m_graph->activeTheme()->font(); font.setPointSize(m_fontSize); - m_graph->theme()->setFont(font); + m_graph->activeTheme()->setFont(font); m_graph->setShadowQuality(QDataVis::ShadowQualitySoftLow); m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront); //! [0] @@ -131,10 +131,14 @@ void ScatterDataModifier::setSmoothDots(int smooth) void ScatterDataModifier::changeTheme(int theme) { - m_graph->setTheme(new Q3DTheme(Q3DTheme::Theme(theme))); - emit backgroundEnabledChanged(m_graph->theme()->isBackgroundEnabled()); - emit gridEnabledChanged(m_graph->theme()->isGridEnabled()); - emit fontChanged(m_graph->theme()->font()); + Q3DTheme *currentTheme = m_graph->activeTheme(); + m_graph->releaseTheme(currentTheme); + delete currentTheme; + currentTheme = new Q3DTheme(Q3DTheme::Theme(theme)); + m_graph->setActiveTheme(currentTheme); + emit backgroundEnabledChanged(currentTheme->isBackgroundEnabled()); + emit gridEnabledChanged(currentTheme->isGridEnabled()); + emit fontChanged(currentTheme->font()); } void ScatterDataModifier::changePresetCamera() @@ -149,14 +153,14 @@ void ScatterDataModifier::changePresetCamera() void ScatterDataModifier::changeLabelStyle() { - m_graph->theme()->setLabelBackgroundEnabled(!m_graph->theme()->isLabelBackgroundEnabled()); + m_graph->activeTheme()->setLabelBackgroundEnabled(!m_graph->activeTheme()->isLabelBackgroundEnabled()); } void ScatterDataModifier::changeFont(const QFont &font) { QFont newFont = font; newFont.setPointSizeF(m_fontSize); - m_graph->theme()->setFont(newFont); + m_graph->activeTheme()->setFont(newFont); } void ScatterDataModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq) @@ -173,12 +177,12 @@ void ScatterDataModifier::changeShadowQuality(int quality) void ScatterDataModifier::setBackgroundEnabled(int enabled) { - m_graph->theme()->setBackgroundEnabled((bool)enabled); + m_graph->activeTheme()->setBackgroundEnabled((bool)enabled); } void ScatterDataModifier::setGridEnabled(int enabled) { - m_graph->theme()->setGridEnabled((bool)enabled); + m_graph->activeTheme()->setGridEnabled((bool)enabled); } //! [8] diff --git a/examples/surface/doc/src/surface.qdoc b/examples/surface/doc/src/surface.qdoc index 6f49a3dc..dd334d01 100644 --- a/examples/surface/doc/src/surface.qdoc +++ b/examples/surface/doc/src/surface.qdoc @@ -124,7 +124,7 @@ Q3DSurface supports all the themes Qt Data Visualization has. The example has a pull down menu for selecting the theme. The following method is connected to the - menu to activate the selected theme. + menu to activate the selected theme. The old theme is released and deleted: \snippet ../examples/surface/surfacegraph.cpp 6 diff --git a/examples/surface/surfacegraph.cpp b/examples/surface/surfacegraph.cpp index 7ebb6b72..3770906e 100644 --- a/examples/surface/surfacegraph.cpp +++ b/examples/surface/surfacegraph.cpp @@ -229,7 +229,10 @@ void SurfaceGraph::setAxisZRange(float min, float max) //! [6] void SurfaceGraph::changeTheme(int theme) { - m_graph->setTheme(new Q3DTheme(Q3DTheme::Theme(theme))); + Q3DTheme *currentTheme = m_graph->activeTheme(); + m_graph->releaseTheme(currentTheme); + delete currentTheme; + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::Theme(theme))); } //! [6] 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<Q3DTheme *> 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<Q3DTheme *> 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(), @@ -272,23 +270,6 @@ bool Q3DBars::isBarSpacingRelative() } /*! - * \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 * * Sets bar selection \a mode to a combination of \c QDataVis::SelectionFlags. It is preset to 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 <QtDataVisualization/qdatavisualizationenums.h> #include <QtDataVisualization/q3dwindow.h> -#include <QtDataVisualization/q3dtheme.h> #include <QFont> #include <QLinearGradient> @@ -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<QBar3DSeries *> 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(), @@ -192,23 +190,6 @@ const Q3DScatterPrivate *Q3DScatter::dptrc() const } /*! - * \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 * * Sets item selection \a mode to a combination of \c QDataVis::SelectionFlags. It is preset to 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 <QtDataVisualization/qdatavisualizationenums.h> #include <QtDataVisualization/q3dwindow.h> #include <QtDataVisualization/q3dscene.h> -#include <QtDataVisualization/q3dtheme.h> #include <QFont> #include <QLinearGradient> @@ -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<QScatter3DSeries *> 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(), @@ -205,23 +203,6 @@ const Q3DSurfacePrivate *Q3DSurface::dptrc() const } /*! - * \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 * * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to 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<QSurface3DSeries *> 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(); } @@ -149,6 +153,62 @@ QAbstract3DInputHandler *Q3DWindow::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<Q3DTheme *> Q3DWindow::themes() const +{ + return d_ptr->m_visualController->themes(); +} + +/*! * \internal */ bool Q3DWindow::event(QEvent *event) 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<Q3DTheme *> themes() const; + protected: bool event(QEvent *event); void resizeEvent(QResizeEvent *event); void exposeEvent(QExposeEvent *event); +signals: + void activeThemeChanged(Q3DTheme *theme); + private: QScopedPointer<Q3DWindowPrivate> 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<ThemeManager *>(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<Q3DTheme *> 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<QColor> &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<QLinearGradient> &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<Q3DTheme *> themes() const; protected: void connectThemeSignals(); @@ -72,7 +75,8 @@ protected: void setColorStyle(Q3DTheme::ColorStyle style); private: - QScopedPointer<Q3DTheme> m_theme; + Q3DTheme *m_activeTheme; + QList<Q3DTheme *> m_themes; // List of all added themes Abstract3DController *m_controller; }; diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp index 587ea879..b9f26938 100644 --- a/src/datavisualizationqml2/abstractdeclarative.cpp +++ b/src/datavisualizationqml2/abstractdeclarative.cpp @@ -43,12 +43,12 @@ Q3DScene* AbstractDeclarative::scene() const void AbstractDeclarative::setTheme(Q3DTheme *theme) { - m_controller->setTheme(theme); + m_controller->setActiveTheme(theme); } Q3DTheme *AbstractDeclarative::theme() const { - return m_controller->theme(); + return m_controller->activeTheme(); } void AbstractDeclarative::setSelectionMode(QDataVis::SelectionFlags mode) @@ -79,7 +79,7 @@ void AbstractDeclarative::setSharedController(Abstract3DController *controller) &AbstractDeclarative::shadowQualityChanged); QObject::connect(m_controller, &Abstract3DController::activeInputHandlerChanged, this, &AbstractDeclarative::inputHandlerChanged); - QObject::connect(m_controller, &Abstract3DController::themeChanged, this, + QObject::connect(m_controller, &Abstract3DController::activeThemeChanged, this, &AbstractDeclarative::themeChanged); QObject::connect(m_controller, &Abstract3DController::selectionModeChanged, this, &AbstractDeclarative::selectionModeChanged); diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp index 8bef7479..5c36607e 100644 --- a/tests/barstest/chart.cpp +++ b/tests/barstest/chart.cpp @@ -63,7 +63,8 @@ GraphModifier::GraphModifier(Q3DBars *barchart, QColorDialog *colorDialog) m_currentAxis(m_fixedRangeAxis), m_negativeValuesOn(false), m_useNullInputHandler(false), - m_defaultInputHandler(0) + m_defaultInputHandler(0), + m_ownTheme(0) { // Generate generic labels QStringList genericColumnLabels; @@ -116,7 +117,7 @@ GraphModifier::GraphModifier(Q3DBars *barchart, QColorDialog *colorDialog) m_graph->addAxis(m_genericRowAxis); m_graph->addAxis(m_genericColumnAxis); - m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)); + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)); m_graph->setShadowQuality(QDataVis::ShadowQualitySoftMedium); m_temperatureData->setItemLabelFormat(QStringLiteral("1: @valueTitle for @colLabel @rowLabel: @valueLabel")); @@ -166,7 +167,7 @@ GraphModifier::GraphModifier(Q3DBars *barchart, QColorDialog *colorDialog) m_temperatureData->setSingleHighlightGradient(singleHighlightGradient); m_temperatureData->setMultiHighlightGradient(multiHighlightGradient); - m_graph->theme()->setFont(QFont("Times Roman", 20)); + m_graph->activeTheme()->setFont(QFont("Times Roman", 20)); // Release and store the default input handler. m_defaultInputHandler = m_graph->activeInputHandler(); @@ -576,7 +577,12 @@ void GraphModifier::changeTheme() { static int theme = Q3DTheme::ThemeQt; - m_graph->setTheme(new Q3DTheme((Q3DTheme::Theme)theme)); + Q3DTheme *currentTheme = m_graph->activeTheme(); + if (currentTheme != m_ownTheme) { + m_graph->releaseTheme(currentTheme); + delete currentTheme; + } + m_graph->setActiveTheme(new Q3DTheme((Q3DTheme::Theme)theme)); switch (theme) { case Q3DTheme::ThemeQt: @@ -614,7 +620,7 @@ void GraphModifier::changeTheme() void GraphModifier::changeLabelStyle() { - m_graph->theme()->setLabelBackgroundEnabled(!m_graph->theme()->isLabelBackgroundEnabled()); + m_graph->activeTheme()->setLabelBackgroundEnabled(!m_graph->activeTheme()->isLabelBackgroundEnabled()); } void GraphModifier::changeSelectionMode() @@ -631,15 +637,15 @@ void GraphModifier::changeFont(const QFont &font) { QFont newFont = font; newFont.setPointSize(m_fontSize); - m_graph->theme()->setFont(newFont); + m_graph->activeTheme()->setFont(newFont); } void GraphModifier::changeFontSize(int fontsize) { m_fontSize = fontsize; - QFont font = m_graph->theme()->font(); + QFont font = m_graph->activeTheme()->font(); font.setPointSize(m_fontSize); - m_graph->theme()->setFont(font); + m_graph->activeTheme()->setFont(font); } void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq) @@ -737,12 +743,12 @@ QBarDataArray *GraphModifier::makeDummyData() void GraphModifier::setBackgroundEnabled(int enabled) { - m_graph->theme()->setBackgroundEnabled(bool(enabled)); + m_graph->activeTheme()->setBackgroundEnabled(bool(enabled)); } void GraphModifier::setGridEnabled(int enabled) { - m_graph->theme()->setGridEnabled(bool(enabled)); + m_graph->activeTheme()->setGridEnabled(bool(enabled)); } void GraphModifier::rotateX(int rotation) @@ -811,38 +817,46 @@ void GraphModifier::setMaxY(int max) void GraphModifier::changeColorStyle() { - int style = m_graph->theme()->colorStyle(); + int style = m_graph->activeTheme()->colorStyle(); if (++style > Q3DTheme::ColorStyleRangeGradient) style = Q3DTheme::ColorStyleUniform; - m_graph->theme()->setColorStyle(Q3DTheme::ColorStyle(style)); + m_graph->activeTheme()->setColorStyle(Q3DTheme::ColorStyle(style)); } void GraphModifier::useOwnTheme() { - Q3DTheme *theme = new Q3DTheme(); - theme->setBackgroundEnabled(true); - theme->setGridEnabled(true); - theme->setAmbientLightStrength(0.3f); - theme->setBackgroundColor(QColor(QRgb(0x99ca53))); - QList<QColor> colors; - colors.append(QColor(QRgb(0x209fdf))); - theme->setBaseColors(colors); - theme->setColorStyle(Q3DTheme::ColorStyleUniform); - theme->setGridLineColor(QColor(QRgb(0x99ca53))); - theme->setHighlightLightStrength(7.0f); - theme->setLabelBackgroundEnabled(true); - theme->setLabelBorderEnabled(true); - theme->setLightColor(Qt::white); - theme->setLightStrength(6.0f); - theme->setMultiHighlightColor(QColor(QRgb(0x6d5fd5))); - theme->setSingleHighlightColor(QColor(QRgb(0xf6a625))); - theme->setLabelBackgroundColor(QColor(0xf6, 0xa6, 0x25, 0xa0)); - theme->setLabelTextColor(QColor(QRgb(0x404044))); - theme->setWindowColor(QColor(QRgb(0xffffff))); - - m_graph->setTheme(theme); + // Own theme is persistent, any changes to it via UI will be remembered + if (!m_ownTheme) { + m_ownTheme = new Q3DTheme(); + m_ownTheme->setBackgroundEnabled(true); + m_ownTheme->setGridEnabled(true); + m_ownTheme->setAmbientLightStrength(0.3f); + m_ownTheme->setBackgroundColor(QColor(QRgb(0x99ca53))); + QList<QColor> colors; + colors.append(QColor(QRgb(0x209fdf))); + m_ownTheme->setBaseColors(colors); + m_ownTheme->setColorStyle(Q3DTheme::ColorStyleUniform); + m_ownTheme->setGridLineColor(QColor(QRgb(0x99ca53))); + m_ownTheme->setHighlightLightStrength(7.0f); + m_ownTheme->setLabelBackgroundEnabled(true); + m_ownTheme->setLabelBorderEnabled(true); + m_ownTheme->setLightColor(Qt::white); + m_ownTheme->setLightStrength(6.0f); + m_ownTheme->setMultiHighlightColor(QColor(QRgb(0x6d5fd5))); + m_ownTheme->setSingleHighlightColor(QColor(QRgb(0xf6a625))); + m_ownTheme->setLabelBackgroundColor(QColor(0xf6, 0xa6, 0x25, 0xa0)); + m_ownTheme->setLabelTextColor(QColor(QRgb(0x404044))); + m_ownTheme->setWindowColor(QColor(QRgb(0xffffff))); + } + + Q3DTheme *currentTheme = m_graph->activeTheme(); + if (currentTheme != m_ownTheme) { + m_graph->releaseTheme(currentTheme); + delete currentTheme; + } + m_graph->setActiveTheme(m_ownTheme); m_colorDialog->open(); } @@ -852,7 +866,7 @@ void GraphModifier::changeBaseColor(const QColor &color) qDebug() << "base color changed to" << color; QList<QColor> colors; colors.append(color); - m_graph->theme()->setBaseColors(colors); + m_graph->activeTheme()->setBaseColors(colors); } void GraphModifier::setGradient() @@ -883,9 +897,9 @@ void GraphModifier::setGradient() QList<QLinearGradient> barGradients; barGradients.append(barGradient); - m_graph->theme()->setBaseGradients(barGradients); - m_graph->theme()->setSingleHighlightGradient(singleHighlightGradient); - m_graph->theme()->setMultiHighlightGradient(multiHighlightGradient); + m_graph->activeTheme()->setBaseGradients(barGradients); + m_graph->activeTheme()->setSingleHighlightGradient(singleHighlightGradient); + m_graph->activeTheme()->setMultiHighlightGradient(multiHighlightGradient); - m_graph->theme()->setColorStyle(Q3DTheme::ColorStyleObjectGradient); + m_graph->activeTheme()->setColorStyle(Q3DTheme::ColorStyleObjectGradient); } diff --git a/tests/barstest/chart.h b/tests/barstest/chart.h index 96038b9f..3948ca8f 100644 --- a/tests/barstest/chart.h +++ b/tests/barstest/chart.h @@ -129,6 +129,7 @@ private: bool m_negativeValuesOn; bool m_useNullInputHandler; QAbstract3DInputHandler *m_defaultInputHandler; + Q3DTheme *m_ownTheme; }; #endif diff --git a/tests/multigraphs/data.cpp b/tests/multigraphs/data.cpp index 99354caf..177d86b7 100644 --- a/tests/multigraphs/data.cpp +++ b/tests/multigraphs/data.cpp @@ -45,15 +45,15 @@ Data::Data(Q3DSurface *surface, Q3DScatter *scatter, Q3DBars *bars, m_started(false) { // Initialize surface - m_surface->setTheme(new Q3DTheme(Q3DTheme::ThemeIsabelle)); + m_surface->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeIsabelle)); QLinearGradient gradient; gradient.setColorAt(0.0, Qt::black); gradient.setColorAt(0.33, Qt::blue); gradient.setColorAt(0.67, Qt::red); gradient.setColorAt(1.0, Qt::yellow); m_surface->setSelectionMode(QDataVis::SelectionNone); - m_surface->theme()->setGridEnabled(false); - m_surface->theme()->setBackgroundEnabled(false); + m_surface->activeTheme()->setGridEnabled(false); + m_surface->activeTheme()->setBackgroundEnabled(false); m_surface->scene()->activeCamera()->setCameraPosition(0.0, 90.0, 150); QSurface3DSeries *series1 = new QSurface3DSeries(new QHeightMapSurfaceDataProxy()); series1->setFlatShadingEnabled(true); @@ -63,9 +63,9 @@ Data::Data(Q3DSurface *surface, Q3DScatter *scatter, Q3DBars *bars, m_surface->addSeries(series1); // Initialize scatter - m_scatter->setTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)); + m_scatter->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)); m_scatter->setSelectionMode(QDataVis::SelectionNone); - m_scatter->theme()->setGridEnabled(false); + m_scatter->activeTheme()->setGridEnabled(false); m_scatter->setShadowQuality(QDataVis::ShadowQualitySoftLow); m_scatter->scene()->activeCamera()->setCameraPosition(0.0, 85.0, 150); QScatter3DSeries *series2 = new QScatter3DSeries; @@ -73,9 +73,9 @@ Data::Data(Q3DSurface *surface, Q3DScatter *scatter, Q3DBars *bars, m_scatter->addSeries(series2); // Initialize bars - m_bars->setTheme(new Q3DTheme(Q3DTheme::ThemeQt)); + m_bars->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeQt)); m_bars->setSelectionMode(QDataVis::SelectionItemAndRow | QDataVis::SelectionSlice); - m_bars->theme()->setGridEnabled(false); + m_bars->activeTheme()->setGridEnabled(false); m_bars->setShadowQuality(QDataVis::ShadowQualityLow); m_bars->setBarSpacing(QSizeF(0.0, 0.0)); m_bars->scene()->activeCamera()->setCameraPosition(0.0, 75.0, 150); @@ -185,24 +185,32 @@ void Data::scrollDown() void Data::useGradientOne() { - m_surface->setTheme(new Q3DTheme(Q3DTheme::ThemeIsabelle)); + Q3DTheme *currentTheme = m_surface->activeTheme(); + m_surface->releaseTheme(currentTheme); + delete currentTheme; + m_surface->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeIsabelle)); QLinearGradient gradient; gradient.setColorAt(0.0, Qt::black); gradient.setColorAt(0.33, Qt::blue); gradient.setColorAt(0.67, Qt::red); gradient.setColorAt(1.0, Qt::yellow); m_surface->seriesList().at(0)->setBaseGradient(gradient); + m_surface->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient); m_statusArea->append(QStringLiteral("<b>Colors:</b> Thermal image imitation")); } void Data::useGradientTwo() { - m_surface->setTheme(new Q3DTheme(Q3DTheme::ThemeQt)); + Q3DTheme *currentTheme = m_surface->activeTheme(); + m_surface->releaseTheme(currentTheme); + delete currentTheme; + m_surface->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeQt)); QLinearGradient gradient; gradient.setColorAt(0.0, Qt::white); gradient.setColorAt(0.8, Qt::red); gradient.setColorAt(1.0, Qt::green); m_surface->seriesList().at(0)->setBaseGradient(gradient); + m_surface->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient); m_statusArea->append(QStringLiteral("<b>Colors:</b> Highlight foreground")); } diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp index b1df526a..10f48465 100644 --- a/tests/scattertest/scatterchart.cpp +++ b/tests/scattertest/scatterchart.cpp @@ -37,10 +37,10 @@ ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter) m_selectedItem(-1), m_targetSeries(0) { - m_chart->setTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)); - QFont font = m_chart->theme()->font(); + m_chart->setActiveTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)); + QFont font = m_chart->activeTheme()->font(); font.setPointSize(m_fontSize); - m_chart->theme()->setFont(font); + m_chart->activeTheme()->setFont(font); m_chart->setShadowQuality(QDataVis::ShadowQualityNone); m_chart->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront); m_chart->setAxisX(new Q3DValueAxis); @@ -161,7 +161,10 @@ void ScatterDataModifier::changeTheme() { static int theme = Q3DTheme::ThemeQt; - m_chart->setTheme(new Q3DTheme(Q3DTheme::Theme(theme))); + Q3DTheme *currentTheme = m_chart->activeTheme(); + m_chart->releaseTheme(currentTheme); + delete currentTheme; + m_chart->setActiveTheme(new Q3DTheme(Q3DTheme::Theme(theme))); if (++theme > Q3DTheme::ThemeIsabelle) theme = Q3DTheme::ThemeQt; @@ -169,22 +172,22 @@ void ScatterDataModifier::changeTheme() void ScatterDataModifier::changeLabelStyle() { - m_chart->theme()->setLabelBackgroundEnabled(!m_chart->theme()->isLabelBackgroundEnabled()); + m_chart->activeTheme()->setLabelBackgroundEnabled(!m_chart->activeTheme()->isLabelBackgroundEnabled()); } void ScatterDataModifier::changeFont(const QFont &font) { QFont newFont = font; newFont.setPointSizeF(m_fontSize); - m_chart->theme()->setFont(newFont); + m_chart->activeTheme()->setFont(newFont); } void ScatterDataModifier::changeFontSize(int fontSize) { m_fontSize = fontSize; - QFont font = m_chart->theme()->font(); + QFont font = m_chart->activeTheme()->font(); font.setPointSize(m_fontSize); - m_chart->theme()->setFont(font); + m_chart->activeTheme()->setFont(font); } void ScatterDataModifier::changePointSize(int pointSize) @@ -470,12 +473,12 @@ void ScatterDataModifier::changeShadowQuality(int quality) void ScatterDataModifier::setBackgroundEnabled(int enabled) { - m_chart->theme()->setBackgroundEnabled((bool)enabled); + m_chart->activeTheme()->setBackgroundEnabled((bool)enabled); } void ScatterDataModifier::setGridEnabled(int enabled) { - m_chart->theme()->setGridEnabled((bool)enabled); + m_chart->activeTheme()->setGridEnabled((bool)enabled); } QVector3D ScatterDataModifier::randVector() diff --git a/tests/spectrum/spectrumapp/main.cpp b/tests/spectrum/spectrumapp/main.cpp index 311de719..92965c1c 100644 --- a/tests/spectrum/spectrumapp/main.cpp +++ b/tests/spectrum/spectrumapp/main.cpp @@ -74,7 +74,7 @@ MainApp::MainApp(Q3DBars *window) m_chart->rowAxis()->setMax(SpectrumNumBands * 2); m_chart->columnAxis()->setMax(SpectrumNumBands - 1); // Disable grid - m_chart->theme()->setGridEnabled(false); + m_chart->activeTheme()->setGridEnabled(false); // Disable auto-scaling of height by defining explicit range m_chart->valueAxis()->setRange(0.0f, 1.0f); // Disable shadows diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp index 3474b67f..749b1c69 100644 --- a/tests/surfacetest/graphmodifier.cpp +++ b/tests/surfacetest/graphmodifier.cpp @@ -338,12 +338,12 @@ void GraphModifier::changeFont(const QFont &font) { QFont newFont = font; newFont.setPointSizeF(m_fontSize); - m_graph->theme()->setFont(newFont); + m_graph->activeTheme()->setFont(newFont); } void GraphModifier::changeStyle() { - m_graph->theme()->setLabelBackgroundEnabled(!m_graph->theme()->isLabelBackgroundEnabled()); + m_graph->activeTheme()->setLabelBackgroundEnabled(!m_graph->activeTheme()->isLabelBackgroundEnabled()); } void GraphModifier::selectButtonClicked() @@ -363,7 +363,10 @@ void GraphModifier::selectedPointChanged(const QPoint &point) void GraphModifier::changeTheme(int theme) { - m_graph->setTheme(new Q3DTheme(Q3DTheme::Theme(theme))); + Q3DTheme *currentTheme = m_graph->activeTheme(); + m_graph->releaseTheme(currentTheme); + delete currentTheme; + m_graph->setActiveTheme(new Q3DTheme(Q3DTheme::Theme(theme))); } diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp index c25c5b89..5a26c7ce 100644 --- a/tests/surfacetest/main.cpp +++ b/tests/surfacetest/main.cpp @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) QSize screenSize = surfaceGraph->screen()->size(); // Set to default, should be same as the initial on themeList - surfaceGraph->setTheme(new Q3DTheme(Q3DTheme::Theme(initialTheme))); + surfaceGraph->setActiveTheme(new Q3DTheme(Q3DTheme::Theme(initialTheme))); QWidget *container = QWidget::createWindowContainer(surfaceGraph); container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2)); |