summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine/surface3dcontroller.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-10-29 14:01:42 +0200
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-10-30 10:06:08 +0200
commit84c156d3e2fcceeab608f401fbc638f2d01219b3 (patch)
tree74de2de1635c60645f4864d08f6afb941948aea8 /src/datavisualization/engine/surface3dcontroller.cpp
parent233d5c02638903e96687d580ada7188f0e6a9756 (diff)
Selection overhaul
Selection modes are now proper flags, so you can easily mix and match item, row, and column modes as you wish. Slice flag means automatic slicing control - if user wishes to control slicing himself, he should not set this mode flag. Clicking an item on graph now emits clicked signal from renderer to controller on all graphs instead of setting the selected item. Controller will set the selected item based on this information. Task-number: QTRD-2366 Task-number: QTRD-2491 Change-Id: I6251c42e22ea676613fbd36685e33574e6eb9a1a Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/engine/surface3dcontroller.cpp')
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp118
1 files changed, 107 insertions, 11 deletions
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index 8d1bcf85..71b09efd 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -34,7 +34,8 @@ Surface3DController::Surface3DController(QRect rect)
: Abstract3DController(rect),
m_renderer(0),
m_isSmoothSurfaceEnabled(false),
- m_isSurfaceGridEnabled(true)
+ m_isSurfaceGridEnabled(true),
+ m_selectedPoint(noSelectionPoint())
{
setActiveDataProxy(0);
@@ -62,6 +63,8 @@ void Surface3DController::initializeOpenGL()
m_renderer = new Surface3DRenderer(this);
setRenderer(m_renderer);
synchDataToRenderer();
+ QObject::connect(m_renderer, &Surface3DRenderer::pointClicked, this,
+ &Surface3DController::handlePointClicked, Qt::QueuedConnection);
emitNeedRender();
}
@@ -91,6 +94,11 @@ void Surface3DController::synchDataToRenderer()
m_changeTracker.surfaceGridChanged = false;
}
+ if (m_changeTracker.selectedPointChanged) {
+ m_renderer->updateSelectedPoint(m_selectedPoint);
+ m_changeTracker.selectedPointChanged = false;
+ }
+
if (m_isDataDirty) {
m_renderer->updateDataModel(static_cast<QSurfaceDataProxy *>(m_data));
m_isDataDirty = false;
@@ -107,8 +115,16 @@ void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstr
void Surface3DController::handleAxisRangeChangedBySender(QObject *sender)
{
- scene()->setSlicingActive(false);
Abstract3DController::handleAxisRangeChangedBySender(sender);
+
+ // Update selected point - may be moved offscreen
+ setSelectedPoint(m_selectedPoint);
+}
+
+QPoint Surface3DController::noSelectionPoint()
+{
+ static QPoint noSelectionPoint(-1, -1);
+ return noSelectionPoint;
}
void Surface3DController::setSmoothSurface(bool enable)
@@ -160,19 +176,88 @@ void Surface3DController::setGradientColorAt(qreal pos, const QColor &color)
emitNeedRender();
}
-void Surface3DController::setSelectionMode(QDataVis::SelectionMode mode)
+void Surface3DController::setSelectionMode(QDataVis::SelectionFlags mode)
{
- if (!(mode == QDataVis::SelectionModeNone || mode == QDataVis::SelectionModeItem
- || mode == QDataVis::SelectionModeSliceRow
- || mode == QDataVis::SelectionModeSliceColumn)) {
+ // Currently surface only supports row and column modes when also slicing
+ if ((mode.testFlag(QDataVis::SelectionRow) || mode.testFlag(QDataVis::SelectionColumn))
+ && !mode.testFlag(QDataVis::SelectionSlice)) {
qWarning("Unsupported selection mode.");
return;
+ } else if (mode.testFlag(QDataVis::SelectionSlice)
+ && (mode.testFlag(QDataVis::SelectionRow) == mode.testFlag(QDataVis::SelectionColumn))) {
+ qWarning("Must specify one of either row or column selection mode in conjunction with slicing mode.");
+ } else {
+ // When setting selection mode to a new slicing mode, activate slicing
+ if (mode != selectionMode()) {
+ bool isSlicing = mode.testFlag(QDataVis::SelectionSlice);
+ if (isSlicing && m_selectedPoint != noSelectionPoint())
+ scene()->setSlicingActive(true);
+ else
+ scene()->setSlicingActive(false);
+ }
+
+ Abstract3DController::setSelectionMode(mode);
}
- // Disable zoom if selection mode changes
- setSlicingActive(false);
- Abstract3DController::setSelectionMode(mode);
}
+void Surface3DController::setSelectedPoint(const QPoint &position)
+{
+ // If the selection targets non-existent point, clear selection instead.
+ QPoint pos = position;
+
+ const QSurfaceDataProxy *proxy = static_cast<const QSurfaceDataProxy *>(m_data);
+ if (pos != noSelectionPoint()) {
+ int maxRow = proxy->rowCount() - 1;
+ int maxCol = proxy->columnCount() - 1;
+
+ if (pos.x() < 0 || pos.x() > maxRow || pos.y() < 0 || pos.y() > maxCol)
+ pos = noSelectionPoint();
+ }
+
+ if (selectionMode().testFlag(QDataVis::SelectionSlice)) {
+ if (pos == noSelectionPoint()) {
+ scene()->setSlicingActive(false);
+ } else {
+ // If the selected point is outside data window, or there is no selected point, disable slicing
+ // TODO: (QTRD-2351) This logic doesn't match the renderer logic for non straight surfaces,
+ // but that logic needs to change anyway, so this is good for now.
+ float axisMinX = float(m_axisX->min());
+ float axisMaxX = float(m_axisX->max());
+ float axisMinZ = float(m_axisZ->min());
+ float axisMaxZ = float(m_axisZ->max());
+
+ // Comparisons between float and double are not accurate, so fudge our comparison values
+ //a little to get all rows and columns into view that need to be visible.
+ const float fudgeFactor = 0.00001f;
+ float fudgedAxisXRange = (axisMaxX - axisMinX) * fudgeFactor;
+ float fudgedAxisZRange = (axisMaxZ - axisMinZ) * fudgeFactor;
+ axisMinX -= fudgedAxisXRange;
+ axisMinZ -= fudgedAxisZRange;
+ axisMaxX += fudgedAxisXRange;
+ axisMaxZ += fudgedAxisZRange;
+ QSurfaceDataItem item = proxy->array()->at(pos.x())->at(pos.y());
+ if (item.x() < axisMinX || item.x() > axisMaxX
+ || item.z() < axisMinZ || item.z() > axisMaxZ) {
+ scene()->setSlicingActive(false);
+ } else {
+ scene()->setSlicingActive(true);
+ }
+ }
+ emitNeedRender();
+ }
+
+ if (pos != m_selectedPoint) {
+ m_selectedPoint = pos;
+ m_changeTracker.selectedPointChanged = true;
+ emit selectedPointChanged(pos);
+ emitNeedRender();
+ }
+}
+
+QPoint Surface3DController::selectedPoint() const
+{
+ return m_selectedPoint;
+}
void Surface3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
{
@@ -191,20 +276,31 @@ void Surface3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
QObject::connect(surfaceDataProxy, &QSurfaceDataProxy::arrayReset,
this, &Surface3DController::handleArrayReset);
- scene()->setSlicingActive(false);
adjustValueAxisRange();
+
+ // Always clear selection on proxy change
+ setSelectedPoint(noSelectionPoint());
+
m_isDataDirty = true;
emitNeedRender();
}
void Surface3DController::handleArrayReset()
{
- scene()->setSlicingActive(false);
adjustValueAxisRange();
m_isDataDirty = true;
+ // Clear selection unless still valid
+ setSelectedPoint(m_selectedPoint);
emitNeedRender();
}
+void Surface3DController::handlePointClicked(const QPoint &position)
+{
+ setSelectedPoint(position);
+ // TODO: pass clicked to parent. (QTRD-2517)
+ // TODO: Also hover needed? (QTRD-2131)
+}
+
void Surface3DController::adjustValueAxisRange()
{
if (m_data) {