diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-08-29 15:51:57 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-08-30 07:52:05 +0300 |
commit | a88922ed813f6f0510fc13c6a5ff999a4e51b4d3 (patch) | |
tree | 918519ba9895e3e30b7e50f89e5c0abe5d9fa0f5 /src | |
parent | 1f9a6ca62c282658ae1f76a59e521cd99a280ba5 (diff) |
Improved the ownership handling of data proxies and axes.
Task-number: QTRD-2212
Change-Id: Ie55e5c2765e28f1b31915f12eb952dbb5260047f
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/datavis3d/data/qabstractdataproxy.cpp | 3 | ||||
-rw-r--r-- | src/datavis3d/data/qabstractdataproxy.h | 4 | ||||
-rw-r--r-- | src/datavis3d/data/qabstractdataproxy_p.h | 4 | ||||
-rw-r--r-- | src/datavis3d/engine/abstract3dcontroller.cpp | 76 | ||||
-rw-r--r-- | src/datavis3d/engine/abstract3dcontroller_p.h | 10 | ||||
-rw-r--r-- | src/datavis3d/engine/bars3dcontroller.cpp | 51 | ||||
-rw-r--r-- | src/datavis3d/engine/bars3dcontroller_p.h | 6 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dbars.cpp | 90 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dbars.h | 7 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dscatter.cpp | 92 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dscatter.h | 7 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dsurface.cpp | 24 | ||||
-rw-r--r-- | src/datavis3d/engine/scatter3dcontroller.cpp | 42 | ||||
-rw-r--r-- | src/datavis3d/engine/scatter3dcontroller_p.h | 5 | ||||
-rw-r--r-- | src/datavis3dqml2/declarativebars.cpp | 14 | ||||
-rw-r--r-- | src/datavis3dqml2/declarativescatter.cpp | 14 |
16 files changed, 325 insertions, 124 deletions
diff --git a/src/datavis3d/data/qabstractdataproxy.cpp b/src/datavis3d/data/qabstractdataproxy.cpp index e155a551..187fa518 100644 --- a/src/datavis3d/data/qabstractdataproxy.cpp +++ b/src/datavis3d/data/qabstractdataproxy.cpp @@ -102,7 +102,8 @@ QString QAbstractDataProxy::itemLabelFormat() const QAbstractDataProxyPrivate::QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type) : QObject(0), q_ptr(q), - m_type(type) + m_type(type), + m_isDefaultProxy(false) { } diff --git a/src/datavis3d/data/qabstractdataproxy.h b/src/datavis3d/data/qabstractdataproxy.h index 33ce9f9c..50817a07 100644 --- a/src/datavis3d/data/qabstractdataproxy.h +++ b/src/datavis3d/data/qabstractdataproxy.h @@ -61,6 +61,10 @@ protected: private: Q_DISABLE_COPY(QAbstractDataProxy) + + friend class Abstract3DController; + friend class Bars3dController; + friend class Scatter3DController; }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qabstractdataproxy_p.h b/src/datavis3d/data/qabstractdataproxy_p.h index eda13b86..6737c681 100644 --- a/src/datavis3d/data/qabstractdataproxy_p.h +++ b/src/datavis3d/data/qabstractdataproxy_p.h @@ -44,10 +44,14 @@ public: void setItemLabelFormat(const QString &format); + inline bool isDefaultProxy() { return m_isDefaultProxy; } + inline void setDefaultProxy(bool isDefault) { m_isDefaultProxy = isDefault; } + protected: QAbstractDataProxy *q_ptr; QAbstractDataProxy::DataType m_type; QString m_itemLabelFormat; + bool m_isDefaultProxy; private: friend class QAbstractDataProxy; diff --git a/src/datavis3d/engine/abstract3dcontroller.cpp b/src/datavis3d/engine/abstract3dcontroller.cpp index 06d81021..ae6501df 100644 --- a/src/datavis3d/engine/abstract3dcontroller.cpp +++ b/src/datavis3d/engine/abstract3dcontroller.cpp @@ -22,6 +22,7 @@ #include "qvalueaxis.h" #include "qcategoryaxis.h" #include "abstract3drenderer_p.h" +#include "qabstractdataproxy_p.h" #if defined(Q_OS_ANDROID) #include "qtouch3dinputhandler.h" @@ -50,7 +51,8 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : m_axisY(0), m_axisZ(0), m_renderer(0), - m_isDataDirty(true) + m_isDataDirty(true), + m_data(0) { m_theme.useColorTheme(QDataVis::ThemeSystem); #if defined(Q_OS_ANDROID) @@ -383,8 +385,6 @@ void Abstract3DController::setAxisX(QAbstractAxis *axis) QAbstractAxis *Abstract3DController::axisX() { - if (m_axisX->d_ptr->isDefaultAxis()) - return 0; return m_axisX; } @@ -395,8 +395,6 @@ void Abstract3DController::setAxisY(QAbstractAxis *axis) QAbstractAxis *Abstract3DController::axisY() { - if (m_axisY->d_ptr->isDefaultAxis()) - return 0; return m_axisY; } @@ -407,8 +405,6 @@ void Abstract3DController::setAxisZ(QAbstractAxis *axis) QAbstractAxis *Abstract3DController::axisZ() { - if (m_axisZ->d_ptr->isDefaultAxis()) - return 0; return m_axisZ; } @@ -427,6 +423,10 @@ void Abstract3DController::addAxis(QAbstractAxis *axis) void Abstract3DController::releaseAxis(QAbstractAxis *axis) { if (axis && m_axes.contains(axis)) { + // Clear the default status from released default axes + if (axis->d_ptr->isDefaultAxis()) + axis->d_ptr->setDefaultAxis(false); + // If the axis is in use, replace it with a temporary one switch (axis->orientation()) { case QAbstractAxis::AxisOrientationX: @@ -449,13 +449,63 @@ void Abstract3DController::releaseAxis(QAbstractAxis *axis) QList<QAbstractAxis *> Abstract3DController::axes() const { - QList<QAbstractAxis *> retList; - foreach (QAbstractAxis *axis, m_axes) { - if (!axis->d_ptr->isDefaultAxis()) - retList.append(axis); + return m_axes; +} + +QAbstractDataProxy *Abstract3DController::activeDataProxy() const +{ + return m_data; +} + +void Abstract3DController::addDataProxy(QAbstractDataProxy *proxy) +{ + Q_ASSERT(proxy); + Abstract3DController *owner = qobject_cast<Abstract3DController *>(proxy->parent()); + if (owner != this) { + Q_ASSERT_X(!owner, "addDataProxy", "Proxy already attached to a graph."); + proxy->setParent(this); + } + if (!m_dataProxies.contains(proxy)) + m_dataProxies.append(proxy); +} + +void Abstract3DController::releaseDataProxy(QAbstractDataProxy *proxy) +{ + if (proxy && m_dataProxies.contains(proxy)) { + // Clear the default status from released default proxies + if (proxy->d_ptr->isDefaultProxy()) + proxy->d_ptr->setDefaultProxy(false); + + // If the proxy is in use, replace it with a temporary one + if (m_data == proxy) + setActiveDataProxy(0); + + m_dataProxies.removeAll(proxy); + proxy->setParent(0); + } +} + +QList<QAbstractDataProxy *> Abstract3DController::dataProxies() const +{ + return m_dataProxies; +} + +void Abstract3DController::setActiveDataProxy(QAbstractDataProxy *proxy) +{ + // If existing proxy is the default proxy, delete it + if (m_data) { + if (m_data->d_ptr->isDefaultProxy()) { + m_dataProxies.removeAll(m_data); + delete m_data; + } else { + // Disconnect the old proxy from use + QObject::disconnect(m_data, 0, this, 0); + } } - return retList; + // Assume ownership and activate + addDataProxy(proxy); + m_data = proxy; } int Abstract3DController::zoomLevel() @@ -729,7 +779,7 @@ void Abstract3DController::setAxisHelper(QAbstractAxis::AxisOrientation orientat QAbstractAxis *axis, QAbstractAxis **axisPtr) { // Setting null axis indicates using default axis - if (axis == 0) + if (!axis) axis = createDefaultAxis(orientation); // If old axis is default axis, delete it diff --git a/src/datavis3d/engine/abstract3dcontroller_p.h b/src/datavis3d/engine/abstract3dcontroller_p.h index 3123a5d7..81775f9d 100644 --- a/src/datavis3d/engine/abstract3dcontroller_p.h +++ b/src/datavis3d/engine/abstract3dcontroller_p.h @@ -36,6 +36,7 @@ #include "qabstractaxis.h" #include "drawer_p.h" #include "qabstract3dinputhandler.h" +#include "qabstractdataproxy.h" class QFont; @@ -165,6 +166,9 @@ protected: Abstract3DRenderer *m_renderer; bool m_isDataDirty; + QAbstractDataProxy *m_data; + QList<QAbstractDataProxy *> m_dataProxies; + explicit Abstract3DController(QRect boundRect, QObject *parent = 0); ~Abstract3DController(); @@ -208,6 +212,12 @@ public: virtual void releaseAxis(QAbstractAxis *axis); virtual QList<QAbstractAxis *> axes() const; // Omits default axes + virtual QAbstractDataProxy *activeDataProxy() const; + virtual void addDataProxy(QAbstractDataProxy *proxy); + virtual void releaseDataProxy(QAbstractDataProxy *proxy); + virtual QList<QAbstractDataProxy *> dataProxies() const; + virtual void setActiveDataProxy(QAbstractDataProxy *proxy); + virtual int zoomLevel(); virtual void setZoomLevel(int zoomLevel); diff --git a/src/datavis3d/engine/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp index 36a00319..26bc585f 100644 --- a/src/datavis3d/engine/bars3dcontroller.cpp +++ b/src/datavis3d/engine/bars3dcontroller.cpp @@ -41,13 +41,12 @@ Bars3dController::Bars3dController(QRect boundRect) m_isBarSpecRelative(true), m_barThicknessRatio(1.0f), m_barSpacing(QSizeF(1.0, 1.0)), - m_renderer(0), - m_data(0) + m_renderer(0) { // Default bar type; specific to bars setBarType(QDataVis::Bars, false); - setDataProxy(new QBarDataProxy); + setActiveDataProxy(0); // Setting a null axis creates a new default axis according to orientation and chart type. // Note: These cannot be set in Abstract3DController constructor, as they will call virtual @@ -59,7 +58,6 @@ Bars3dController::Bars3dController(QRect boundRect) Bars3dController::~Bars3dController() { - delete m_data; } void Bars3dController::initializeOpenGL() @@ -105,7 +103,7 @@ void Bars3dController::synchDataToRenderer() } if (m_isDataDirty) { - m_renderer->updateDataModel(m_data); + m_renderer->updateDataModel(static_cast<QBarDataProxy *>(m_data)); m_isDataDirty = false; } } @@ -258,22 +256,31 @@ void Bars3dController::wheelEvent(QWheelEvent *event) setZoomLevel(zoomLevel); } -void Bars3dController::setDataProxy(QBarDataProxy *proxy) +void Bars3dController::setActiveDataProxy(QAbstractDataProxy *proxy) { - delete m_data; - m_data = proxy; + // Setting null proxy indicates default proxy + if (!proxy) { + proxy = new QBarDataProxy; + proxy->d_ptr->setDefaultProxy(true); + } + + Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeBar); + + Abstract3DController::setActiveDataProxy(proxy); + + QBarDataProxy *barDataProxy = static_cast<QBarDataProxy *>(m_data); - QObject::connect(m_data, &QBarDataProxy::arrayReset, this, + QObject::connect(barDataProxy, &QBarDataProxy::arrayReset, this, &Bars3dController::handleArrayReset); - QObject::connect(m_data, &QBarDataProxy::rowsAdded, this, + QObject::connect(barDataProxy, &QBarDataProxy::rowsAdded, this, &Bars3dController::handleRowsAdded); - QObject::connect(m_data, &QBarDataProxy::rowsChanged, this, + QObject::connect(barDataProxy, &QBarDataProxy::rowsChanged, this, &Bars3dController::handleRowsChanged); - QObject::connect(m_data, &QBarDataProxy::rowsRemoved, this, + QObject::connect(barDataProxy, &QBarDataProxy::rowsRemoved, this, &Bars3dController::handleRowsRemoved); - QObject::connect(m_data, &QBarDataProxy::rowsInserted, this, + QObject::connect(barDataProxy, &QBarDataProxy::rowsInserted, this, &Bars3dController::handleRowsInserted); - QObject::connect(m_data, &QBarDataProxy::itemChanged, this, + QObject::connect(barDataProxy, &QBarDataProxy::itemChanged, this, &Bars3dController::handleItemChanged); adjustValueAxisRange(); @@ -281,11 +288,6 @@ void Bars3dController::setDataProxy(QBarDataProxy *proxy) setSelectedBarPos(noSelectionPoint()); } -QBarDataProxy *Bars3dController::dataProxy() -{ - return m_data; -} - void Bars3dController::handleArrayReset() { setSlicingActive(false); @@ -326,7 +328,7 @@ void Bars3dController::handleRowsRemoved(int startIndex, int count) adjustValueAxisRange(); m_isDataDirty = true; // TODO this will break once data window offset is implemented - if (startIndex >= m_data->rowCount()) + if (startIndex >= static_cast<QBarDataProxy *>(m_data)->rowCount()) setSelectedBarPos(noSelectionPoint()); } @@ -453,8 +455,8 @@ void Bars3dController::setSelectedBarPos(const QPoint &position) // TODO this will break once data window offset is implemented QPoint pos = position; if (pos.x() < 0 || pos.y() < 0 - || pos.x() >= m_data->rowCount() - || pos.y() >= m_data->rowAt(pos.x())->size()) { + || pos.x() >= static_cast<QBarDataProxy *>(m_data)->rowCount() + || pos.y() >= static_cast<QBarDataProxy *>(m_data)->rowAt(pos.x())->size()) { pos = noSelectionPoint(); } @@ -489,8 +491,9 @@ void Bars3dController::adjustValueAxisRange() { QValueAxis *valueAxis = static_cast<QValueAxis *>(m_axisY); if (valueAxis && valueAxis->isAutoAdjustRange() && m_data) { - QPair<GLfloat, GLfloat> limits = m_data->dptr()->limitValues(0, m_rowCount, - 0, m_columnCount); + QPair<GLfloat, GLfloat> limits = + static_cast<QBarDataProxy *>(m_data)->dptr()->limitValues(0, m_rowCount, + 0, m_columnCount); if (limits.first < 0) { // TODO: Currently we only support symmetric y-axis for bar chart if there are negative values qreal maxAbs = qMax(qFabs(limits.first), qFabs(limits.second)); diff --git a/src/datavis3d/engine/bars3dcontroller_p.h b/src/datavis3d/engine/bars3dcontroller_p.h index bdff63b3..5ee5c214 100644 --- a/src/datavis3d/engine/bars3dcontroller_p.h +++ b/src/datavis3d/engine/bars3dcontroller_p.h @@ -78,7 +78,6 @@ private: // Rendering Bars3dRenderer *m_renderer; - QBarDataProxy *m_data; public: explicit Bars3dController(QRect rect); @@ -129,9 +128,8 @@ public: void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); void wheelEvent(QWheelEvent *event); - // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy. - void setDataProxy(QBarDataProxy *proxy); - QBarDataProxy *dataProxy(); + virtual void setActiveDataProxy(QAbstractDataProxy *proxy); + virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust); static QPoint noSelectionPoint(); diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp index 5c2cf0c8..a206a258 100644 --- a/src/datavis3d/engine/q3dbars.cpp +++ b/src/datavis3d/engine/q3dbars.cpp @@ -21,6 +21,7 @@ #include "bars3dcontroller_p.h" #include "qvalueaxis.h" #include "qcategoryaxis.h" +#include "qbardataproxy.h" #include <QMouseEvent> @@ -76,6 +77,14 @@ QT_DATAVIS3D_BEGIN_NAMESPACE * familiarizing yourself with the examples provided, like the \l{Rainfall Example} or * the \l{Widget Example}. * + * If no axes are explicitly set to Q3DBars, temporary default axes with no labels are created. + * These default axes can be modified via axis accessors, but as soon any axis is explicitly + * set for the orientation, the default axis for that orientation is destroyed. + * + * Data proxies work similarly: If no data proxy is explicitly set, Q3DBars creates a default + * proxy. If any other proxy is set as active data proxy later, the default proxy and all data + * added to it is destroyed. + * * \sa Q3DScatter, Q3DSurface, {Qt Data Visualization 3D C++ Classes} */ @@ -407,8 +416,8 @@ QDataVis::ShadowQuality Q3DBars::shadowQuality() const * Sets a user-defined row \a axis. Implicitly calls addAxis() to transfer ownership of * the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set row axis at all, a temporary - * default axis with no labels is used. + * If the \a axis is null, a temporary default axis with no labels is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -418,7 +427,7 @@ void Q3DBars::setRowAxis(QCategoryAxis *axis) } /*! - * \return category axis for rows. Returns null pointer if default axis is in use. + * \return category axis for rows. */ QCategoryAxis *Q3DBars::rowAxis() const { @@ -429,8 +438,8 @@ QCategoryAxis *Q3DBars::rowAxis() const * Sets a user-defined column \a axis. Implicitly calls addAxis() to transfer ownership of * the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set column axis at all, a temporary - * default axis with no labels is used. + * If the \a axis is null, a temporary default axis with no labels is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -440,7 +449,7 @@ void Q3DBars::setColumnAxis(QCategoryAxis *axis) } /*! - * \return category axis for columns. Returns null pointer if default axis is in use. + * \return category axis for columns. */ QCategoryAxis *Q3DBars::columnAxis() const { @@ -451,8 +460,9 @@ QCategoryAxis *Q3DBars::columnAxis() const * Sets a user-defined value \a axis (the Y-axis). Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set value axis at all, a temporary - * default axis with no labels and automatic range adjusting is used. + * If the \a axis is null, a temporary default axis with no labels and automatically adjusting + * range is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -462,7 +472,7 @@ void Q3DBars::setValueAxis(QValueAxis *axis) } /*! - * \return used value axis (Y-axis). Returns null pointer if default axis is in use. + * \return used value axis (Y-axis). */ QValueAxis *Q3DBars::valueAxis() const { @@ -483,7 +493,9 @@ void Q3DBars::addAxis(QAbstractAxis *axis) /*! * Releases the ownership of the \a axis back to the caller, if it is added to this graph. - * If the released \a axis is in use, a temporary default axis will be set active. + * If the released \a axis is in use, a new default axis will be created and set active. + * + * If the default axis is released and added back later, it behaves as any other axis would. * * \sa addAxis(), setValueAxis(), setRowAxis(), setColumnAxis() */ @@ -503,19 +515,65 @@ QList<QAbstractAxis *> Q3DBars::axes() const } /*! - * Sets a user-defined data \a proxy. Ownership of the proxy is transferred to Q3DBars. + * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of + * the \a proxy to this graph. + * + * If the \a proxy is null, a temporary default proxy is created and activated. + * This temporary proxy is destroyed if another \a proxy is explicitly set active via this method. + * + * \sa addDataProxy(), releaseDataProxy() */ -void Q3DBars::setDataProxy(QBarDataProxy *proxy) +void Q3DBars::setActiveDataProxy(QBarDataProxy *proxy) { - d_ptr->m_shared->setDataProxy(proxy); + d_ptr->m_shared->setActiveDataProxy(proxy); } /*! - * \return used data proxy. + * \return active data proxy. */ -QBarDataProxy *Q3DBars::dataProxy() +QBarDataProxy *Q3DBars::activeDataProxy() const { - return d_ptr->m_shared->dataProxy(); + return static_cast<QBarDataProxy *>(d_ptr->m_shared->activeDataProxy()); +} + +/*! + * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use, + * addDataProxy is simply used to give the ownership of the data \a proxy to the graph. + * The \a proxy must not be null or added to another graph. + * + * \sa releaseDataProxy(), setActiveDataProxy() + */ +void Q3DBars::addDataProxy(QBarDataProxy *proxy) +{ + d_ptr->m_shared->addDataProxy(proxy); +} + +/*! + * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph. + * If the released \a proxy is in use, a new empty default proxy is created and taken to use. + * + * If the default \a proxy is released and added back later, it behaves as any other proxy would. + * + * \sa addDataProxy(), setActiveDataProxy() + */ +void Q3DBars::releaseDataProxy(QBarDataProxy *proxy) +{ + d_ptr->m_shared->releaseDataProxy(proxy); +} + +/*! + * \return list of all added data proxies. + * + * \sa addDataProxy() + */ +QList<QBarDataProxy *> Q3DBars::dataProxies() const +{ + QList<QBarDataProxy *> retList; + QList<QAbstractDataProxy *> abstractList = d_ptr->m_shared->dataProxies(); + foreach (QAbstractDataProxy *proxy, abstractList) + retList.append(static_cast<QBarDataProxy *>(proxy)); + + return retList; } Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q, QRect rect) diff --git a/src/datavis3d/engine/q3dbars.h b/src/datavis3d/engine/q3dbars.h index b3e695d3..1792581e 100644 --- a/src/datavis3d/engine/q3dbars.h +++ b/src/datavis3d/engine/q3dbars.h @@ -104,8 +104,11 @@ public: void releaseAxis(QAbstractAxis *axis); QList<QAbstractAxis *> axes() const; - void setDataProxy(QBarDataProxy *proxy); - QBarDataProxy *dataProxy(); + void setActiveDataProxy(QBarDataProxy *proxy); + QBarDataProxy *activeDataProxy() const; + void addDataProxy(QBarDataProxy *proxy); + void releaseDataProxy(QBarDataProxy *proxy); + QList<QBarDataProxy *> dataProxies() const; signals: void shadowQualityChanged(QDataVis::ShadowQuality quality); diff --git a/src/datavis3d/engine/q3dscatter.cpp b/src/datavis3d/engine/q3dscatter.cpp index bd9a884f..f44d6c44 100644 --- a/src/datavis3d/engine/q3dscatter.cpp +++ b/src/datavis3d/engine/q3dscatter.cpp @@ -20,6 +20,7 @@ #include "q3dscatter_p.h" #include "scatter3dcontroller_p.h" #include "qvalueaxis.h" +#include "qscatterdataproxy.h" #include <QMouseEvent> @@ -68,6 +69,14 @@ QT_DATAVIS3D_BEGIN_NAMESPACE * code example. You can learn more by familiarizing yourself with the examples provided, like * the \l{Scatter Chart Example}. * + * If no axes are explicitly set to Q3DScatter, temporary default axes with no labels are created. + * These default axes can be modified via axis accessors, but as soon any axis is explicitly + * set for the orientation, the default axis for that orientation is destroyed. + * + * Data proxies work similarly: If no data proxy is explicitly set, Q3DScatter creates a default + * proxy. If any other proxy is set as active data proxy later, the default proxy and all data + * added to it is destroyed. + * * \sa Q3DBars, Q3DSurface, {Qt Data Visualization 3D C++ Classes} */ @@ -368,8 +377,9 @@ QDataVis::ShadowQuality Q3DScatter::shadowQuality() const * Sets a user-defined X-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set value axis at all, a temporary - * default axis with no labels and automatic range adjusting is used. + * If the \a axis is null, a temporary default axis with no labels and automatically adjusting + * range is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -379,7 +389,7 @@ void Q3DScatter::setAxisX(QValueAxis *axis) } /*! - * \return used X-axis. Returns null pointer if default axis is in use. + * \return used X-axis. */ QValueAxis *Q3DScatter::axisX() const { @@ -390,8 +400,9 @@ QValueAxis *Q3DScatter::axisX() const * Sets a user-defined Y-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set value axis at all, a temporary - * default axis with no labels and automatic range adjusting is used. + * If the \a axis is null, a temporary default axis with no labels and automatically adjusting + * range is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -401,7 +412,7 @@ void Q3DScatter::setAxisY(QValueAxis *axis) } /*! - * \return used Y-axis. Returns null pointer if default axis is in use. + * \return used Y-axis. */ QValueAxis *Q3DScatter::axisY() const { @@ -412,8 +423,9 @@ QValueAxis *Q3DScatter::axisY() const * Sets a user-defined Z-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set value axis at all, a temporary - * default axis with no labels and automatic range adjusting is used. + * If the \a axis is null, a temporary default axis with no labels and automatically adjusting + * range is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -423,7 +435,7 @@ void Q3DScatter::setAxisZ(QValueAxis *axis) } /*! - * \return used Z-axis. Returns null pointer if default axis is in use. + * \return used Z-axis. */ QValueAxis *Q3DScatter::axisZ() const { @@ -444,6 +456,9 @@ void Q3DScatter::addAxis(QValueAxis *axis) /*! * Releases the ownership of the \a axis back to the caller, if it is added to this graph. + * If the released \a axis is in use, a new default axis will be created and set active. + * + * If the default axis is released and added back later, it behaves as any other axis would. * * \sa addAxis(), setAxisX(), setAxisY(), setAxisZ() */ @@ -468,19 +483,65 @@ QList<QValueAxis *> Q3DScatter::axes() const } /*! - * Sets a user-defined data \a proxy. Ownership of the proxy is transferred to Q3DScatter. + * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of + * the \a proxy to this graph. + * + * If the \a proxy is null, a temporary default proxy is created and activated. + * This temporary proxy is destroyed if another \a proxy is explicitly set active via this method. + * + * \sa addDataProxy(), releaseDataProxy() + */ +void Q3DScatter::setActiveDataProxy(QScatterDataProxy *proxy) +{ + d_ptr->m_shared->setActiveDataProxy(proxy); +} + +/*! + * \return active data proxy. */ -void Q3DScatter::setDataProxy(QScatterDataProxy *proxy) +QScatterDataProxy *Q3DScatter::activeDataProxy() const { - d_ptr->m_shared->setDataProxy(proxy); + return static_cast<QScatterDataProxy *>(d_ptr->m_shared->activeDataProxy()); } /*! - * \return used data proxy. + * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use, + * addDataProxy is simply used to give the ownership of the data \a proxy to the graph. + * The \a proxy must not be null or added to another graph. + * + * \sa releaseDataProxy(), setActiveDataProxy() */ -QScatterDataProxy *Q3DScatter::dataProxy() +void Q3DScatter::addDataProxy(QScatterDataProxy *proxy) { - return d_ptr->m_shared->dataProxy(); + d_ptr->m_shared->addDataProxy(proxy); +} + +/*! + * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph. + * If the released \a proxy is in use, a new empty default proxy is created and taken to use. + * + * If the default \a proxy is released and added back later, it behaves as any other proxy would. + * + * \sa addDataProxy(), setActiveDataProxy() + */ +void Q3DScatter::releaseDataProxy(QScatterDataProxy *proxy) +{ + d_ptr->m_shared->releaseDataProxy(proxy); +} + +/*! + * \return list of all added data proxies. + * + * \sa addDataProxy() + */ +QList<QScatterDataProxy *> Q3DScatter::dataProxies() const +{ + QList<QScatterDataProxy *> retList; + QList<QAbstractDataProxy *> abstractList = d_ptr->m_shared->dataProxies(); + foreach (QAbstractDataProxy *proxy, abstractList) + retList.append(static_cast<QScatterDataProxy *>(proxy)); + + return retList; } /*! @@ -509,3 +570,4 @@ void Q3DScatterPrivate::handleShadowQualityUpdate(QDataVis::ShadowQuality qualit } QT_DATAVIS3D_END_NAMESPACE + diff --git a/src/datavis3d/engine/q3dscatter.h b/src/datavis3d/engine/q3dscatter.h index a432b101..79169545 100644 --- a/src/datavis3d/engine/q3dscatter.h +++ b/src/datavis3d/engine/q3dscatter.h @@ -96,8 +96,11 @@ public: void releaseAxis(QValueAxis *axis); QList<QValueAxis *> axes() const; - void setDataProxy(QScatterDataProxy *proxy); - QScatterDataProxy *dataProxy(); + void setActiveDataProxy(QScatterDataProxy *proxy); + QScatterDataProxy *activeDataProxy() const; + void addDataProxy(QScatterDataProxy *proxy); + void releaseDataProxy(QScatterDataProxy *proxy); + QList<QScatterDataProxy *> dataProxies() const; signals: void shadowQualityChanged(QDataVis::ShadowQuality quality); diff --git a/src/datavis3d/engine/q3dsurface.cpp b/src/datavis3d/engine/q3dsurface.cpp index 2201053d..c9d35a28 100644 --- a/src/datavis3d/engine/q3dsurface.cpp +++ b/src/datavis3d/engine/q3dsurface.cpp @@ -158,8 +158,9 @@ void Q3DSurface::setSegmentCount(int segmentCount, qreal step, qreal minimum) * Sets a user-defined X-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set value axis at all, a temporary - * default axis with no labels and automatic range adjusting is used. + * If the \a axis is null, a temporary default axis with no labels and automatically adjusting + * range is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -169,7 +170,7 @@ void Q3DSurface::setAxisX(QValueAxis *axis) } /*! - * \return used X-axis. Returns null pointer if default axis is in use. + * \return used X-axis. */ QValueAxis *Q3DSurface::axisX() const { @@ -180,8 +181,9 @@ QValueAxis *Q3DSurface::axisX() const * Sets a user-defined Y-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set value axis at all, a temporary - * default axis with no labels and automatic range adjusting is used. + * If the \a axis is null, a temporary default axis with no labels and automatically adjusting + * range is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -191,7 +193,7 @@ void Q3DSurface::setAxisY(QValueAxis *axis) } /*! - * \return used Y-axis. Returns null pointer if default axis is in use. + * \return used Y-axis. */ QValueAxis *Q3DSurface::axisY() const { @@ -202,8 +204,9 @@ QValueAxis *Q3DSurface::axisY() const * Sets a user-defined Z-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * - * If the \a axis is null, or if user doesn't explicitly set value axis at all, a temporary - * default axis with no labels and automatic range adjusting is used. + * If the \a axis is null, a temporary default axis with no labels and automatically adjusting + * range is created. + * This temporary axis is destroyed if another \a axis is explicitly set to same orientation. * * \sa addAxis(), releaseAxis() */ @@ -213,7 +216,7 @@ void Q3DSurface::setAxisZ(QValueAxis *axis) } /*! - * \return used Z-axis. Returns null pointer if default axis is in use. + * \return used Z-axis. */ QValueAxis *Q3DSurface::axisZ() const { @@ -234,6 +237,9 @@ void Q3DSurface::addAxis(QValueAxis *axis) /*! * Releases the ownership of the \a axis back to the caller, if it is added to this graph. + * If the released \a axis is in use, a new default axis will be created and set active. + * + * If the default axis is released and added back later, it behaves as any other axis would. * * \sa addAxis(), setAxisX(), setAxisY(), setAxisZ() */ diff --git a/src/datavis3d/engine/scatter3dcontroller.cpp b/src/datavis3d/engine/scatter3dcontroller.cpp index c5ed1fed..10fa1d14 100644 --- a/src/datavis3d/engine/scatter3dcontroller.cpp +++ b/src/datavis3d/engine/scatter3dcontroller.cpp @@ -35,13 +35,12 @@ Scatter3DController::Scatter3DController(QRect boundRect) m_mousePos(QPoint(0, 0)), m_isSlicingActivated(false), m_renderer(0), - m_data(0), m_selectedItemIndex(noSelectionIndex()) { // Default object type; specific to scatter setObjectType(QDataVis::Spheres, false); - setDataProxy(new QScatterDataProxy); + setActiveDataProxy(new QScatterDataProxy); // Setting a null axis creates a new default axis according to orientation and chart type. // Note: These cannot be set in Abstract3DController constructor, as they will call virtual @@ -53,7 +52,6 @@ Scatter3DController::Scatter3DController(QRect boundRect) Scatter3DController::~Scatter3DController() { - delete m_data; } void Scatter3DController::initializeOpenGL() @@ -89,7 +87,7 @@ void Scatter3DController::synchDataToRenderer() } if (m_isDataDirty) { - m_renderer->updateDataModel(m_data); + m_renderer->updateDataModel(static_cast<QScatterDataProxy *>(m_data)); m_isDataDirty = false; } } @@ -236,20 +234,29 @@ void Scatter3DController::wheelEvent(QWheelEvent *event) setZoomLevel(zoomLevel); } -void Scatter3DController::setDataProxy(QScatterDataProxy *proxy) +void Scatter3DController::setActiveDataProxy(QAbstractDataProxy *proxy) { - delete m_data; - m_data = proxy; + // Setting null proxy indicates default proxy + if (!proxy) { + proxy = new QScatterDataProxy; + proxy->d_ptr->setDefaultProxy(true); + } + + Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeScatter); + + Abstract3DController::setActiveDataProxy(proxy); + + QScatterDataProxy *scatterDataProxy = static_cast<QScatterDataProxy *>(m_data); - QObject::connect(m_data, &QScatterDataProxy::arrayReset, + QObject::connect(scatterDataProxy, &QScatterDataProxy::arrayReset, this, &Scatter3DController::handleArrayReset); - QObject::connect(m_data, &QScatterDataProxy::itemsAdded, + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsAdded, this, &Scatter3DController::handleItemsAdded); - QObject::connect(m_data, &QScatterDataProxy::itemsChanged, + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsChanged, this, &Scatter3DController::handleItemsChanged); - QObject::connect(m_data, &QScatterDataProxy::itemsRemoved, + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsRemoved, this, &Scatter3DController::handleItemsRemoved); - QObject::connect(m_data, &QScatterDataProxy::itemsInserted, + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsInserted, this, &Scatter3DController::handleItemsInserted); adjustValueAxisRange(); @@ -257,11 +264,6 @@ void Scatter3DController::setDataProxy(QScatterDataProxy *proxy) setSelectedItemIndex(noSelectionIndex()); } -QScatterDataProxy *Scatter3DController::dataProxy() -{ - return m_data; -} - void Scatter3DController::handleArrayReset() { setSlicingActive(false); @@ -295,7 +297,7 @@ void Scatter3DController::handleItemsRemoved(int startIndex, int count) // TODO should dirty only affected values? adjustValueAxisRange(); m_isDataDirty = true; - if (startIndex >= m_data->itemCount()) + if (startIndex >= static_cast<QScatterDataProxy *>(m_data)->itemCount()) setSelectedItemIndex(noSelectionIndex()); } @@ -356,7 +358,7 @@ void Scatter3DController::setSelectedItemIndex(int index) { // TODO If items not within axis ranges are culled from drawing, should they be // TODO unselectable as well? - if (index < 0 || index >= m_data->itemCount()) + if (index < 0 || index >= static_cast<QScatterDataProxy *>(m_data)->itemCount()) index = noSelectionIndex(); if (index != m_selectedItemIndex) { @@ -379,7 +381,7 @@ QPoint Scatter3DController::mousePosition() void Scatter3DController::adjustValueAxisRange() { if (m_data) { - QVector3D limits = m_data->dptr()->limitValues(); + QVector3D limits = static_cast<QScatterDataProxy *>(m_data)->dptr()->limitValues(); QValueAxis *valueAxis = static_cast<QValueAxis *>(m_axisX); if (valueAxis && valueAxis->isAutoAdjustRange()) { if (limits.x() > 0) diff --git a/src/datavis3d/engine/scatter3dcontroller_p.h b/src/datavis3d/engine/scatter3dcontroller_p.h index 9d847852..7a535ae3 100644 --- a/src/datavis3d/engine/scatter3dcontroller_p.h +++ b/src/datavis3d/engine/scatter3dcontroller_p.h @@ -64,7 +64,6 @@ private: // Rendering Scatter3DRenderer *m_renderer; - QScatterDataProxy *m_data; int m_selectedItemIndex; public: @@ -101,9 +100,7 @@ public: void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); void wheelEvent(QWheelEvent *event); - // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy. - void setDataProxy(QScatterDataProxy *proxy); - QScatterDataProxy *dataProxy(); + virtual void setActiveDataProxy(QAbstractDataProxy *proxy); void synchDataToRenderer(); diff --git a/src/datavis3dqml2/declarativebars.cpp b/src/datavis3dqml2/declarativebars.cpp index 32ed5c57..4bb45232 100644 --- a/src/datavis3dqml2/declarativebars.cpp +++ b/src/datavis3dqml2/declarativebars.cpp @@ -45,7 +45,7 @@ DeclarativeBars::DeclarativeBars(QQuickItem *parent) &DeclarativeBars::handleShadowQualityUpdate); QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy; - m_shared->setDataProxy(proxy); + m_shared->setActiveDataProxy(proxy); QObject::connect(proxy, &QBarDataProxy::arrayReset, this, &DeclarativeBars::dataResolved); @@ -112,17 +112,17 @@ void DeclarativeBars::setCameraPosition(qreal horizontal, qreal vertical, int di void DeclarativeBars::setData(QAbstractItemModel *data) { - static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->setItemModel(data); + static_cast<QItemModelBarDataProxy *>(m_shared->activeDataProxy())->setItemModel(data); } QAbstractItemModel *DeclarativeBars::data() { - return static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->itemModel(); + return static_cast<QItemModelBarDataProxy *>(m_shared->activeDataProxy())->itemModel(); } void DeclarativeBars::setMapping(QItemModelBarDataMapping *mapping) { - static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->setMapping(mapping); + static_cast<QItemModelBarDataProxy *>(m_shared->activeDataProxy())->setMapping(mapping); } QCategoryAxis *DeclarativeBars::rowAxis() const @@ -157,7 +157,7 @@ void DeclarativeBars::setColumnAxis(QCategoryAxis *axis) QItemModelBarDataMapping *DeclarativeBars::mapping() const { - return static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->mapping(); + return static_cast<QItemModelBarDataProxy *>(m_shared->activeDataProxy())->mapping(); } void DeclarativeBars::setBarThickness(qreal thicknessRatio) @@ -347,12 +347,12 @@ void DeclarativeBars::setColumns(int columns) void DeclarativeBars::setItemLabelFormat(const QString &format) { - m_shared->dataProxy()->setItemLabelFormat(format); + m_shared->activeDataProxy()->setItemLabelFormat(format); } QString DeclarativeBars::itemLabelFormat() { - return m_shared->dataProxy()->itemLabelFormat(); + return m_shared->activeDataProxy()->itemLabelFormat(); } void DeclarativeBars::setSelectedBarPos(const QPoint &position) diff --git a/src/datavis3dqml2/declarativescatter.cpp b/src/datavis3dqml2/declarativescatter.cpp index 3d35e420..2a7610c2 100644 --- a/src/datavis3dqml2/declarativescatter.cpp +++ b/src/datavis3dqml2/declarativescatter.cpp @@ -43,7 +43,7 @@ DeclarativeScatter::DeclarativeScatter(QQuickItem *parent) QObject::connect(m_shared, &Abstract3DController::shadowQualityChanged, this, &DeclarativeScatter::handleShadowQualityUpdate); - m_shared->setDataProxy(new QItemModelScatterDataProxy); + m_shared->setActiveDataProxy(new QItemModelScatterDataProxy); } DeclarativeScatter::~DeclarativeScatter() @@ -102,22 +102,22 @@ void DeclarativeScatter::setObjectColor(const QColor &baseColor, const QColor &h void DeclarativeScatter::setData(QAbstractItemModel *data) { - static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->setItemModel(data); + static_cast<QItemModelScatterDataProxy *>(m_shared->activeDataProxy())->setItemModel(data); } QAbstractItemModel *DeclarativeScatter::data() { - return static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->itemModel(); + return static_cast<QItemModelScatterDataProxy *>(m_shared->activeDataProxy())->itemModel(); } void DeclarativeScatter::setMapping(QItemModelScatterDataMapping *mapping) { - static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->setMapping(mapping); + static_cast<QItemModelScatterDataProxy *>(m_shared->activeDataProxy())->setMapping(mapping); } QItemModelScatterDataMapping *DeclarativeScatter::mapping() const { - return static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->mapping(); + return static_cast<QItemModelScatterDataProxy *>(m_shared->activeDataProxy())->mapping(); } QValueAxis *DeclarativeScatter::axisX() const @@ -291,12 +291,12 @@ QDataVis::ShadowQuality DeclarativeScatter::shadowQuality() void DeclarativeScatter::setItemLabelFormat(const QString &format) { - m_shared->dataProxy()->setItemLabelFormat(format); + m_shared->activeDataProxy()->setItemLabelFormat(format); } QString DeclarativeScatter::itemLabelFormat() { - return m_shared->dataProxy()->itemLabelFormat(); + return m_shared->activeDataProxy()->itemLabelFormat(); } void DeclarativeScatter::mousePressEvent(QMouseEvent *event) |