summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-08-29 15:51:57 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-08-30 07:52:05 +0300
commita88922ed813f6f0510fc13c6a5ff999a4e51b4d3 (patch)
tree918519ba9895e3e30b7e50f89e5c0abe5d9fa0f5 /src
parent1f9a6ca62c282658ae1f76a59e521cd99a280ba5 (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.cpp3
-rw-r--r--src/datavis3d/data/qabstractdataproxy.h4
-rw-r--r--src/datavis3d/data/qabstractdataproxy_p.h4
-rw-r--r--src/datavis3d/engine/abstract3dcontroller.cpp76
-rw-r--r--src/datavis3d/engine/abstract3dcontroller_p.h10
-rw-r--r--src/datavis3d/engine/bars3dcontroller.cpp51
-rw-r--r--src/datavis3d/engine/bars3dcontroller_p.h6
-rw-r--r--src/datavis3d/engine/q3dbars.cpp90
-rw-r--r--src/datavis3d/engine/q3dbars.h7
-rw-r--r--src/datavis3d/engine/q3dscatter.cpp92
-rw-r--r--src/datavis3d/engine/q3dscatter.h7
-rw-r--r--src/datavis3d/engine/q3dsurface.cpp24
-rw-r--r--src/datavis3d/engine/scatter3dcontroller.cpp42
-rw-r--r--src/datavis3d/engine/scatter3dcontroller_p.h5
-rw-r--r--src/datavis3dqml2/declarativebars.cpp14
-rw-r--r--src/datavis3dqml2/declarativescatter.cpp14
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)