summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/data/qabstract3dseries_p.h1
-rw-r--r--src/datavisualization/data/qbar3dseries.cpp17
-rw-r--r--src/datavisualization/data/qbar3dseries.h1
-rw-r--r--src/datavisualization/data/qscatter3dseries.cpp45
-rw-r--r--src/datavisualization/data/qscatter3dseries.h6
-rw-r--r--src/datavisualization/data/qscatter3dseries_p.h3
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp33
-rw-r--r--src/datavisualization/engine/bars3dcontroller_p.h2
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp17
-rw-r--r--src/datavisualization/engine/q3dbars.cpp2
-rw-r--r--src/datavisualization/engine/q3dscatter.cpp21
-rw-r--r--src/datavisualization/engine/q3dscatter.h5
-rw-r--r--src/datavisualization/engine/scatter3dcontroller.cpp84
-rw-r--r--src/datavisualization/engine/scatter3dcontroller_p.h18
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp66
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h9
16 files changed, 212 insertions, 118 deletions
diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h
index 2851c8e0..a82c3554 100644
--- a/src/datavisualization/data/qabstract3dseries_p.h
+++ b/src/datavisualization/data/qabstract3dseries_p.h
@@ -67,6 +67,7 @@ private:
friend class Surface3DController;
friend class Scatter3DController;
friend class QBar3DSeries;
+ friend class QScatter3DSeries;
};
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp
index febbd97e..ac292e5e 100644
--- a/src/datavisualization/data/qbar3dseries.cpp
+++ b/src/datavisualization/data/qbar3dseries.cpp
@@ -138,10 +138,10 @@ QBarDataProxy *QBar3DSeries::dataProxy() const
/*!
* \property Q3DBars::selectedBar
*
- * Selects a bar in a \a position. The position is the (row, column) position in
+ * Selects a bar at the \a position. The \a position is the (row, column) position in
* the data array of the series.
* Only one bar can be selected at a time.
- * To clear selection, specify an illegal \a position, e.g. (-1, -1).
+ * To clear selection, set invalidSelectionPosition() as the \a position.
* If this series is added to a graph, the graph can adjust the selection according to user
* interaction or if it becomes invalid. Selecting a bar on another added series will also
* clear the selection.
@@ -161,6 +161,15 @@ QPoint QBar3DSeries::selectedBar() const
}
/*!
+ * \return an invalid position for selection. Set this position to selectedBar property if you
+ * want to clear the selection.
+ */
+QPoint QBar3DSeries::invalidSelectionPosition() const
+{
+ return Bars3DController::invalidSelectionPosition();
+}
+
+/*!
* \internal
*/
QBar3DSeriesPrivate *QBar3DSeries::dptr()
@@ -180,7 +189,7 @@ const QBar3DSeriesPrivate *QBar3DSeries::dptrc() const
QBar3DSeriesPrivate::QBar3DSeriesPrivate(QBar3DSeries *q)
: QAbstract3DSeriesPrivate(q, QAbstract3DSeries::SeriesTypeBar),
- m_selectedBar(Bars3DController::noSelectionPoint())
+ m_selectedBar(Bars3DController::invalidSelectionPosition())
{
m_itemLabelFormat = QStringLiteral("@valueTitle: @valueLabel");
}
@@ -206,7 +215,6 @@ void QBar3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy)
void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newController)
{
QBarDataProxy *barDataProxy = static_cast<QBarDataProxy *>(m_dataProxy);
- Bars3DController *controller = static_cast<Bars3DController *>(newController);
if (m_controller && barDataProxy) {
// Disconnect old controller/old proxy
@@ -215,6 +223,7 @@ void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newCon
}
if (newController && barDataProxy) {
+ Bars3DController *controller = static_cast<Bars3DController *>(newController);
QObject::connect(barDataProxy, &QBarDataProxy::arrayReset, controller,
&Bars3DController::handleArrayReset);
QObject::connect(barDataProxy, &QBarDataProxy::rowsAdded, controller,
diff --git a/src/datavisualization/data/qbar3dseries.h b/src/datavisualization/data/qbar3dseries.h
index ec1754d1..ddc52170 100644
--- a/src/datavisualization/data/qbar3dseries.h
+++ b/src/datavisualization/data/qbar3dseries.h
@@ -42,6 +42,7 @@ public:
void setSelectedBar(const QPoint &position);
QPoint selectedBar() const;
+ QPoint invalidSelectionPosition() const;
signals:
void dataProxyChanged(QBarDataProxy *proxy);
diff --git a/src/datavisualization/data/qscatter3dseries.cpp b/src/datavisualization/data/qscatter3dseries.cpp
index f0374339..aff0f33c 100644
--- a/src/datavisualization/data/qscatter3dseries.cpp
+++ b/src/datavisualization/data/qscatter3dseries.cpp
@@ -126,6 +126,39 @@ QScatterDataProxy *QScatter3DSeries::dataProxy() const
}
/*!
+ * \property QScatter3DSeries::selectedItem
+ *
+ * Selects an item at the \a index. The \a index is the index in the data array of the series.
+ * Only one item can be selected at a time.
+ * To clear selection, set invalidSelectionIndex() as the \a index.
+ * If this series is added to a graph, the graph can adjust the selection according to user
+ * interaction or if it becomes invalid. Selecting an item on another added series will also
+ * clear the selection.
+ */
+void QScatter3DSeries::setSelectedItem(int index)
+{
+ // Don't do this in private to avoid loops, as that is used for callback from controller.
+ if (d_ptr->m_controller)
+ static_cast<Scatter3DController *>(d_ptr->m_controller)->setSelectedItem(index, this);
+ else
+ dptr()->setSelectedItem(index);
+}
+
+int QScatter3DSeries::selectedItem() const
+{
+ return dptrc()->m_selectedItem;
+}
+
+/*!
+ * \return an invalid index for selection. Set this index to selectedItem property if you
+ * want to clear the selection.
+ */
+int QScatter3DSeries::invalidSelectionIndex() const
+{
+ return Scatter3DController::invalidSelectionIndex();
+}
+
+/*!
* \internal
*/
QScatter3DSeriesPrivate *QScatter3DSeries::dptr()
@@ -144,7 +177,8 @@ const QScatter3DSeriesPrivate *QScatter3DSeries::dptrc() const
// QScatter3DSeriesPrivate
QScatter3DSeriesPrivate::QScatter3DSeriesPrivate(QScatter3DSeries *q)
- : QAbstract3DSeriesPrivate(q, QAbstract3DSeries::SeriesTypeScatter)
+ : QAbstract3DSeriesPrivate(q, QAbstract3DSeries::SeriesTypeScatter),
+ m_selectedItem(Scatter3DController::invalidSelectionIndex())
{
m_itemLabelFormat = QStringLiteral("@valueTitle: @valueLabel");
}
@@ -179,7 +213,6 @@ void QScatter3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *ne
if (newController && scatterDataProxy) {
Scatter3DController *controller = static_cast<Scatter3DController *>(newController);
-
QObject::connect(scatterDataProxy, &QScatterDataProxy::arrayReset,
controller, &Scatter3DController::handleArrayReset);
QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsAdded,
@@ -196,4 +229,12 @@ void QScatter3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *ne
}
}
+void QScatter3DSeriesPrivate::setSelectedItem(int index)
+{
+ if (index != m_selectedItem) {
+ m_selectedItem = index;
+ emit qptr()->selectedItemChanged(m_selectedItem);
+ }
+}
+
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qscatter3dseries.h b/src/datavisualization/data/qscatter3dseries.h
index bb24f79a..8c28f3a6 100644
--- a/src/datavisualization/data/qscatter3dseries.h
+++ b/src/datavisualization/data/qscatter3dseries.h
@@ -30,6 +30,7 @@ class QT_DATAVISUALIZATION_EXPORT QScatter3DSeries : public QAbstract3DSeries
{
Q_OBJECT
Q_PROPERTY(QScatterDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged)
+ Q_PROPERTY(int selectedItem READ selectedItem WRITE setSelectedItem NOTIFY selectedItemChanged)
public:
explicit QScatter3DSeries(QObject *parent = 0);
@@ -39,8 +40,13 @@ public:
void setDataProxy(QScatterDataProxy *proxy);
QScatterDataProxy *dataProxy() const;
+ void setSelectedItem(int index);
+ int selectedItem() const;
+ Q_INVOKABLE int invalidSelectionIndex() const;
+
signals:
void dataProxyChanged(QScatterDataProxy *proxy);
+ void selectedItemChanged(int index);
protected:
explicit QScatter3DSeries(QScatter3DSeriesPrivate *d, QObject *parent = 0);
diff --git a/src/datavisualization/data/qscatter3dseries_p.h b/src/datavisualization/data/qscatter3dseries_p.h
index b839af2e..0cf47bce 100644
--- a/src/datavisualization/data/qscatter3dseries_p.h
+++ b/src/datavisualization/data/qscatter3dseries_p.h
@@ -44,8 +44,11 @@ public:
virtual void setDataProxy(QAbstractDataProxy *proxy);
virtual void connectControllerAndProxy(Abstract3DController *newController);
+ void setSelectedItem(int index);
+
private:
QScatter3DSeries *qptr();
+ int m_selectedItem;
private:
friend class QScatter3DSeries;
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
index 995633a8..b1cf8338 100644
--- a/src/datavisualization/engine/bars3dcontroller.cpp
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -32,7 +32,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
Bars3DController::Bars3DController(QRect boundRect)
: Abstract3DController(boundRect),
- m_selectedBar(noSelectionPoint()),
+ m_selectedBar(invalidSelectionPosition()),
m_selectedBarSeries(0),
m_isBarSpecRelative(true),
m_barThicknessRatio(1.0f),
@@ -179,11 +179,7 @@ void Bars3DController::handleDataColumnLabelsChanged()
void Bars3DController::handleBarClicked(const QPoint &position, QBar3DSeries *series)
{
- // Series may already have been removed, so check it before setting the selection.
- if (m_seriesList.contains(series))
- setSelectedBar(position, series);
- else
- setSelectedBar(noSelectionPoint(), 0);
+ setSelectedBar(position, series);
// TODO: pass clicked to parent. (QTRD-2517)
// TODO: Also hover needed? (QTRD-2131)
@@ -206,7 +202,7 @@ void Bars3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
setSelectedBar(m_selectedBar, m_selectedBarSeries);
}
-QPoint Bars3DController::noSelectionPoint()
+QPoint Bars3DController::invalidSelectionPosition()
{
static QPoint noSelectionPos(-1, -1);
return noSelectionPos;
@@ -240,7 +236,7 @@ void Bars3DController::addSeries(QAbstract3DSeries *series)
}
QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series);
- if (barSeries->selectedBar() != noSelectionPoint())
+ if (barSeries->selectedBar() != invalidSelectionPosition())
setSelectedBar(barSeries->selectedBar(), barSeries);
}
@@ -249,7 +245,7 @@ void Bars3DController::removeSeries(QAbstract3DSeries *series)
bool firstRemoved = (m_seriesList.size() && m_seriesList.at(0) == series);
if (m_selectedBarSeries == series)
- setSelectedBar(noSelectionPoint(), 0);
+ setSelectedBar(invalidSelectionPosition(), 0);
Abstract3DController::removeSeries(series);
@@ -365,6 +361,10 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri
// If the selection targets non-existent bar, clear selection instead.
QPoint pos = position;
+ // Series may already have been removed, so check it before setting the selection.
+ if (!m_seriesList.contains(series))
+ series = 0;
+
adjustSelectionPosition(pos, series);
if (selectionMode().testFlag(QDataVis::SelectionSlice)) {
@@ -383,14 +383,15 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri
m_selectedBar = pos;
m_selectedBarSeries = series;
m_changeTracker.selectedBarChanged = true;
- // Clear selection from other series and set the new selection to the affected series
+
+ // Clear selection from other series and finally set new selection to the specified series
foreach (QAbstract3DSeries *otherSeries, m_seriesList) {
QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(otherSeries);
if (barSeries != m_selectedBarSeries)
- barSeries->dptr()->setSelectedBar(noSelectionPoint());
- else
- barSeries->dptr()->setSelectedBar(m_selectedBar);
+ barSeries->dptr()->setSelectedBar(invalidSelectionPosition());
}
+ if (m_selectedBarSeries)
+ m_selectedBarSeries->dptr()->setSelectedBar(m_selectedBar);
emitNeedRender();
}
@@ -449,15 +450,15 @@ void Bars3DController::adjustSelectionPosition(QPoint &pos, const QBar3DSeries *
proxy = series->dataProxy();
if (!proxy)
- pos = noSelectionPoint();
+ pos = invalidSelectionPosition();
- if (pos != noSelectionPoint()) {
+ if (pos != invalidSelectionPosition()) {
int maxRow = proxy->rowCount() - 1;
int maxCol = (pos.x() <= maxRow && pos.x() >= 0 && proxy->rowAt(pos.x()))
? proxy->rowAt(pos.x())->size() - 1 : -1;
if (pos.x() < 0 || pos.x() > maxRow || pos.y() < 0 || pos.y() > maxCol)
- pos = noSelectionPoint();
+ pos = invalidSelectionPosition();
}
}
diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h
index 4da6c730..e9f39541 100644
--- a/src/datavisualization/engine/bars3dcontroller_p.h
+++ b/src/datavisualization/engine/bars3dcontroller_p.h
@@ -96,7 +96,7 @@ public:
virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust);
virtual void handleSeriesVisibilityChangedBySender(QObject *sender);
- static QPoint noSelectionPoint();
+ static QPoint invalidSelectionPosition();
virtual void setAxisX(Q3DAbstractAxis *axis);
virtual void setAxisZ(Q3DAbstractAxis *axis);
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 7682f389..6c5d49c2 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -86,10 +86,10 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
m_scaleZ(0),
m_scaleFactor(0),
m_maxSceneSize(40.0f),
- m_visualSelectedBarPos(Bars3DController::noSelectionPoint()),
+ m_visualSelectedBarPos(Bars3DController::invalidSelectionPosition()),
m_visualSelectedBarSeriesIndex(-1),
m_hasHeightAdjustmentChanged(true),
- m_selectedBarPos(Bars3DController::noSelectionPoint()),
+ m_selectedBarPos(Bars3DController::invalidSelectionPosition()),
m_selectedBarSeries(0),
m_noZeroInRange(false),
m_seriesScale(0.0f),
@@ -1025,7 +1025,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
BarRenderItem *selectedBar(0);
QVector3D modelScaler(m_scaleX * m_seriesScale, 0.0f, m_scaleZ);
- bool somethingSelected = (m_visualSelectedBarPos != Bars3DController::noSelectionPoint());
+ bool somethingSelected = (m_visualSelectedBarPos != Bars3DController::invalidSelectionPosition());
for (int row = startRow; row != stopRow; row += stepRow) {
for (int bar = startBar; bar != stopBar; bar += stepBar) {
float seriesPos = m_seriesStart;
@@ -1843,10 +1843,10 @@ void Bars3DRenderer::updateSelectedBar(const QPoint &position, const QBar3DSerie
m_selectedBarPos = position;
m_selectedBarSeries = series;
m_selectionDirty = true;
+ m_visualSelectedBarSeriesIndex = -1;
if (m_renderingArrays.isEmpty()) {
- m_visualSelectedBarPos = Bars3DController::noSelectionPoint();
- m_visualSelectedBarSeriesIndex = -1;
+ m_visualSelectedBarPos = Bars3DController::invalidSelectionPosition();
return;
}
@@ -1855,7 +1855,6 @@ void Bars3DRenderer::updateSelectedBar(const QPoint &position, const QBar3DSerie
int maxX = m_renderingArrays.at(0).size() - 1;
int maxZ = maxX >= 0 ? m_renderingArrays.at(0).at(0).size() - 1 : -1;
- m_visualSelectedBarSeriesIndex = -1;
for (int i = 0; i < m_visibleSeriesList.size(); i++) {
if (m_visibleSeriesList.at(i).series() == series) {
m_visualSelectedBarSeriesIndex = i;
@@ -1863,10 +1862,10 @@ void Bars3DRenderer::updateSelectedBar(const QPoint &position, const QBar3DSerie
}
}
- if (m_selectedBarPos == Bars3DController::noSelectionPoint()
+ if (m_selectedBarPos == Bars3DController::invalidSelectionPosition()
|| adjustedX < 0 || adjustedX > maxX
|| adjustedZ < 0 || adjustedZ > maxZ) {
- m_visualSelectedBarPos = Bars3DController::noSelectionPoint();
+ m_visualSelectedBarPos = Bars3DController::invalidSelectionPosition();
} else {
m_visualSelectedBarPos = QPoint(adjustedX, adjustedZ);
}
@@ -2028,7 +2027,7 @@ QPoint Bars3DRenderer::selectionColorToArrayPosition(const QVector3D &selectionC
{
QPoint position;
if (selectionColor == selectionSkipColor) {
- position = Bars3DController::noSelectionPoint();
+ position = Bars3DController::invalidSelectionPosition();
} else {
position = QPoint(int(selectionColor.x() + int(m_axisCacheX.min())),
int(selectionColor.y()) + int(m_axisCacheZ.min()));
diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp
index 60d827bd..6fef5be4 100644
--- a/src/datavisualization/engine/q3dbars.cpp
+++ b/src/datavisualization/engine/q3dbars.cpp
@@ -149,7 +149,7 @@ Q3DBars::~Q3DBars()
* so the rows and columns of all series must match for the visualized data to be meaningful.
* If the graph has multiple visible series, only the first one added will
* generate the row or column labels on the axes in cases where the labels are not explicitly set
- * to the axes. If newly added series has specified a selected bar, it will be highlighted and
+ * to the axes. If the newly added series has specified a selected bar, it will be highlighted and
* any existing selection will be cleared. Only one added series can have an active selection.
*/
void Q3DBars::addSeries(QBar3DSeries *series)
diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp
index 7aaa0e6b..c01b5747 100644
--- a/src/datavisualization/engine/q3dscatter.cpp
+++ b/src/datavisualization/engine/q3dscatter.cpp
@@ -102,8 +102,6 @@ Q3DScatter::Q3DScatter()
&Q3DScatter::gridVisibleChanged);
QObject::connect(d_ptr->m_shared, &Abstract3DController::backgroundVisibleChanged, this,
&Q3DScatter::backgroundVisibleChanged);
- QObject::connect(d_ptr->m_shared, &Scatter3DController::selectedItemIndexChanged, this,
- &Q3DScatter::selectedItemIndexChanged);
QObject::connect(d_ptr->m_shared, &Abstract3DController::colorStyleChanged, this,
&Q3DScatter::colorStyleChanged);
QObject::connect(d_ptr->m_shared, &Abstract3DController::objectColorChanged, this,
@@ -131,7 +129,8 @@ Q3DScatter::~Q3DScatter()
/*!
* Adds the \a series to the graph. A graph can contain multiple series, but has only one set of
- * axes.
+ * axes. If the newly added series has specified a selected item, it will be highlighted and
+ * any existing selection will be cleared. Only one added series can have an active selection.
*/
void Q3DScatter::addSeries(QScatter3DSeries *series)
{
@@ -369,22 +368,6 @@ bool Q3DScatter::isBackgroundVisible() const
}
/*!
- * \property Q3DScatter::selectedItemIndex
- *
- * Selects an item in the \a index. Only one item can be selected at a time.
- * To clear selection, specify an illegal \a index, e.g. -1.
- */
-void Q3DScatter::setSelectedItemIndex(int index)
-{
- d_ptr->m_shared->setSelectedItemIndex(index);
-}
-
-int Q3DScatter::selectedItemIndex() const
-{
- return d_ptr->m_shared->selectedItemIndex();
-}
-
-/*!
* \property Q3DScatter::shadowQuality
*
* Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to
diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h
index 2f403ce1..5f3a1024 100644
--- a/src/datavisualization/engine/q3dscatter.h
+++ b/src/datavisualization/engine/q3dscatter.h
@@ -44,7 +44,6 @@ class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow
Q_PROPERTY(QtDataVisualization::QDataVis::Theme theme READ theme WRITE setTheme NOTIFY themeChanged)
Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible NOTIFY gridVisibleChanged)
Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible NOTIFY backgroundVisibleChanged)
- Q_PROPERTY(int selectedItemIndex READ selectedItemIndex WRITE setSelectedItemIndex NOTIFY selectedItemIndexChanged)
Q_PROPERTY(Q3DScene* scene READ scene)
Q_PROPERTY(QtDataVisualization::QDataVis::ColorStyle colorStyle READ colorStyle WRITE setColorStyle NOTIFY colorStyleChanged)
Q_PROPERTY(QColor itemColor READ itemColor WRITE setItemColor NOTIFY itemColorChanged)
@@ -90,9 +89,6 @@ public:
void setBackgroundVisible(bool visible);
bool isBackgroundVisible() const;
- void setSelectedItemIndex(int index);
- int selectedItemIndex() const;
-
void setShadowQuality(QDataVis::ShadowQuality quality);
QDataVis::ShadowQuality shadowQuality() const;
@@ -131,7 +127,6 @@ signals:
void themeChanged(QDataVis::Theme theme);
void gridVisibleChanged(bool visible);
void backgroundVisibleChanged(bool visible);
- void selectedItemIndexChanged(int index);
void colorStyleChanged(QDataVis::ColorStyle style);
void itemColorChanged(QColor color);
void itemGradientChanged(QLinearGradient gradient);
diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp
index 11a2d03f..27d1b609 100644
--- a/src/datavisualization/engine/scatter3dcontroller.cpp
+++ b/src/datavisualization/engine/scatter3dcontroller.cpp
@@ -32,7 +32,8 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
Scatter3DController::Scatter3DController(QRect boundRect)
: Abstract3DController(boundRect),
m_renderer(0),
- m_selectedItemIndex(noSelectionIndex())
+ m_selectedItem(invalidSelectionIndex()),
+ m_selectedItemSeries(0)
{
// Default object type; specific to scatter
setObjectType(QDataVis::MeshStyleSpheres, false);
@@ -72,9 +73,9 @@ void Scatter3DController::synchDataToRenderer()
return;
// Notify changes to renderer
- if (m_changeTracker.selectedItemIndexChanged) {
- m_renderer->updateSelectedItemIndex(m_selectedItemIndex);
- m_changeTracker.selectedItemIndexChanged = false;
+ if (m_changeTracker.selectedItemChanged) {
+ m_renderer->updateSelectedItem(m_selectedItem, m_selectedItemSeries);
+ m_changeTracker.selectedItemChanged = false;
}
}
@@ -86,24 +87,25 @@ void Scatter3DController::addSeries(QAbstract3DSeries *series)
Abstract3DController::addSeries(series);
- if (firstAdded) {
+ if (firstAdded)
adjustValueAxisRange();
- // TODO: Temp until selection by series is properly implemented
- setSelectedItemIndex(noSelectionIndex());
- }
+
+ QScatter3DSeries *scatterSeries = static_cast<QScatter3DSeries *>(series);
+ if (scatterSeries->selectedItem() != invalidSelectionIndex())
+ setSelectedItem(scatterSeries->selectedItem(), scatterSeries);
}
void Scatter3DController::removeSeries(QAbstract3DSeries *series)
{
bool firstRemoved = (m_seriesList.size() && m_seriesList.at(0) == series);
+ if (m_selectedItemSeries == series)
+ setSelectedItem(invalidSelectionIndex(), 0);
+
Abstract3DController::removeSeries(series);
- if (firstRemoved) {
+ if (firstRemoved)
adjustValueAxisRange();
- // TODO: Temp until selection by series is properly implemented
- setSelectedItemIndex(noSelectionIndex());
- }
}
QList<QScatter3DSeries *> Scatter3DController::scatterSeriesList()
@@ -123,7 +125,7 @@ void Scatter3DController::handleArrayReset()
{
adjustValueAxisRange();
m_isDataDirty = true;
- setSelectedItemIndex(m_selectedItemIndex);
+ setSelectedItem(m_selectedItem, m_selectedItemSeries);
emitNeedRender();
}
@@ -154,9 +156,10 @@ void Scatter3DController::handleItemsRemoved(int startIndex, int count)
// TODO should dirty only affected values?
adjustValueAxisRange();
m_isDataDirty = true;
- QScatterDataProxy *proxy = qobject_cast<QScatterDataProxy *>(sender());
- if (!proxy || startIndex >= proxy->itemCount())
- setSelectedItemIndex(noSelectionIndex());
+
+ // Clear selection unless it is still valid
+ setSelectedItem(m_selectedItem, m_selectedItemSeries);
+
emitNeedRender();
}
@@ -170,9 +173,10 @@ void Scatter3DController::handleItemsInserted(int startIndex, int count)
emitNeedRender();
}
-void Scatter3DController::handleItemClicked(int index)
+void Scatter3DController::handleItemClicked(int index, QScatter3DSeries *series)
{
- setSelectedItemIndex(index);
+ setSelectedItem(index, series);
+
// TODO: pass clicked to parent. (QTRD-2517)
// TODO: Also hover needed? (QTRD-2131)
}
@@ -190,7 +194,7 @@ void Scatter3DController::handleAxisRangeChangedBySender(QObject *sender)
Abstract3DController::handleAxisRangeChangedBySender(sender);
// Update selected index - may be moved offscreen
- setSelectedItemIndex(m_selectedItemIndex);
+ setSelectedItem(m_selectedItem, m_selectedItemSeries);
}
void Scatter3DController::setObjectType(QDataVis::MeshStyle style, bool smooth)
@@ -222,28 +226,42 @@ void Scatter3DController::setSelectionMode(QDataVis::SelectionFlags mode)
qWarning("Unsupported selection mode - only none and item selection modes are supported.");
return;
}
+
Abstract3DController::setSelectionMode(mode);
}
-void Scatter3DController::setSelectedItemIndex(int index)
+void Scatter3DController::setSelectedItem(int index, QScatter3DSeries *series)
{
- // TODO: Support for multiple sets. Just remove the item count test for now
- if (index < 0 /*|| index >= static_cast<QScatterDataProxy *>(m_data)->itemCount()*/)
- index = noSelectionIndex();
-
- if (index != m_selectedItemIndex) {
- m_selectedItemIndex = index;
- m_changeTracker.selectedItemIndexChanged = true;
- emit selectedItemIndexChanged(index);
+ const QScatterDataProxy *proxy = 0;
+
+ // Series may already have been removed, so check it before setting the selection.
+ if (!m_seriesList.contains(series))
+ series = 0;
+
+ if (series)
+ proxy = series->dataProxy();
+
+ if (!proxy || index < 0 || index >= proxy->itemCount())
+ index = invalidSelectionIndex();
+
+ if (index != m_selectedItem || series != m_selectedItemSeries) {
+ m_selectedItem = index;
+ m_selectedItemSeries = series;
+ m_changeTracker.selectedItemChanged = true;
+
+ // Clear selection from other series and finally set new selection to the specified series
+ foreach (QAbstract3DSeries *otherSeries, m_seriesList) {
+ QScatter3DSeries *scatterSeries = static_cast<QScatter3DSeries *>(otherSeries);
+ if (scatterSeries != m_selectedItemSeries)
+ scatterSeries->dptr()->setSelectedItem(invalidSelectionIndex());
+ }
+ if (m_selectedItemSeries)
+ m_selectedItemSeries->dptr()->setSelectedItem(m_selectedItem);
+
emitNeedRender();
}
}
-int Scatter3DController::selectedItemIndex() const
-{
- return m_selectedItemIndex;
-}
-
void Scatter3DController::adjustValueAxisRange()
{
QVector3D minLimits;
diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h
index a75b61ac..349b226a 100644
--- a/src/datavisualization/engine/scatter3dcontroller_p.h
+++ b/src/datavisualization/engine/scatter3dcontroller_p.h
@@ -41,10 +41,10 @@ class QScatterDataProxy;
class QScatter3DSeries;
struct Scatter3DChangeBitField {
- bool selectedItemIndexChanged : 1;
+ bool selectedItemChanged : 1;
Scatter3DChangeBitField() :
- selectedItemIndexChanged(true)
+ selectedItemChanged(true)
{
}
};
@@ -58,7 +58,9 @@ private:
// Rendering
Scatter3DRenderer *m_renderer;
- int m_selectedItemIndex;
+ int m_selectedItem;
+ QScatter3DSeries *m_selectedItemSeries; // Points to the series for which the bar is selected
+ // in single series selection cases.
public:
explicit Scatter3DController(QRect rect);
@@ -72,9 +74,8 @@ public:
// Change selection mode
void setSelectionMode(QDataVis::SelectionFlags mode);
- void setSelectedItemIndex(int index);
- int selectedItemIndex() const;
- static inline int noSelectionIndex() { return -1; }
+ void setSelectedItem(int index, QScatter3DSeries *series);
+ static inline int invalidSelectionIndex() { return -1; }
void synchDataToRenderer();
@@ -93,10 +94,7 @@ public slots:
void handleItemsInserted(int startIndex, int count);
// Renderer callback handlers
- void handleItemClicked(int index);
-
-signals:
- void selectedItemIndexChanged(int index);
+ void handleItemClicked(int index, QScatter3DSeries *series);
private:
void adjustValueAxisRange();
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index 2abb4fe9..5f03f982 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -80,6 +80,10 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_shadowQualityMultiplier(3),
m_heightNormalizer(1.0f),
m_scaleFactor(0),
+ m_selectedItemIndex(Scatter3DController::invalidSelectionIndex()),
+ m_selectedItemTotalIndex(Scatter3DController::invalidSelectionIndex()),
+ m_selectedItemSeriesIndex(Scatter3DController::invalidSelectionIndex()),
+ m_selectedSeries(0),
m_areaSize(QSizeF(0.0, 0.0)),
m_dotSizeScale(1.0f),
m_hasHeightAdjustmentChanged(true),
@@ -180,7 +184,8 @@ void Scatter3DRenderer::updateData()
}
}
m_dotSizeScale = (GLfloat)qBound(0.01, (2.0 / qSqrt((qreal)totalDataSize)), 0.1);
- m_selectedItem = 0;
+
+ updateSelectedItem(m_selectedItemIndex, m_selectedSeries);
}
void Scatter3DRenderer::updateScene(Q3DScene *scene)
@@ -342,6 +347,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
modelMatrix.translate(item.translation());
if (!m_drawingPoints) {
modelMatrix.scale(modelScaler);
+ // TODO: Remove all references to item size?
//modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
// heightMultiplier * item.size() + heightScaler,
// depthMultiplier * item.size() + depthScaler));
@@ -451,6 +457,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
modelMatrix.translate(item.translation());
if (!m_drawingPoints) {
modelMatrix.scale(modelScaler);
+ // TODO: Remove all references to item size?
//modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
// heightMultiplier * item.size() + heightScaler,
// depthMultiplier * item.size() + depthScaler));
@@ -494,7 +501,10 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Read color under cursor
QVector3D clickedColor = Utils::getSelection(m_inputPosition,
m_cachedBoundingRect.height());
- emit itemClicked(selectionColorToIndex(clickedColor));
+ int clickedIndex = 0;
+ QScatter3DSeries *clickedSeries = 0;
+ selectionColorToSeriesAndIndex(clickedColor, clickedIndex, clickedSeries);
+ emit itemClicked(clickedIndex, clickedSeries);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -556,7 +566,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Draw dots
bool dotSelectionFound = false;
ScatterRenderItem *selectedItem(0);
- int selectedSeriesIndex(0);
int dotNo = 0;
for (int series = 0; series < seriesCount; series++) {
@@ -577,6 +586,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
if (!m_drawingPoints) {
modelMatrix.scale(modelScaler);
itModelMatrix.scale(modelScaler);
+ // TODO: Remove all references to item size?
//modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
// heightMultiplier * item.size() + heightScaler,
// depthMultiplier * item.size() + depthScaler));
@@ -596,7 +606,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
gradientTexture = m_objectGradientTexture;
GLfloat lightStrength = m_cachedTheme.m_lightStrength;
- if (m_cachedSelectionMode > QDataVis::SelectionNone && (m_selectedItemIndex == dotNo)) {
+ if (m_cachedSelectionMode > QDataVis::SelectionNone && (m_selectedItemTotalIndex == dotNo)) {
if (m_cachedColorStyle == QDataVis::ColorStyleUniform || m_drawingPoints)
dotColor = Utils::vectorFromColor(m_cachedSingleHighlightColor);
else
@@ -604,7 +614,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
lightStrength = m_cachedTheme.m_highlightLightStrength;
// Insert data to ScatterRenderItem. We have no ownership, don't delete the previous one
selectedItem = &item;
- selectedSeriesIndex = series;
dotSelectionFound = true;
}
@@ -1359,7 +1368,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
static const QString yLabelTag(QStringLiteral("@yLabel"));
static const QString zLabelTag(QStringLiteral("@zLabel"));
- labelText = m_visibleSeriesList[selectedSeriesIndex].itemLabelFormat();
+ labelText = m_visibleSeriesList[m_selectedItemSeriesIndex].itemLabelFormat();
labelText.replace(xTitleTag, m_axisCacheX.title());
labelText.replace(yTitleTag, m_axisCacheY.title());
@@ -1410,12 +1419,30 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Release label shader
m_labelShader->release();
+
+ m_selectionDirty = false;
}
-void Scatter3DRenderer::updateSelectedItemIndex(int index)
+void Scatter3DRenderer::updateSelectedItem(int index, const QScatter3DSeries *series)
{
m_selectionDirty = true;
- m_selectedItemIndex = index;
+ m_selectedSeries = series;
+ m_selectedItemIndex = Scatter3DController::invalidSelectionIndex();
+ m_selectedItemTotalIndex = Scatter3DController::invalidSelectionIndex();
+ m_selectedItemSeriesIndex = Scatter3DController::invalidSelectionIndex();
+
+ if (!m_renderingArrays.isEmpty() && index != Scatter3DController::invalidSelectionIndex()) {
+ int totalIndex = 0;
+ for (int i = 0; i < m_visibleSeriesList.size(); i++) {
+ if (m_visibleSeriesList.at(i).series() == series) {
+ m_selectedItemSeriesIndex = i;
+ m_selectedItemIndex = index;
+ m_selectedItemTotalIndex = index + totalIndex;
+ break;
+ }
+ totalIndex += m_renderingArrays.at(i).size();
+ }
+ }
}
void Scatter3DRenderer::handleResize()
@@ -1656,17 +1683,26 @@ QVector3D Scatter3DRenderer::indexToSelectionColor(GLint index)
return QVector3D(dotIdxRed, dotIdxGreen, dotIdxBlue);
}
-int Scatter3DRenderer::selectionColorToIndex(const QVector3D &color)
+void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector3D &color, int &index, QScatter3DSeries *&series)
{
- int selectedIndex;
- if (color == selectionSkipColor) {
- selectedIndex = Scatter3DController::noSelectionIndex();
- } else {
- selectedIndex = int(color.x())
+ if (color != selectionSkipColor) {
+ index = int(color.x())
+ (int(color.y()) << 8)
+ (int(color.z()) << 16);
+ // Find the series and adjust the index accordingly
+ for (int i = 0; i < m_renderingArrays.size(); i++) {
+ if (index < m_renderingArrays.at(i).size()) {
+ series = static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(i).series());
+ return; // Valid found and already set to return parameters, so we can return
+ } else {
+ index -= m_renderingArrays.at(i).size();
+ }
+ }
}
- return selectedIndex;
+
+ // No valid match found
+ index = Scatter3DController::invalidSelectionIndex();
+ series = 0;
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index bba790a1..6f8f9cbd 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -82,6 +82,9 @@ private:
GLfloat m_heightNormalizer;
GLfloat m_scaleFactor;
int m_selectedItemIndex;
+ int m_selectedItemTotalIndex;
+ int m_selectedItemSeriesIndex;
+ const QScatter3DSeries *m_selectedSeries;
QSizeF m_areaSize;
GLfloat m_dotSizeScale;
QVector3D m_translationOffset;
@@ -139,14 +142,14 @@ public slots:
// Overloaded from abstract renderer
virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
- void updateSelectedItemIndex(int index);
+ void updateSelectedItem(int index, const QScatter3DSeries *series);
signals:
- void itemClicked(int index);
+ void itemClicked(int index, QScatter3DSeries *series);
private:
QVector3D indexToSelectionColor(GLint index);
- int selectionColorToIndex(const QVector3D &color);
+ void selectionColorToSeriesAndIndex(const QVector3D &color, int &index, QScatter3DSeries *&series);
};
QT_DATAVISUALIZATION_END_NAMESPACE