summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine
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
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')
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp26
-rw-r--r--src/datavisualization/engine/abstract3dcontroller_p.h7
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp8
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h8
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp113
-rw-r--r--src/datavisualization/engine/bars3dcontroller_p.h21
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp271
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h14
-rw-r--r--src/datavisualization/engine/drawer.cpp9
-rw-r--r--src/datavisualization/engine/drawer_p.h7
-rw-r--r--src/datavisualization/engine/q3dbars.cpp21
-rw-r--r--src/datavisualization/engine/q3dbars.h19
-rw-r--r--src/datavisualization/engine/q3dscatter.cpp4
-rw-r--r--src/datavisualization/engine/q3dscatter.h10
-rw-r--r--src/datavisualization/engine/q3dsurface.cpp29
-rw-r--r--src/datavisualization/engine/q3dsurface.h18
-rw-r--r--src/datavisualization/engine/scatter3dcontroller.cpp37
-rw-r--r--src/datavisualization/engine/scatter3dcontroller_p.h5
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp64
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h10
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp118
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h16
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp191
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h16
24 files changed, 608 insertions, 434 deletions
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
index bfdc375e..5a9d8a7a 100644
--- a/src/datavisualization/engine/abstract3dcontroller.cpp
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -37,7 +37,7 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) :
m_boundingRect(boundRect.x(), boundRect.y(), boundRect.width(), boundRect.height()),
m_theme(),
m_font(QFont(QStringLiteral("Arial"))),
- m_selectionMode(QDataVis::SelectionModeItem),
+ m_selectionMode(QDataVis::SelectionItem),
m_shadowQuality(QDataVis::ShadowQualityMedium),
m_labelStyle(QDataVis::LabelStyleTransparent),
m_isBackgroundEnabled(true),
@@ -63,7 +63,7 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) :
inputHandler->d_ptr->m_isDefaultHandler = true;
setActiveInputHandler(inputHandler);
connect(inputHandler, &QAbstract3DInputHandler::inputStateChanged, this,
- &Abstract3DController::emitNeedRender);
+ &Abstract3DController::handleInputStateChanged);
connect(m_scene, &Q3DScene::needRender, this,
&Abstract3DController::emitNeedRender);
}
@@ -705,14 +705,16 @@ QFont Abstract3DController::font()
return m_font;
}
-void Abstract3DController::setSelectionMode(QDataVis::SelectionMode mode)
+void Abstract3DController::setSelectionMode(QDataVis::SelectionFlags mode)
{
- m_selectionMode = mode;
- m_changeTracker.selectionModeChanged = true;
- emitNeedRender();
+ if (mode != m_selectionMode) {
+ m_selectionMode = mode;
+ m_changeTracker.selectionModeChanged = true;
+ emitNeedRender();
+ }
}
-QDataVis::SelectionMode Abstract3DController::selectionMode()
+QDataVis::SelectionFlags Abstract3DController::selectionMode()
{
return m_selectionMode;
}
@@ -927,6 +929,16 @@ void Abstract3DController::handleAxisLabelFormatChanged(const QString &format)
handleAxisLabelFormatChangedBySender(sender());
}
+void Abstract3DController::handleInputStateChanged(QDataVis::InputState state)
+{
+ // When in automatic slicing mode, input state change to overview disables slice mode
+ if (m_selectionMode.testFlag(QDataVis::SelectionSlice)
+ && state == QDataVis::InputStateOnOverview) {
+ setSlicingActive(false);
+ }
+ emitNeedRender();
+}
+
void Abstract3DController::handleAxisLabelFormatChangedBySender(QObject *sender)
{
// Label format changing needs to dirty the data so that labels are reset.
diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h
index f17c6c4d..dd5a56ce 100644
--- a/src/datavisualization/engine/abstract3dcontroller_p.h
+++ b/src/datavisualization/engine/abstract3dcontroller_p.h
@@ -148,7 +148,7 @@ private:
GLfloat m_verticalRotation;
Theme m_theme;
QFont m_font;
- QDataVis::SelectionMode m_selectionMode;
+ QDataVis::SelectionFlags m_selectionMode;
QDataVis::ShadowQuality m_shadowQuality;
QDataVis::LabelStyle m_labelStyle;
bool m_isBackgroundEnabled;
@@ -254,8 +254,8 @@ public:
virtual QFont font();
// Selection mode
- virtual void setSelectionMode(QDataVis::SelectionMode mode);
- virtual QDataVis::SelectionMode selectionMode();
+ virtual void setSelectionMode(QDataVis::SelectionFlags mode);
+ virtual QDataVis::SelectionFlags selectionMode();
// Adjust shadow quality
virtual void setShadowQuality(QDataVis::ShadowQuality quality);
@@ -312,6 +312,7 @@ public slots:
void handleAxisSubSegmentCountChanged(int count);
void handleAxisAutoAdjustRangeChanged(bool autoAdjust);
void handleAxisLabelFormatChanged(const QString &format);
+ void handleInputStateChanged(QDataVis::InputState state);
signals:
void shadowQualityChanged(QDataVis::ShadowQuality quality);
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index eef810df..a11363a9 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -37,10 +37,11 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_cachedBoundingRect(QRect(0,0,0,0)),
m_cachedShadowQuality(QDataVis::ShadowQualityMedium),
m_autoScaleAdjustment(1.0f),
- m_cachedSelectionMode(QDataVis::SelectionModeNone),
+ m_cachedSelectionMode(QDataVis::SelectionNone),
m_cachedIsGridEnabled(false),
m_cachedIsBackgroundEnabled(false),
- m_cachedScene(new Q3DScene())
+ m_cachedScene(new Q3DScene()),
+ m_selectionDirty(true)
#ifdef DISPLAY_RENDER_SPEED
, m_isFirstFrame(true),
m_numFrames(0)
@@ -221,9 +222,10 @@ void Abstract3DRenderer::updateMeshFileName(const QString &objFileName)
}
}
-void Abstract3DRenderer::updateSelectionMode(QDataVis::SelectionMode mode)
+void Abstract3DRenderer::updateSelectionMode(QDataVis::SelectionFlags mode)
{
m_cachedSelectionMode = mode;
+ m_selectionDirty = true;
}
void Abstract3DRenderer::updateGridEnabled(bool enable)
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index 1c61ac07..b3ee6eac 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -42,6 +42,9 @@
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+static const QVector3D selectionSkipColor = QVector3D(255.0f, 255.0f, 255.0f); // Selection texture's background color
+static const QVector3D invalidColorVector = QVector3D(-1.0f, -1.0f, -1.0f);
+
class TextureHelper;
class Theme;
class Drawer;
@@ -65,7 +68,7 @@ protected:
QString m_cachedItemLabelFormat;
QString m_cachedObjFile;
- QDataVis::SelectionMode m_cachedSelectionMode;
+ QDataVis::SelectionFlags m_cachedSelectionMode;
bool m_cachedIsGridEnabled;
bool m_cachedIsBackgroundEnabled;
@@ -76,6 +79,7 @@ protected:
Q3DBox m_boundingBox;
Q3DScene *m_cachedScene;
+ bool m_selectionDirty;
#ifdef DISPLAY_RENDER_SPEED
bool m_isFirstFrame;
@@ -98,7 +102,7 @@ public:
virtual void updateTheme(Theme theme);
virtual void updateFont(const QFont &font);
virtual void updateLabelStyle(QDataVis::LabelStyle style);
- virtual void updateSelectionMode(QDataVis::SelectionMode newMode);
+ virtual void updateSelectionMode(QDataVis::SelectionFlags newMode);
virtual void updateGridEnabled(bool enable);
virtual void updateBackgroundEnabled(bool enable);
virtual void updateMeshFileName(const QString &objFileName);
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
index 2eea6c74..dc1a9401 100644
--- a/src/datavisualization/engine/bars3dcontroller.cpp
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -31,7 +31,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
Bars3DController::Bars3DController(QRect boundRect)
: Abstract3DController(boundRect),
- m_selectedBarPos(noSelectionPoint()),
+ m_selectedBar(noSelectionPoint()),
m_isBarSpecRelative(true),
m_barThicknessRatio(1.0f),
m_barSpacing(QSizeF(1.0, 1.0)),
@@ -65,8 +65,8 @@ void Bars3DController::initializeOpenGL()
setRenderer(m_renderer);
synchDataToRenderer();
- QObject::connect(m_renderer, &Bars3DRenderer::selectedBarPosChanged, this,
- &Bars3DController::handleSelectedBarPosChanged, Qt::QueuedConnection);
+ QObject::connect(m_renderer, &Bars3DRenderer::barClicked, this,
+ &Bars3DController::handleBarClicked, Qt::QueuedConnection);
emitNeedRender();
}
@@ -83,9 +83,9 @@ void Bars3DController::synchDataToRenderer()
m_changeTracker.barSpecsChanged = false;
}
- if (m_changeTracker.selectedBarPosChanged) {
- m_renderer->updateSelectedBarPos(m_selectedBarPos);
- m_changeTracker.selectedBarPosChanged = false;
+ if (m_changeTracker.selectedBarChanged) {
+ m_renderer->updateSelectedBar(m_selectedBar);
+ m_changeTracker.selectedBarChanged = false;
}
if (m_isDataDirty) {
@@ -125,11 +125,10 @@ void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
QObject::connect(barDataProxy, &QBarDataProxy::columnLabelsChanged, this,
&Bars3DController::handleDataColumnLabelsChanged);
- scene()->setSlicingActive(false);
adjustAxisRanges();
// Always clear selection on proxy change
- setSelectedBarPos(noSelectionPoint());
+ setSelectedBar(noSelectionPoint());
handleDataRowLabelsChanged();
handleDataColumnLabelsChanged();
@@ -139,11 +138,10 @@ void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
void Bars3DController::handleArrayReset()
{
- scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
// Clear selection unless still valid
- setSelectedBarPos(m_selectedBarPos);
+ setSelectedBar(m_selectedBar);
emitNeedRender();
}
@@ -151,8 +149,6 @@ void Bars3DController::handleRowsAdded(int startIndex, int count)
{
Q_UNUSED(startIndex)
Q_UNUSED(count)
- // TODO should update slice instead of deactivating?
- scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -162,8 +158,6 @@ void Bars3DController::handleRowsChanged(int startIndex, int count)
{
Q_UNUSED(startIndex)
Q_UNUSED(count)
- // TODO should update slice instead of deactivating?
- scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -173,13 +167,11 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count)
{
Q_UNUSED(startIndex)
Q_UNUSED(count)
- // TODO should update slice instead of deactivating?
- scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
// Clear selection unless still valid
- setSelectedBarPos(m_selectedBarPos);
+ setSelectedBar(m_selectedBar);
emitNeedRender();
}
@@ -188,8 +180,6 @@ void Bars3DController::handleRowsInserted(int startIndex, int count)
{
Q_UNUSED(startIndex)
Q_UNUSED(count)
- // TODO should update slice instead of deactivating?
- scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -199,8 +189,6 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex)
{
Q_UNUSED(rowIndex)
Q_UNUSED(columnIndex)
- // TODO should update slice instead of deactivating?
- scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -228,16 +216,11 @@ void Bars3DController::handleDataColumnLabelsChanged()
}
}
-void Bars3DController::handleSelectedBarPosChanged(const QPoint &position)
+void Bars3DController::handleBarClicked(const QPoint &position)
{
- QPoint pos = position;
- if (pos == QPoint(255, 255))
- pos = noSelectionPoint();
- if (pos != m_selectedBarPos) {
- m_selectedBarPos = pos;
- emit selectedBarPosChanged(pos);
- emitNeedRender();
- }
+ setSelectedBar(position);
+ // TODO: pass clicked to parent. (QTRD-2517)
+ // TODO: Also hover needed? (QTRD-2131)
}
void Bars3DController::handleAxisAutoAdjustRangeChangedInOrientation(
@@ -270,12 +253,6 @@ void Bars3DController::handleAxisRangeChangedBySender(QObject *sender)
{
// Data window changed
if (sender == m_axisX || sender == m_axisZ) {
- // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
- scene()->setSlicingActive(false);
-
- // Clear selection unless still valid
- setSelectedBarPos(m_selectedBarPos);
-
if (sender == m_axisX)
handleDataRowLabelsChanged();
if (sender == m_axisZ)
@@ -283,6 +260,9 @@ void Bars3DController::handleAxisRangeChangedBySender(QObject *sender)
}
Abstract3DController::handleAxisRangeChangedBySender(sender);
+
+ // Update selected bar - may be moved offscreen
+ setSelectedBar(m_selectedBar);
}
void Bars3DController::setBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative)
@@ -330,43 +310,62 @@ void Bars3DController::setBarType(QDataVis::MeshStyle style, bool smooth)
Abstract3DController::setMeshFileName(objFile);
}
-void Bars3DController::setSelectionMode(QDataVis::SelectionMode mode)
+void Bars3DController::setSelectionMode(QDataVis::SelectionFlags mode)
{
- // Disable zoom if selection mode changes
- scene()->setSlicingActive(false);
- Abstract3DController::setSelectionMode(mode);
+ 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_selectedBar != noSelectionPoint())
+ scene()->setSlicingActive(true);
+ else
+ scene()->setSlicingActive(false);
+ }
+
+ Abstract3DController::setSelectionMode(mode);
+ }
}
-void Bars3DController::setSelectedBarPos(const QPoint &position)
+void Bars3DController::setSelectedBar(const QPoint &position)
{
- // If the selection is outside data window or targets non-existent
- // bar, clear selection instead.
+ // If the selection targets non-existent bar, clear selection instead.
QPoint pos = position;
if (pos != noSelectionPoint()) {
- int minRow = int(m_axisX->min());
- int maxRow = int(m_axisX->max());
- int minCol = int(m_axisZ->min());
- int maxCol = int(m_axisZ->max());
-
- if (pos.x() < minRow || pos.x() > maxRow || pos.y() < minCol || pos.y() > maxCol
- || pos.x() + minRow >= static_cast<QBarDataProxy *>(m_data)->rowCount()
- || pos.y() + minCol >= static_cast<QBarDataProxy *>(m_data)->rowAt(pos.x())->size()) {
+ const QBarDataProxy *proxy = static_cast<const QBarDataProxy *>(m_data);
+ 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();
+ }
+
+ if (selectionMode().testFlag(QDataVis::SelectionSlice)) {
+ // If the selected bar is outside data window, or there is no selected bar, disable slicing
+ if (pos.x() < m_axisX->min() || pos.x() > m_axisX->max()
+ || pos.y() < m_axisZ->min() || pos.y() > m_axisZ->max()) {
+ scene()->setSlicingActive(false);
+ } else {
+ scene()->setSlicingActive(true);
}
+ emitNeedRender();
}
- if (pos != m_selectedBarPos) {
- m_selectedBarPos = pos;
- m_changeTracker.selectedBarPosChanged = true;
- emit selectedBarPosChanged(pos);
+ if (pos != m_selectedBar) {
+ m_selectedBar = pos;
+ m_changeTracker.selectedBarChanged = true;
+ emit selectedBarChanged(pos);
emitNeedRender();
}
}
-QPoint Bars3DController::selectedBarPos() const
+QPoint Bars3DController::selectedBar() const
{
- return m_selectedBarPos;
+ return m_selectedBar;
}
void Bars3DController::adjustAxisRanges()
diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h
index 8398dd81..2e751053 100644
--- a/src/datavisualization/engine/bars3dcontroller_p.h
+++ b/src/datavisualization/engine/bars3dcontroller_p.h
@@ -42,12 +42,12 @@ class QBarDataProxy;
struct Bars3DChangeBitField {
bool slicingActiveChanged : 1;
bool barSpecsChanged : 1;
- bool selectedBarPosChanged : 1;
+ bool selectedBarChanged : 1;
Bars3DChangeBitField() :
slicingActiveChanged(true),
barSpecsChanged(true),
- selectedBarPosChanged(true)
+ selectedBarChanged(true)
{
}
};
@@ -60,7 +60,7 @@ private:
Bars3DChangeBitField m_changeTracker;
// Interaction
- QPoint m_selectedBarPos; // Points to row & column in data window.
+ QPoint m_selectedBar; // Points to row & column in data window.
// Look'n'feel
bool m_isBarSpecRelative;
@@ -86,15 +86,11 @@ public:
GLfloat barThickness();
QSizeF barSpacing();
bool isBarSpecRelative();
-
- // bar type; bars (=cubes), pyramids, cones, cylinders, etc.
void setBarType(QDataVis::MeshStyle style, bool smooth = false);
- // Change selection mode; single bar, bar and row, bar and column, or all
- void setSelectionMode(QDataVis::SelectionMode mode);
-
- void setSelectedBarPos(const QPoint &position);
- QPoint selectedBarPos() const;
+ void setSelectionMode(QDataVis::SelectionFlags mode);
+ void setSelectedBar(const QPoint &position);
+ QPoint selectedBar() const;
virtual void setActiveDataProxy(QAbstractDataProxy *proxy);
@@ -116,11 +112,10 @@ public slots:
void handleItemChanged(int rowIndex, int columnIndex);
void handleDataRowLabelsChanged();
void handleDataColumnLabelsChanged();
-
- void handleSelectedBarPosChanged(const QPoint &position);
+ void handleBarClicked(const QPoint &position);
signals:
- void selectedBarPosChanged(QPoint position);
+ void selectedBarChanged(QPoint position);
protected:
virtual Q3DAbstractAxis *createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation);
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 0b0ae9aa..8e8a4e93 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -42,7 +42,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
const GLfloat labelMargin = 0.05f;
const GLfloat gridLineWidth = 0.005f;
-static QVector3D selectionSkipColor = QVector3D(255, 255, 255); // Selection texture's background color
const int smallerVPSize = 5;
Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
@@ -51,6 +50,7 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
m_cachedIsSlicingActivated(false),
m_cachedRowCount(0),
m_cachedColumnCount(0),
+ m_cachedInputState(QDataVis::InputStateNone),
m_selectedBar(0),
m_sliceSelection(0),
m_sliceCache(0),
@@ -85,9 +85,10 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
m_scaleZ(0),
m_scaleFactor(0),
m_maxSceneSize(40.0f),
- m_selection(selectionSkipColor),
- m_previousSelection(selectionSkipColor),
- m_hasHeightAdjustmentChanged(true)
+ m_visualSelectedBarPos(Bars3DController::noSelectionPoint()),
+ m_clickedBarColor(invalidColorVector),
+ m_hasHeightAdjustmentChanged(true),
+ m_selectedBarPos(Bars3DController::noSelectionPoint())
{
initializeOpenGLFunctions();
initializeOpenGL();
@@ -207,6 +208,9 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy)
m_renderColumns = updateSize;
m_renderRows = qMin((dataRowCount - minRow), m_renderItemArray.size());
+ // Reset selected bar to update selection
+ updateSelectedBar(m_selectedBarPos);
+
Abstract3DRenderer::updateDataModel(dataProxy);
}
@@ -243,6 +247,15 @@ void Bars3DRenderer::render(GLuint defaultFboHandle)
{
bool slicingChanged = m_cachedIsSlicingActivated != m_cachedScene->isSlicingActive();
+ // TODO: Can't call back to controller here! (QTRD-2216)
+ // TODO: Needs to be added to synchronization
+ QDataVis::InputState currentInputState = m_controller->inputState();
+ if (currentInputState != m_cachedInputState) {
+ if (currentInputState == QDataVis::InputStateOnScene)
+ m_clickedBarColor = invalidColorVector;
+ m_cachedInputState = currentInputState;
+ }
+
// Handle GL state setup for FBO buffers and clearing of the render surface
Abstract3DRenderer::render(defaultFboHandle);
@@ -253,10 +266,9 @@ void Bars3DRenderer::render(GLuint defaultFboHandle)
if (m_cachedIsSlicingActivated)
drawSlicedScene(m_axisCacheX.titleItem(), m_axisCacheY.titleItem(), m_axisCacheZ.titleItem());
- // If slicing has been activated by this render pass, we need another render
- // Also trigger another render always when slicing changes in general to ensure
+ // Trigger another render always when slicing changes in general to ensure
// final draw is correct.
- if (m_cachedIsSlicingActivated != m_cachedScene->isSlicingActive() || slicingChanged)
+ if (slicingChanged)
emit needRender();
}
@@ -313,6 +325,9 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
QVector3D barHighlightColor(Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor));
QVector3D rowHighlightColor(Utils::vectorFromColor(m_cachedTheme.m_highlightRowColor));
QVector3D columnHighlightColor(Utils::vectorFromColor(m_cachedTheme.m_highlightColumnColor));
+ bool rowMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionRow);
+ bool itemMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionItem);
+
for (int bar = startBar; bar != stopBar; bar += stepBar) {
BarRenderItem *item = m_sliceSelection->at(bar);
if (!item)
@@ -328,7 +343,7 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
QMatrix4x4 itModelMatrix;
GLfloat barPosY = negativesComp * item->translation().y() - barPosYAdjustment;
- if (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode)
+ if (rowMode)
barPosX = item->translation().x();
else
barPosX = -(item->translation().z()); // flip z; frontmost bar to the left
@@ -341,23 +356,27 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
#if 0
QVector3D baseColor;
- if (m_selection.x() == item->position().x() && m_selection.y() == item->position().y())
+ if (m_visualSelectedBarPos.x() == item->position().x()
+ && m_visualSelectedBarPos.y() == item->position().y()) {
baseColor = barHighlightColor;
- else if (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode)
+ } else if (QDataVis::SelectionSliceRow == m_cachedSelectionMode) {
baseColor = rowHighlightColor;
- else
+ } else {
baseColor = columnHighlightColor;
+ }
QVector3D heightColor = Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item->height();
QVector3D barColor = baseColor + heightColor;
#else
QVector3D barColor;
- if (m_selection.x() == item->position().x() && m_selection.y() == item->position().y())
+ if (itemMode && m_visualSelectedBarPos.x() == item->position().x()
+ && m_visualSelectedBarPos.y() == item->position().y()) {
barColor = barHighlightColor;
- else if (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode)
+ } else if (rowMode) {
barColor = rowHighlightColor;
- else
+ } else {
barColor = columnHighlightColor;
+ }
#endif
if (item->height() != 0) {
@@ -394,6 +413,10 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
QVector3D negativesRotation(0.0f, 0.0f, 90.0f);
QVector3D sliceLabelRotation(0.0f, 0.0f, -45.0f);
GLfloat negativesCompPow2 = negativesComp * negativesComp;
+
+ // Labels in axis caches can be in inverted order depending in orientation
+ bool flipped = (m_xFlipped && rowMode) || (m_zFlipped && !rowMode);
+
for (int col = 0; col < stopBar; col++) {
BarRenderItem *item = m_sliceSelection->at(col);
// Draw values
@@ -401,46 +424,53 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix,
valuePositionComp, negativesRotation, item->height(),
m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera,
- false, false, Drawer::LabelOver, Qt::AlignTop);
+ false, false, Drawer::LabelOver, Qt::AlignTop, true);
} else {
m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix,
valuePositionComp, zeroVector, negativesCompPow2 * item->height(),
- m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera);
+ m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera,
+ false, false, Drawer::LabelOver, Qt::AlignCenter, true);
}
// Draw labels
if (m_sliceCache->labelItems().size() > col) {
- m_drawer->drawLabel(*item, *m_sliceCache->labelItems().at(col), viewMatrix,
+ int labelIndex = flipped ? m_sliceCache->labelItems().size() - 1 - col : col;
+ m_drawer->drawLabel(*item, *m_sliceCache->labelItems().at(labelIndex), viewMatrix,
projectionMatrix, positionComp, sliceLabelRotation,
item->height(), m_cachedSelectionMode, m_labelShader,
- m_labelObj, activeCamera, false, false, Drawer::LabelBelow);
+ m_labelObj, activeCamera, false, false, Drawer::LabelBelow,
+ Qt::AlignCenter, true);
}
}
// Draw labels for axes
- if (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode) {
+ if (rowMode) {
if (m_sliceTitleItem) {
m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader,
- m_labelObj, activeCamera, false, false, Drawer::LabelTop);
+ m_labelObj, activeCamera, false, false, Drawer::LabelTop,
+ Qt::AlignCenter, true);
}
m_drawer->drawLabel(*dummyItem, zLabel, viewMatrix, projectionMatrix,
positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader,
- m_labelObj, activeCamera, false, false, Drawer::LabelBottom);
+ m_labelObj, activeCamera, false, false, Drawer::LabelBottom,
+ Qt::AlignCenter, true);
} else {
m_drawer->drawLabel(*dummyItem, xLabel, viewMatrix, projectionMatrix,
positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader,
- m_labelObj, activeCamera, false, false, Drawer::LabelBottom);
+ m_labelObj, activeCamera, false, false, Drawer::LabelBottom,
+ Qt::AlignCenter, true);
if (m_sliceTitleItem) {
m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader,
- m_labelObj, activeCamera, false, false, Drawer::LabelTop);
+ m_labelObj, activeCamera, false, false, Drawer::LabelTop,
+ Qt::AlignCenter, true);
}
}
m_drawer->drawLabel(*dummyItem, yLabel, viewMatrix, projectionMatrix,
positionComp, QVector3D(0.0f, 0.0f, 90.0f), 0,
m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera,
- false, false, Drawer::LabelLeft);
+ false, false, Drawer::LabelLeft, Qt::AlignCenter, true);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
@@ -532,6 +562,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
+ bool rowMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionRow);
+
#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// Render scene into a depth texture for using with shadow mapping
@@ -654,8 +686,10 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
#endif
+ // TODO: Selection must be enabled currently to support clicked signal. (QTRD-2517)
// Skip selection mode drawing if we're slicing or have no selection mode
- if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QDataVis::SelectionModeNone) {
+ if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QDataVis::SelectionNone
+ && m_cachedInputState == QDataVis::InputStateOnScene) {
// Bind selection shader
m_selectionShader->bind();
@@ -724,9 +758,12 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
glEnable(GL_DITHER);
// Read color under cursor
- if (QDataVis::InputStateOnScene == m_controller->inputState()) {
- m_selection = Utils::getSelection(m_controller->inputPosition(),
- m_cachedBoundingRect.height());
+ // TODO: Can't call back to controller here! (QTRD-2216)
+ QVector3D clickedColor = Utils::getSelection(m_controller->inputPosition(),
+ m_cachedBoundingRect.height());
+ if (m_clickedBarColor == invalidColorVector) {
+ m_clickedBarColor = clickedColor;
+ emit barClicked(selectionColorToArrayPosition(m_clickedBarColor));
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -762,21 +799,20 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
m_barShader->setUniformValue(m_barShader->ambientS(),
m_cachedTheme.m_ambientStrength);
- bool selectionDirty = (m_selection != m_previousSelection
- || (m_selection != selectionSkipColor
- && QDataVis::InputStateOnScene == m_controller->inputState()
- && !m_cachedIsSlicingActivated));
- if (selectionDirty) {
- m_previousSelection = m_selection;
- if (m_sliceSelection) {
- if (!m_cachedIsSlicingActivated) {
- m_sliceCache = 0;
- m_sliceTitleItem = 0;
- }
- if (m_sliceSelection->size()) {
+
+ // TODO: Can't call back to controller here! (QTRD-2216)
+ if (m_selectionDirty) {
+ if (m_cachedIsSlicingActivated) {
+ if (m_sliceSelection && m_sliceSelection->size()) {
// Slice doesn't own its items, no need to delete them - just clear
m_sliceSelection->clear();
}
+ // Set slice cache, i.e. axis cache from where slice labels are taken
+ if (rowMode)
+ m_sliceCache = &m_axisCacheZ;
+ else
+ m_sliceCache = &m_axisCacheX;
+ m_sliceTitleItem = 0;
}
}
@@ -792,6 +828,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
bool barSelectionFound = false;
BarRenderItem *selectedBar(0);
QVector3D modelScaler(m_scaleX, 0.0f, m_scaleZ);
+ bool somethingSelected = (m_visualSelectedBarPos != Bars3DController::noSelectionPoint());
for (int row = startRow; row != stopRow; row += stepRow) {
for (int bar = startBar; bar != stopBar; bar += stepBar) {
BarRenderItem &item = m_renderItemArray[row][bar];
@@ -834,8 +871,10 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
GLfloat lightStrength = m_cachedTheme.m_lightStrength;
GLfloat shadowLightStrength = adjustedLightStrength;
- if (m_cachedSelectionMode > QDataVis::SelectionModeNone) {
- Bars3DController::SelectionType selectionType = isSelected(row, bar);
+ if (m_cachedSelectionMode > QDataVis::SelectionNone) {
+ Bars3DController::SelectionType selectionType = Bars3DController::SelectionNone;
+ if (somethingSelected)
+ selectionType = isSelected(row, bar);
switch (selectionType) {
case Bars3DController::SelectionItem: {
@@ -849,26 +888,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
item.setTranslation(modelMatrix.column(3).toVector3D());
barSelectionFound = true;
}
- if (selectionDirty && m_cachedSelectionMode >= QDataVis::SelectionModeSliceRow) {
+ if (m_selectionDirty && m_cachedIsSlicingActivated) {
item.setTranslation(modelMatrix.column(3).toVector3D());
item.setPosition(QPoint(row, bar));
m_sliceSelection->append(&item);
barSelectionFound = true;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
- if (m_axisCacheX.labelItems().size() > row)
- m_sliceTitleItem = m_axisCacheX.labelItems().at(row);
- if (!m_sliceCache) {
- // m_sliceCache is the axis for labels, while title comes from different axis.
- m_sliceCache = &m_axisCacheZ;
- }
- } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
- if (m_axisCacheZ.labelItems().size() > bar)
- m_sliceTitleItem = m_axisCacheZ.labelItems().at(bar);
- if (!m_sliceCache) {
- // m_sliceCache is the axis for labels, while title comes from different axis.
- m_sliceCache = &m_axisCacheX;
- }
- }
}
break;
}
@@ -877,11 +901,14 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
barColor = rowHighlightColor;
lightStrength = m_cachedTheme.m_highlightLightStrength;
shadowLightStrength = adjustedHighlightStrength;
- if (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode) {
+ if (m_cachedIsSlicingActivated) {
item.setTranslation(modelMatrix.column(3).toVector3D());
item.setPosition(QPoint(row, bar));
- if (selectionDirty && bar < m_renderColumns)
+ if (m_selectionDirty && bar < m_renderColumns) {
+ if (!m_sliceTitleItem && m_axisCacheX.labelItems().size() > row)
+ m_sliceTitleItem = m_axisCacheX.labelItems().at(row);
m_sliceSelection->append(&item);
+ }
}
break;
}
@@ -890,11 +917,14 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
barColor = columnHighlightColor;
lightStrength = m_cachedTheme.m_highlightLightStrength;
shadowLightStrength = adjustedHighlightStrength;
- if (QDataVis::SelectionModeSliceColumn == m_cachedSelectionMode) {
+ if (m_cachedIsSlicingActivated) {
item.setTranslation(modelMatrix.column(3).toVector3D());
item.setPosition(QPoint(row, bar));
- if (selectionDirty && row < m_renderRows)
+ if (m_selectionDirty && row < m_renderRows) {
+ if (!m_sliceTitleItem && m_axisCacheZ.labelItems().size() > bar)
+ m_sliceTitleItem = m_axisCacheZ.labelItems().at(bar);
m_sliceSelection->append(&item);
+ }
}
break;
}
@@ -938,9 +968,6 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
- if (selectionDirty)
- emit selectedBarPosChanged(QPoint(int(m_selection.x()), int(m_selection.y())));
-
// Release bar shader
m_barShader->release();
@@ -1292,7 +1319,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
positionComp, labelRotation, 0, m_cachedSelectionMode,
m_labelShader, m_labelObj, activeCamera,
- true, true, Drawer::LabelMid, alignment);
+ true, true, Drawer::LabelMid, alignment, m_cachedIsSlicingActivated);
}
}
labelRotation = QVector3D(-90.0f, 90.0f, 0.0f);
@@ -1307,7 +1334,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
alignment = m_zFlipped ? Qt::AlignRight : Qt::AlignLeft;
- for (int column = 0; column != m_cachedColumnCount; column += 1) {
+ for (int column = 0; column != m_cachedColumnCount; column++) {
if (m_axisCacheZ.labelItems().size() > column) {
// Go through all columns and get position of max+1 or min-1 row, depending on z flip
// We need only positions for them, labels have already been generated at QDataSetPrivate. Just add LabelItems
@@ -1394,19 +1421,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
glDisable(GL_POLYGON_OFFSET_FILL);
- // Handle slice activation and selection label drawing
- if (!barSelectionFound) {
- // We have no ownership, don't delete. Just NULL the pointer.
- m_selectedBar = NULL;
- if (m_cachedIsSlicingActivated
- && (m_selection == selectionSkipColor
- || QDataVis::InputStateOnOverview == m_controller->inputState())) {
- m_cachedScene->setSlicingActive(false);
- }
- } else if (m_cachedSelectionMode >= QDataVis::SelectionModeSliceRow && selectionDirty) {
- // Activate slice mode
- m_cachedScene->setSlicingActive(true);
-
+ // Handle slice and bar label generation
+ if (m_cachedIsSlicingActivated && m_selectionDirty) {
// Create label textures
for (int col = 0; col < m_sliceSelection->size(); col++) {
BarRenderItem *item = m_sliceSelection->at(col);
@@ -1414,7 +1430,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), item->value()));
m_drawer->generateLabelItem(item->sliceLabelItem(), item->sliceLabel());
}
- } else {
+ } else if (barSelectionFound) {
// Print value of selected bar
glDisable(GL_DEPTH_TEST);
// Draw the selection label
@@ -1473,6 +1489,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
m_updateLabels = false;
glEnable(GL_DEPTH_TEST);
+ } else {
+ m_selectedBar = 0;
}
glDisable(GL_TEXTURE_2D);
@@ -1480,6 +1498,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
// Release label shader
m_labelShader->release();
+
+ m_selectionDirty = false;
}
void Bars3DRenderer::handleResize()
@@ -1536,20 +1556,6 @@ void Bars3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientatio
}
}
-void Bars3DRenderer::updateSelectionMode(QDataVis::SelectionMode mode)
-{
- Abstract3DRenderer::updateSelectionMode(mode);
-
- // Create zoom selection if there isn't one
- if (mode >= QDataVis::SelectionModeSliceRow && !m_sliceSelection) {
- m_sliceSelection = new QList<BarRenderItem *>;
- if (mode == QDataVis::SelectionModeSliceRow)
- m_sliceSelection->reserve(m_cachedRowCount);
- else
- m_sliceSelection->reserve(m_cachedColumnCount);
- }
-}
-
void Bars3DRenderer::updateBackgroundEnabled(bool enable)
{
if (enable != m_cachedIsBackgroundEnabled) {
@@ -1558,13 +1564,23 @@ void Bars3DRenderer::updateBackgroundEnabled(bool enable)
}
}
-void Bars3DRenderer::updateSelectedBarPos(const QPoint &position)
+void Bars3DRenderer::updateSelectedBar(const QPoint &position)
{
- if (position == Bars3DController::noSelectionPoint())
- m_selection = selectionSkipColor;
- else
- m_selection = QVector3D(position.x(), position.y(), 0);
- emit needRender();
+ m_selectedBarPos = position;
+
+ int adjustedX = m_selectedBarPos.x() - int(m_axisCacheX.min());
+ int adjustedZ = m_selectedBarPos.y() - int(m_axisCacheZ.min());
+ int maxX = m_renderItemArray.size() - 1;
+ int maxZ = maxX >= 0 ? m_renderItemArray.at(0).size() - 1 : -1;
+
+ if (m_selectedBarPos == Bars3DController::noSelectionPoint()
+ || adjustedX < 0 || adjustedX > maxX
+ || adjustedZ < 0 || adjustedZ > maxZ) {
+ m_visualSelectedBarPos = Bars3DController::noSelectionPoint();
+ } else {
+ m_visualSelectedBarPos = QPoint(adjustedX, adjustedZ);
+ }
+ m_selectionDirty = true;
}
void Bars3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
@@ -1684,41 +1700,33 @@ void Bars3DRenderer::calculateHeightAdjustment()
Bars3DController::SelectionType Bars3DRenderer::isSelected(GLint row, GLint bar)
{
- //static QVector3D prevSel = m_selection; // TODO: For debugging
Bars3DController::SelectionType isSelectedType = Bars3DController::SelectionNone;
- if (m_selection == selectionSkipColor)
- return isSelectedType; // skip window
-
- //#if !defined(QT_OPENGL_ES_2)
- // QVector3D current = QVector3D((GLuint)row, (GLuint)bar, 0);
- //#else
- QVector3D current = QVector3D((GLubyte)row, (GLubyte)bar, 0);
- //#endif
-
- // TODO: For debugging
- //if (selection != prevSel) {
- // qDebug() << "current" << current.x() << current .y() << current.z();
- // qDebug() << "selection" << selection.x() << selection .y() << selection.z();
- // prevSel = selection;
- //}
- if (current == m_selection) {
+
+ if (row == m_visualSelectedBarPos.x() && bar == m_visualSelectedBarPos.y()
+ && (m_cachedSelectionMode.testFlag(QDataVis::SelectionItem))) {
isSelectedType = Bars3DController::SelectionItem;
- }
- else if (current.y() == m_selection.y()
- && (m_cachedSelectionMode == QDataVis::SelectionModeItemAndColumn
- || m_cachedSelectionMode == QDataVis::SelectionModeItemRowAndColumn
- || m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn)) {
- isSelectedType = Bars3DController::SelectionColumn;
- }
- else if (current.x() == m_selection.x()
- && (m_cachedSelectionMode == QDataVis::SelectionModeItemAndRow
- || m_cachedSelectionMode == QDataVis::SelectionModeItemRowAndColumn
- || m_cachedSelectionMode == QDataVis::SelectionModeSliceRow)) {
+ } else if (row == m_visualSelectedBarPos.x()
+ && (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow))) {
isSelectedType = Bars3DController::SelectionRow;
+ } else if (bar == m_visualSelectedBarPos.y()
+ && (m_cachedSelectionMode.testFlag(QDataVis::SelectionColumn))) {
+ isSelectedType = Bars3DController::SelectionColumn;
}
return isSelectedType;
}
+QPoint Bars3DRenderer::selectionColorToArrayPosition(const QVector3D &selectionColor)
+{
+ QPoint position;
+ if (selectionColor == selectionSkipColor) {
+ position = Bars3DController::noSelectionPoint();
+ } else {
+ position = QPoint(int(selectionColor.x() + int(m_axisCacheX.min())),
+ int(selectionColor.y()) + int(m_axisCacheZ.min()));
+ }
+ return position;
+}
+
void Bars3DRenderer::updateSlicingActive(bool isSlicing)
{
if (isSlicing == m_cachedIsSlicingActivated)
@@ -1726,6 +1734,9 @@ void Bars3DRenderer::updateSlicingActive(bool isSlicing)
m_cachedIsSlicingActivated = isSlicing;
+ if (m_cachedIsSlicingActivated && !m_sliceSelection)
+ m_sliceSelection = new QList<BarRenderItem *>;
+
setViewPorts();
if (!m_cachedIsSlicingActivated)
@@ -1734,6 +1745,8 @@ void Bars3DRenderer::updateSlicingActive(bool isSlicing)
#if !defined(QT_OPENGL_ES_2)
updateDepthBuffer(); // Re-init depth buffer as well
#endif
+
+ m_selectionDirty = true;
}
void Bars3DRenderer::setViewPorts()
diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index dd80902a..5d186a7d 100644
--- a/src/datavisualization/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -60,6 +60,7 @@ private:
bool m_cachedIsSlicingActivated;
int m_cachedRowCount;
int m_cachedColumnCount;
+ QDataVis::InputState m_cachedInputState;
// Internal state
BarRenderItem *m_selectedBar; // points to renderitem array
@@ -98,14 +99,13 @@ private:
GLfloat m_scaleZ;
GLfloat m_scaleFactor;
GLfloat m_maxSceneSize;
- QVector3D m_selection;
- QVector3D m_previousSelection;
+ QPoint m_visualSelectedBarPos; // The selection id color
int m_renderRows;
int m_renderColumns;
-
+ QVector3D m_clickedBarColor;
+ QPoint m_selectedBarPos;
bool m_hasHeightAdjustmentChanged;
BarRenderItem m_dummyBarRenderItem;
-
BarRenderItemArray m_renderItemArray;
public:
@@ -126,16 +126,15 @@ public slots:
void updateBarSpecs(GLfloat thicknessRatio = 1.0f,
const QSizeF &spacing = QSizeF(1.0, 1.0),
bool relative = true);
- void updateSelectionMode(QDataVis::SelectionMode newMode);
void updateSlicingActive(bool isSlicing);
void updateBackgroundEnabled(bool enable);
- void updateSelectedBarPos(const QPoint &position);
+ void updateSelectedBar(const QPoint &position);
// Overloaded from abstract renderer
virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
signals:
- void selectedBarPosChanged(QPoint position);
+ void barClicked(QPoint position);
private:
virtual void initShaders(const QString &vertexShader, const QString &fragmentShader);
@@ -161,6 +160,7 @@ private:
void calculateSceneScalingFactors();
void calculateHeightAdjustment();
Abstract3DController::SelectionType isSelected(GLint row, GLint bar);
+ QPoint selectionColorToArrayPosition(const QVector3D &selectionColor);
Q_DISABLE_COPY(Bars3DRenderer)
diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp
index 418dba77..61454bd8 100644
--- a/src/datavisualization/engine/drawer.cpp
+++ b/src/datavisualization/engine/drawer.cpp
@@ -164,11 +164,10 @@ void Drawer::drawSurfaceGrid(ShaderHelper *shader, SurfaceObject *object)
void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem,
const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix,
const QVector3D &positionComp, const QVector3D &rotation,
- GLfloat itemHeight, QDataVis::SelectionMode mode,
+ GLfloat itemHeight, QDataVis::SelectionFlags mode,
ShaderHelper *shader, ObjectHelper *object,
- const Q3DCamera *camera,
- bool useDepth, bool rotateAlong,
- LabelPosition position, Qt::AlignmentFlag alignment)
+ const Q3DCamera *camera, bool useDepth, bool rotateAlong,
+ LabelPosition position, Qt::AlignmentFlag alignment, bool isSlicing)
{
// Draw label
if (!labelItem.textureId())
@@ -275,7 +274,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
xPosition = item.translation().x();
if (useDepth)
zPosition = item.translation().z();
- else if (QDataVis::SelectionModeSliceColumn == mode)
+ else if (mode.testFlag(QDataVis::SelectionColumn) && isSlicing)
xPosition = -(item.translation().z()) + positionComp.z(); // flip first to left
}
diff --git a/src/datavisualization/engine/drawer_p.h b/src/datavisualization/engine/drawer_p.h
index 89a4ce8c..933b20c7 100644
--- a/src/datavisualization/engine/drawer_p.h
+++ b/src/datavisualization/engine/drawer_p.h
@@ -80,11 +80,10 @@ public:
void drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem,
const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix,
const QVector3D &positionComp, const QVector3D &rotation, GLfloat itemHeight,
- QDataVis::SelectionMode mode, ShaderHelper *shader, ObjectHelper *object,
- const Q3DCamera *camera,
- bool useDepth = false, bool rotateAlong = false,
+ QDataVis::SelectionFlags mode, ShaderHelper *shader, ObjectHelper *object,
+ const Q3DCamera *camera, bool useDepth = false, bool rotateAlong = false,
LabelPosition position = LabelOver,
- Qt::AlignmentFlag alignment = Qt::AlignCenter);
+ Qt::AlignmentFlag alignment = Qt::AlignCenter, bool isSlicing = false);
void generateSelectionLabelTexture(AbstractRenderItem *item);
void generateLabelItem(LabelItem &item, const QString &text, int widestLabel = 0);
diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp
index d6b48e03..086bfc82 100644
--- a/src/datavisualization/engine/q3dbars.cpp
+++ b/src/datavisualization/engine/q3dbars.cpp
@@ -102,8 +102,8 @@ Q3DBars::Q3DBars()
{
setVisualController(d_ptr->m_shared);
d_ptr->m_shared->initializeOpenGL();
- QObject::connect(d_ptr->m_shared, &Bars3DController::selectedBarPosChanged, this,
- &Q3DBars::selectedBarPosChanged);
+ QObject::connect(d_ptr->m_shared, &Bars3DController::selectedBarChanged, this,
+ &Q3DBars::selectedBarChanged);
QObject::connect(d_ptr->m_shared, &Abstract3DController::needRender, this,
&Q3DWindow::renderLater);
}
@@ -297,12 +297,12 @@ QColor Q3DBars::barColor() const
* Sets bar selection \a mode to one of \c QDataVis::SelectionMode. It is preset to
* \c QDataVis::SelectionModeItem by default.
*/
-void Q3DBars::setSelectionMode(QDataVis::SelectionMode mode)
+void Q3DBars::setSelectionMode(QDataVis::SelectionFlags mode)
{
d_ptr->m_shared->setSelectionMode(mode);
}
-QDataVis::SelectionMode Q3DBars::selectionMode() const
+QDataVis::SelectionFlags Q3DBars::selectionMode() const
{
return d_ptr->m_shared->selectionMode();
}
@@ -398,20 +398,21 @@ bool Q3DBars::isBackgroundVisible() const
}
/*!
- * \property Q3DBars::selectedBarPos
+ * \property Q3DBars::selectedBar
*
- * Selects a bar in a \a position. The position is the position in data window.
+ * Selects a bar in a \a position. The position is the (row, column) position in
+ * the data array of the active data proxy.
* Only one bar can be selected at a time.
* To clear selection, specify an illegal \a position, e.g. (-1, -1).
*/
-void Q3DBars::setSelectedBarPos(const QPoint &position)
+void Q3DBars::setSelectedBar(const QPoint &position)
{
- d_ptr->m_shared->setSelectedBarPos(position);
+ d_ptr->m_shared->setSelectedBar(position);
}
-QPoint Q3DBars::selectedBarPos() const
+QPoint Q3DBars::selectedBar() const
{
- return d_ptr->m_shared->selectedBarPos();
+ return d_ptr->m_shared->selectedBar();
}
/*!
diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h
index d0ddf3fb..51c35257 100644
--- a/src/datavisualization/engine/q3dbars.h
+++ b/src/datavisualization/engine/q3dbars.h
@@ -35,7 +35,7 @@ class Q3DScene;
class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow
{
Q_OBJECT
- Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode)
Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle)
Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged)
Q_PROPERTY(qreal barThickness READ barThickness WRITE setBarThickness)
@@ -45,14 +45,9 @@ class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow
Q_PROPERTY(QFont font READ font WRITE setFont)
Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
- Q_PROPERTY(QPoint selectedBarPos READ selectedBarPos WRITE setSelectedBarPos NOTIFY selectedBarPosChanged)
+ Q_PROPERTY(QPoint selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged)
Q_PROPERTY(Q3DScene* scene READ scene)
- Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
- Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
- Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
- Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
-
public:
explicit Q3DBars();
~Q3DBars();
@@ -76,8 +71,8 @@ public:
void setMeshFileName(const QString &objFileName);
QString meshFileName() const;
- void setSelectionMode(QDataVis::SelectionMode mode);
- QDataVis::SelectionMode selectionMode() const;
+ void setSelectionMode(QDataVis::SelectionFlags mode);
+ QDataVis::SelectionFlags selectionMode() const;
void setFont(const QFont &font);
QFont font() const;
@@ -96,8 +91,8 @@ public:
void setBackgroundVisible(bool visible);
bool isBackgroundVisible() const;
- void setSelectedBarPos(const QPoint &position);
- QPoint selectedBarPos() const;
+ void setSelectedBar(const QPoint &position);
+ QPoint selectedBar() const;
void setShadowQuality(QDataVis::ShadowQuality quality);
QDataVis::ShadowQuality shadowQuality() const;
@@ -120,7 +115,7 @@ public:
signals:
void shadowQualityChanged(QDataVis::ShadowQuality quality);
- void selectedBarPosChanged(QPoint position);
+ void selectedBarChanged(QPoint position);
protected:
diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp
index fc95842a..aa67498e 100644
--- a/src/datavisualization/engine/q3dscatter.cpp
+++ b/src/datavisualization/engine/q3dscatter.cpp
@@ -232,12 +232,12 @@ QColor Q3DScatter::objectColor() const
* Sets item selection \a mode to one of \c QDataVis::SelectionMode. It is preset to
* \c QDataVis::SelectionModeItem by default.
*/
-void Q3DScatter::setSelectionMode(QDataVis::SelectionMode mode)
+void Q3DScatter::setSelectionMode(QDataVis::SelectionFlags mode)
{
d_ptr->m_shared->setSelectionMode(mode);
}
-QDataVis::SelectionMode Q3DScatter::selectionMode() const
+QDataVis::SelectionFlags Q3DScatter::selectionMode() const
{
return d_ptr->m_shared->selectionMode();
}
diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h
index fdea604e..0241f439 100644
--- a/src/datavisualization/engine/q3dscatter.h
+++ b/src/datavisualization/engine/q3dscatter.h
@@ -35,7 +35,7 @@ class QScatterDataProxy;
class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow
{
Q_OBJECT
- Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode)
Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle)
Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
@@ -44,10 +44,6 @@ class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow
Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
Q_PROPERTY(int selectedItemIndex READ selectedItemIndex WRITE setSelectedItemIndex NOTIFY selectedItemIndexChanged)
Q_PROPERTY(Q3DScene* scene READ scene)
- Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
- Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
- Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
- Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
public:
explicit Q3DScatter();
@@ -63,8 +59,8 @@ public:
void setMeshFileName(const QString &objFileName);
QString meshFileName() const;
- void setSelectionMode(QDataVis::SelectionMode mode);
- QDataVis::SelectionMode selectionMode() const;
+ void setSelectionMode(QDataVis::SelectionFlags mode);
+ QDataVis::SelectionFlags selectionMode() const;
void setFont(const QFont &font);
QFont font() const;
diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp
index 42260e8b..7b9e32bb 100644
--- a/src/datavisualization/engine/q3dsurface.cpp
+++ b/src/datavisualization/engine/q3dsurface.cpp
@@ -101,6 +101,8 @@ Q3DSurface::Q3DSurface()
{
setVisualController(d_ptr->m_shared);
d_ptr->m_shared->initializeOpenGL();
+ QObject::connect(d_ptr->m_shared, &Surface3DController::selectedPointChanged, this,
+ &Q3DSurface::selectedPointChanged);
QObject::connect(d_ptr->m_shared, &Abstract3DController::needRender, this,
&Q3DWindow::renderLater);
}
@@ -260,15 +262,16 @@ bool Q3DSurface::isSmoothSurfaceEnabled() const
/*!
* \property Q3DSurface::selectionMode
*
- * Sets point selection \a mode to one of \c QDataVis::SelectionMode. Surface supports SelectionModeItem,
- * SelectionModeSliceRow and SelectionModeSliceColumn. It is preset to \c QDataVis::SelectionModeItem by default.
+ * Sets point selection \a mode to one of \c QDataVis::SelectionMode. Surface supports
+ * \c SelectionItem and \c SelectionSlice with either \c SelectionRow or \c SelectionColumn.
+ * It is preset to \c SelectionItem by default.
*/
-void Q3DSurface::setSelectionMode(QDataVis::SelectionMode mode)
+void Q3DSurface::setSelectionMode(QDataVis::SelectionFlags mode)
{
d_ptr->m_shared->setSelectionMode(mode);
}
-QDataVis::SelectionMode Q3DSurface::selectionMode() const
+QDataVis::SelectionFlags Q3DSurface::selectionMode() const
{
return d_ptr->m_shared->selectionMode();
}
@@ -331,6 +334,24 @@ Q3DScene *Q3DSurface::scene() const
}
/*!
+ * \property Q3DSurface::selectedPoint
+ *
+ * Selects a surface grid point in a \a position. The position is the (row, column) position in
+ * the data array of the active data proxy.
+ * Only one point can be selected at a time.
+ * To clear selection, specify an illegal \a position, e.g. (-1, -1).
+ */
+void Q3DSurface::setSelectedPoint(const QPoint &position)
+{
+ d_ptr->m_shared->setSelectedPoint(position);
+}
+
+QPoint Q3DSurface::selectedPoint() const
+{
+ return d_ptr->m_shared->selectedPoint();
+}
+
+/*!
* \property Q3DSurface::labelStyle
*
* Sets label \a style to one of \c QDataVis::LabelStyle. It is preset to
diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h
index 1b572a36..c131f245 100644
--- a/src/datavisualization/engine/q3dsurface.h
+++ b/src/datavisualization/engine/q3dsurface.h
@@ -34,7 +34,7 @@ class QSurfaceDataProxy;
class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow
{
Q_OBJECT
- Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode)
Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle)
Q_PROPERTY(QtDataVisualization::QDataVis::Theme theme READ theme WRITE setTheme)
Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
@@ -45,10 +45,8 @@ class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow
Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient)
Q_PROPERTY(QFont font READ font WRITE setFont)
Q_PROPERTY(Q3DScene* scene READ scene)
- Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
- Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
- Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
- Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
+ Q_PROPERTY(QPoint selectedPoint READ selectedPoint WRITE setSelectedPoint NOTIFY selectedPointChanged)
+
public:
explicit Q3DSurface();
@@ -69,8 +67,8 @@ public:
void setSmoothSurfaceEnabled(bool enabled);
bool isSmoothSurfaceEnabled() const;
- void setSelectionMode(QDataVis::SelectionMode mode);
- QDataVis::SelectionMode selectionMode() const;
+ void setSelectionMode(QDataVis::SelectionFlags mode);
+ QDataVis::SelectionFlags selectionMode() const;
void setSurfaceGridEnabled(bool enabled);
bool isSurfaceGridEnabled() const;
@@ -101,9 +99,15 @@ public:
Q3DScene *scene() const;
+ void setSelectedPoint(const QPoint &position);
+ QPoint selectedPoint() const;
+
void setLabelStyle(QDataVis::LabelStyle style);
QDataVis::LabelStyle labelStyle() const;
+signals:
+ void selectedPointChanged(QPoint position);
+
protected:
void mouseDoubleClickEvent(QMouseEvent *event);
void touchEvent(QTouchEvent *event);
diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp
index 9f43d94e..ca16a34b 100644
--- a/src/datavisualization/engine/scatter3dcontroller.cpp
+++ b/src/datavisualization/engine/scatter3dcontroller.cpp
@@ -60,8 +60,8 @@ void Scatter3DController::initializeOpenGL()
setRenderer(m_renderer);
synchDataToRenderer();
- QObject::connect(m_renderer, &Scatter3DRenderer::selectedItemIndexChanged, this,
- &Scatter3DController::handleSelectedItemIndexChanged, Qt::QueuedConnection);
+ QObject::connect(m_renderer, &Scatter3DRenderer::itemClicked, this,
+ &Scatter3DController::handleItemClicked, Qt::QueuedConnection);
emitNeedRender();
}
@@ -117,17 +117,15 @@ void Scatter3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
adjustValueAxisRange();
setSelectedItemIndex(noSelectionIndex());
- setSlicingActive(false);
m_isDataDirty = true;
emitNeedRender();
}
void Scatter3DController::handleArrayReset()
{
- setSlicingActive(false);
adjustValueAxisRange();
m_isDataDirty = true;
- setSelectedItemIndex(noSelectionIndex());
+ setSelectedItemIndex(m_selectedItemIndex);
emitNeedRender();
}
@@ -173,13 +171,11 @@ void Scatter3DController::handleItemsInserted(int startIndex, int count)
emitNeedRender();
}
-void Scatter3DController::handleSelectedItemIndexChanged(int index)
+void Scatter3DController::handleItemClicked(int index)
{
- if (index != m_selectedItemIndex) {
- m_selectedItemIndex = index;
- emit selectedItemIndexChanged(index);
- emitNeedRender();
- }
+ setSelectedItemIndex(index);
+ // TODO: pass clicked to parent. (QTRD-2517)
+ // TODO: Also hover needed? (QTRD-2131)
}
void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation(
@@ -190,6 +186,14 @@ void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation(
adjustValueAxisRange();
}
+void Scatter3DController::handleAxisRangeChangedBySender(QObject *sender)
+{
+ Abstract3DController::handleAxisRangeChangedBySender(sender);
+
+ // Update selected index - may be moved offscreen
+ setSelectedItemIndex(m_selectedItemIndex);
+}
+
void Scatter3DController::setObjectType(QDataVis::MeshStyle style, bool smooth)
{
QString objFile;
@@ -207,21 +211,18 @@ void Scatter3DController::setObjectType(QDataVis::MeshStyle style, bool smooth)
Abstract3DController::setMeshFileName(objFile);
}
-void Scatter3DController::setSelectionMode(QDataVis::SelectionMode mode)
+void Scatter3DController::setSelectionMode(QDataVis::SelectionFlags mode)
{
- if (mode > QDataVis::SelectionModeItem) {
- qWarning("Unsupported selection mode.");
+ // We only support single item selection mode
+ if (int(mode ^ QDataVis::SelectionItem) != 0) {
+ qWarning("Unsupported selection mode - only item selection mode is supported.");
return;
}
- // Disable zoom if selection mode changes
- setSlicingActive(false);
Abstract3DController::setSelectionMode(mode);
}
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 >= static_cast<QScatterDataProxy *>(m_data)->itemCount())
index = noSelectionIndex();
diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h
index 63735aca..a1eae9f3 100644
--- a/src/datavisualization/engine/scatter3dcontroller_p.h
+++ b/src/datavisualization/engine/scatter3dcontroller_p.h
@@ -71,7 +71,7 @@ public:
void setObjectType(QDataVis::MeshStyle style, bool smooth = false);
// Change selection mode
- void setSelectionMode(QDataVis::SelectionMode mode);
+ void setSelectionMode(QDataVis::SelectionFlags mode);
void setSelectedItemIndex(int index);
int selectedItemIndex() const;
@@ -82,6 +82,7 @@ public:
void synchDataToRenderer();
virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust);
+ virtual void handleAxisRangeChangedBySender(QObject *sender);
public slots:
void handleArrayReset();
@@ -89,7 +90,7 @@ public slots:
void handleItemsChanged(int startIndex, int count);
void handleItemsRemoved(int startIndex, int count);
void handleItemsInserted(int startIndex, int count);
- void handleSelectedItemIndexChanged(int index);
+ void handleItemClicked(int index);
signals:
void selectedItemIndexChanged(int index);
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index 62163d6c..283020d0 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -49,7 +49,6 @@ const GLfloat labelMargin = 0.05f;
// TODO: Make margin modifiable?
const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background)
const GLfloat gridLineWidth = 0.005f;
-static QVector3D selectionSkipColor = QVector3D(255, 255, 255); // Selection texture's background color
Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
: Abstract3DRenderer(controller),
@@ -78,11 +77,11 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_shadowQualityMultiplier(3),
m_heightNormalizer(1.0f),
m_scaleFactor(0),
- m_selection(selectionSkipColor),
- m_previousSelection(selectionSkipColor),
+ m_clickedColor(invalidColorVector),
m_areaSize(QSizeF(0.0, 0.0)),
m_dotSizeScale(1.0f),
- m_hasHeightAdjustmentChanged(true)
+ m_hasHeightAdjustmentChanged(true),
+ m_cachedInputState(QDataVis::InputStateNone)
{
initializeOpenGLFunctions();
initializeOpenGL();
@@ -195,6 +194,15 @@ void Scatter3DRenderer::updateScene(Q3DScene *scene)
void Scatter3DRenderer::render(GLuint defaultFboHandle)
{
+ // TODO: Can't call back to controller here! (QTRD-2216)
+ // TODO: Needs to be added to synchronization
+ QDataVis::InputState currentInputState = m_controller->inputState();
+ if (currentInputState != m_cachedInputState) {
+ if (currentInputState == QDataVis::InputStateOnScene)
+ m_clickedColor = invalidColorVector;
+ m_cachedInputState = currentInputState;
+ }
+
// Handle GL state setup for FBO buffers and clearing of the render surface
Abstract3DRenderer::render(defaultFboHandle);
@@ -376,7 +384,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
#endif
// Skip selection mode drawing if we have no selection mode
- if (m_cachedSelectionMode > QDataVis::SelectionModeNone) {
+ // TODO: Can't call back to controller here! (QTRD-2216)
+ if (m_cachedSelectionMode > QDataVis::SelectionNone
+ && QDataVis::InputStateOnScene == m_controller->inputState()) {
// Bind selection shader
m_selectionShader->bind();
@@ -433,9 +443,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
glEnable(GL_DITHER);
// Read color under cursor
- if (QDataVis::InputStateOnScene == m_controller->inputState()) {
- m_selection = Utils::getSelection(m_controller->inputPosition(),
- m_cachedBoundingRect.height());
+ // TODO: Can't call back to controller here! (QTRD-2216)
+ QVector3D clickedColor = Utils::getSelection(m_controller->inputPosition(),
+ m_cachedBoundingRect.height());
+ if (m_clickedColor == invalidColorVector) {
+ m_clickedColor = clickedColor;
+ emit itemClicked(selectionColorToIndex(m_clickedColor));
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -471,20 +484,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Draw dots
bool dotSelectionFound = false;
- int selectedIndex;
- if (m_selection == selectionSkipColor) {
- selectedIndex = Scatter3DController::noSelectionIndex();
- } else {
- selectedIndex = int(m_selection.x())
- + (int(m_selection.y()) << 8)
- + (int(m_selection.z()) << 16);
- }
-
- if (m_selection != m_previousSelection) {
- emit selectedItemIndexChanged(selectedIndex);
- m_previousSelection = m_selection;
- }
-
ScatterRenderItem *selectedItem(0);
QVector3D baseColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
@@ -524,7 +523,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
#endif
GLfloat lightStrength = m_cachedTheme.m_lightStrength;
- if (m_cachedSelectionMode > QDataVis::SelectionModeNone && (selectedIndex == dot)) {
+ if (m_cachedSelectionMode > QDataVis::SelectionNone && (m_selectedItemIndex == dot)) {
dotColor = Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor);
lightStrength = m_cachedTheme.m_highlightLightStrength;
// Insert data to ScatterRenderItem. We have no ownership, don't delete the previous one
@@ -1312,10 +1311,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
void Scatter3DRenderer::updateSelectedItemIndex(int index)
{
- if (index == Scatter3DController::noSelectionIndex())
- m_selection = selectionSkipColor;
- else
- m_selection = indexToSelectionColor(index);
+ m_selectionDirty = true;
+ m_selectedItemIndex = index;
}
void Scatter3DRenderer::handleResize()
@@ -1574,4 +1571,17 @@ QVector3D Scatter3DRenderer::indexToSelectionColor(GLint index)
return QVector3D(dotIdxRed, dotIdxGreen, dotIdxBlue);
}
+int Scatter3DRenderer::selectionColorToIndex(const QVector3D &color)
+{
+ int selectedIndex;
+ if (color == selectionSkipColor) {
+ selectedIndex = Scatter3DController::noSelectionIndex();
+ } else {
+ selectedIndex = int(color.x())
+ + (int(color.y()) << 8)
+ + (int(color.z()) << 16);
+ }
+ return selectedIndex;
+}
+
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index f444f891..4a1f0b30 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -84,8 +84,8 @@ private:
GLint m_shadowQualityMultiplier;
GLfloat m_heightNormalizer;
GLfloat m_scaleFactor;
- QVector3D m_selection;
- QVector3D m_previousSelection;
+ QVector3D m_clickedColor;
+ int m_selectedItemIndex;
QSizeF m_areaSize;
GLfloat m_dotSizeScale;
@@ -94,6 +94,8 @@ private:
ScatterRenderItemArray m_renderItemArray;
+ QDataVis::InputState m_cachedInputState;
+
public:
explicit Scatter3DRenderer(Scatter3DController *controller);
~Scatter3DRenderer();
@@ -143,11 +145,11 @@ public slots:
void updateSelectedItemIndex(int index);
signals:
- void selectionUpdated(QVector3D selection);
- void selectedItemIndexChanged(int index);
+ void itemClicked(int index);
private:
QVector3D indexToSelectionColor(GLint index);
+ int selectionColorToIndex(const QVector3D &color);
};
QT_DATAVISUALIZATION_END_NAMESPACE
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) {
diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h
index 0698c291..07d15f29 100644
--- a/src/datavisualization/engine/surface3dcontroller_p.h
+++ b/src/datavisualization/engine/surface3dcontroller_p.h
@@ -42,11 +42,13 @@ struct Surface3DChangeBitField {
bool gradientColorChanged : 1;
bool smoothStatusChanged : 1;
bool surfaceGridChanged : 1;
+ bool selectedPointChanged : 1;
Surface3DChangeBitField() :
gradientColorChanged(true),
smoothStatusChanged(true),
- surfaceGridChanged(true)
+ surfaceGridChanged(true),
+ selectedPointChanged(true)
{
}
};
@@ -57,12 +59,11 @@ class QT_DATAVISUALIZATION_EXPORT Surface3DController : public Abstract3DControl
private:
Surface3DChangeBitField m_changeTracker;
-
- // Rendering
Surface3DRenderer *m_renderer;
bool m_isSmoothSurfaceEnabled;
bool m_isSurfaceGridEnabled;
QLinearGradient m_userDefinedGradient;
+ QPoint m_selectedPoint;
public:
explicit Surface3DController(QRect rect);
@@ -82,18 +83,25 @@ public:
void setGradientColorAt(qreal pos, const QColor &color);
- void setSelectionMode(QDataVis::SelectionMode mode);
+ void setSelectionMode(QDataVis::SelectionFlags mode);
+
+ void setSelectedPoint(const QPoint &position);
+ QPoint selectedPoint() const;
virtual void setActiveDataProxy(QAbstractDataProxy *proxy);
virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust);
virtual void handleAxisRangeChangedBySender(QObject *sender);
+ static QPoint noSelectionPoint();
+
public slots:
void handleArrayReset();
+ void handlePointClicked(const QPoint &position);
signals:
void smoothSurfaceEnabledChanged(bool enable);
+ void selectedPointChanged(QPoint position);
private:
void adjustValueAxisRange();
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 68b88bec..3bbade38 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -56,6 +56,7 @@ const GLfloat gridLineWidth = 0.005f;
const GLfloat sliceZScale = 0.1f;
const GLfloat sliceUnits = 2.5f;
const int subViewDivider = 5;
+const uint invalidSelectionId = uint(-1);
Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
: Abstract3DRenderer(controller),
@@ -63,6 +64,8 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_labelStyle(QDataVis::LabelStyleFromTheme),
m_font(QFont(QStringLiteral("Arial"))),
m_isGridEnabled(true),
+ m_cachedIsSlicingActivated(false),
+ m_cachedInputState(QDataVis::InputStateNone),
m_shader(0),
m_depthShader(0),
m_backgroundShader(0),
@@ -107,9 +110,9 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_yFlipped(false),
m_sampleSpace(QRect(0, 0, 0, 0)),
m_shadowQualityMultiplier(3),
- m_cachedSelectionId(0),
- m_selectionModeChanged(false),
- m_hasHeightAdjustmentChanged(true)
+ m_clickedPointId(invalidSelectionId),
+ m_hasHeightAdjustmentChanged(true),
+ m_selectedPoint(Surface3DController::noSelectionPoint())
{
// Check if flat feature is supported
ShaderHelper tester(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
@@ -252,19 +255,19 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
}
}
- m_selectionActive = false;
- m_cachedSelectionId = 0;
for (int i = 0; i < m_sliceDataArray.size(); i++)
delete m_sliceDataArray.at(i);
m_sliceDataArray.clear();
+ m_selectionDirty = true;
+
Abstract3DRenderer::updateDataModel(dataProxy);
}
-void Surface3DRenderer::updateSliceDataModel(int selectionId)
+void Surface3DRenderer::updateSliceDataModel(const QPoint &point)
{
- int column = (selectionId - 1) % m_sampleSpace.width();
- int row = (selectionId - 1) / m_sampleSpace.width();
+ int column = point.y();
+ int row = point.x();
for (int i = 0; i < m_sliceDataArray.size(); i++)
delete m_sliceDataArray.at(i);
@@ -275,7 +278,7 @@ void Surface3DRenderer::updateSliceDataModel(int selectionId)
qreal adjust = (0.025 * m_heightNormalizer) / 2.0;
qreal stepDown = 2.0 * adjust;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ if (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow)) {
QSurfaceDataRow *src = m_dataArray.at(row);
sliceRow = new QSurfaceDataRow(src->size());
for (int i = 0; i < sliceRow->size(); i++)
@@ -433,14 +436,22 @@ void Surface3DRenderer::updateScene(Q3DScene *scene)
if (m_selectionPointer)
m_selectionPointer->updateScene(m_cachedScene);
+
+ updateSlicingActive(scene->isSlicingActive());
}
void Surface3DRenderer::render(GLuint defaultFboHandle)
{
- bool slicingActivated = m_cachedScene->isSlicingActive();
- bool slicingChanged = m_cachedIsSlicingActivated != slicingActivated;
-
- updateSlicingActive(slicingActivated);
+ bool slicingChanged = m_cachedIsSlicingActivated != m_cachedScene->isSlicingActive();
+
+ // TODO: Can't call back to controller here! (QTRD-2216)
+ // TODO: Needs to be added to synchronization
+ QDataVis::InputState currentInputState = m_controller->inputState();
+ if (currentInputState != m_cachedInputState) {
+ if (currentInputState == QDataVis::InputStateOnScene)
+ m_clickedPointId = invalidSelectionId;
+ m_cachedInputState = currentInputState;
+ }
// Handle GL state setup for FBO buffers and clearing of the render surface
Abstract3DRenderer::render(defaultFboHandle);
@@ -448,18 +459,19 @@ void Surface3DRenderer::render(GLuint defaultFboHandle)
// Draw the surface scene
drawScene(defaultFboHandle);
- // In slice mode; draw slice and render selection ball
- if (m_cachedIsSlicingActivated)
+ // In slice mode; draw slice
+ if (m_cachedIsSlicingActivated && m_selectionActive)
drawSlicedScene();
- // Render selection ball if not in slice mode
- if (m_selectionPointer && m_selectionActive)
+ // Render selection ball
+ if (m_selectionPointer && m_selectionActive
+ && m_cachedSelectionMode.testFlag(QDataVis::SelectionItem)) {
m_selectionPointer->render(defaultFboHandle);
+ }
- // If slicing has been activated by this render pass, we need another render
- // Also trigger another render always when slicing changes in general to ensure
+ // Trigger another render always when slicing changes in general to ensure
// final draw is correct.
- if (slicingActivated != m_cachedScene->isSlicingActive() || slicingChanged)
+ if (slicingChanged)
emit needRender();
}
@@ -487,14 +499,16 @@ void Surface3DRenderer::drawSlicedScene()
QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
+ bool rowMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionRow);
+
GLfloat scaleX = 0.0f;
GLfloat scaleXBackground = 0.0f;
GLfloat offset = 0.0f;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ if (rowMode) {
scaleX = m_surfaceScaleX;
scaleXBackground = m_scaleXWithBackground;
offset = m_surfaceOffsetX;
- } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
+ } else {
scaleX = m_surfaceScaleZ;
scaleXBackground = m_scaleZWithBackground;
offset = -m_surfaceOffsetZ;
@@ -521,7 +535,7 @@ void Surface3DRenderer::drawSlicedScene()
MVPMatrix = projectionViewMatrix * modelMatrix;
QVector3D color;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow)
+ if (rowMode)
color = Utils::vectorFromColor(m_cachedTheme.m_highlightRowColor);
else
color = Utils::vectorFromColor(m_cachedTheme.m_highlightColumnColor);
@@ -611,7 +625,7 @@ void Surface3DRenderer::drawSlicedScene()
int lastSegment;
GLfloat lineStep;
GLfloat linePos;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ if (rowMode) {
lineStep = -2.0f * aspectRatio * m_axisCacheX.subSegmentStep() / m_scaleFactor;
lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount();
linePos = m_scaleX;
@@ -676,7 +690,7 @@ void Surface3DRenderer::drawSlicedScene()
m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
positionComp, rotation, 0, m_cachedSelectionMode, m_labelShader,
m_labelObj, m_cachedScene->activeCamera(),
- true, true, Drawer::LabelMid, Qt::AlignRight);
+ true, true, Drawer::LabelMid, Qt::AlignRight, true);
}
labelNbr++;
labelPos += posStep;
@@ -685,7 +699,7 @@ void Surface3DRenderer::drawSlicedScene()
// X Labels to ground
int countLabelItems;
int lastSegment;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ if (rowMode) {
posStep = 2.0f * aspectRatio * m_axisCacheX.segmentStep() / m_scaleFactor;
labelPos = -m_scaleX;
lastSegment = m_axisCacheX.segmentCount();
@@ -709,15 +723,15 @@ void Surface3DRenderer::drawSlicedScene()
m_dummyRenderItem.setTranslation(labelTrans);
LabelItem *axisLabelItem;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow)
+ if (rowMode)
axisLabelItem = m_axisCacheX.labelItems().at(labelNbr);
else
axisLabelItem = m_axisCacheZ.labelItems().at(labelNbr);
m_drawer->drawLabel(m_dummyRenderItem, *axisLabelItem, viewMatrix, projectionMatrix,
- positionComp, rotation, 0, QDataVis::SelectionModeSliceRow,
+ positionComp, rotation, 0, QDataVis::SelectionRow,
m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
- false, false, Drawer::LabelBelow, Qt::AlignTop);
+ false, false, Drawer::LabelBelow, Qt::AlignTop, true);
}
labelNbr++;
labelPos += posStep;
@@ -735,7 +749,6 @@ void Surface3DRenderer::drawSlicedScene()
void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
{
GLfloat backgroundRotation = 0;
- uint selectionId = 0;
// Specify viewport
glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
@@ -880,15 +893,12 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
#endif
}
#endif
-
- bool selectionDirty = false;
-
// Enable texturing
glEnable(GL_TEXTURE_2D);
// Draw selection buffer
- if (!m_cachedIsSlicingActivated && m_controller->inputState() == QDataVis::InputStateOnScene
- && m_surfaceObj && m_cachedSelectionMode > QDataVis::SelectionModeNone) {
+ if (!m_cachedIsSlicingActivated && m_surfaceObj && m_cachedInputState == QDataVis::InputStateOnScene
+ && m_cachedSelectionMode > QDataVis::SelectionNone) {
m_selectionShader->bind();
glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
@@ -924,12 +934,16 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// Put the RGBA value back to uint
#if !defined(QT_OPENGL_ES_2)
- selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536 + pixel[3] * 16777216;
+ uint selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536 + pixel[3] * 16777216;
#else
- selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536;
+ uint selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536;
#endif
- selectionDirty = true;
+ if (m_clickedPointId == invalidSelectionId) {
+ m_clickedPointId = selectionId;
+ QPoint newPoint = selectionIdToSurfacePoint(m_clickedPointId);
+ emit pointClicked(newPoint);
+ }
}
// Draw the surface
@@ -1578,39 +1592,30 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_labelShader->release();
// Selection handling
- if (m_selectionModeChanged || selectionDirty) {
- if (selectionDirty)
- m_cachedSelectionId = selectionId;
- if (m_cachedSelectionMode == QDataVis::SelectionModeNone) {
- m_cachedSelectionId = 0;
- m_selectionActive = false;
- }
- if (m_cachedSelectionMode == QDataVis::SelectionModeItem) {
- if (m_cachedSelectionId)
- surfacePointSelected(m_cachedSelectionId);
- else
- m_selectionActive = false;
- }
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow
- || m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
- if (m_cachedSelectionId) {
- updateSliceDataModel(m_cachedSelectionId);
- m_cachedScene->setSlicingActive(true);
-
- surfacePointSelected(m_cachedSelectionId);
-
- emit needRender();
+ if (m_selectionDirty) {
+ QPoint visiblePoint = Surface3DController::noSelectionPoint();
+ if (m_selectedPoint != Surface3DController::noSelectionPoint()) {
+ int x = m_selectedPoint.x() - m_sampleSpace.y();
+ int y = m_selectedPoint.y() - m_sampleSpace.x();
+ if (x >= 0 && y >= 0 && x < m_sampleSpace.height() && y < m_sampleSpace.width()
+ && m_dataArray.size()) {
+ visiblePoint = QPoint(x, y);
}
}
- m_selectionModeChanged = false;
- }
- if (m_controller->inputState() == QDataVis::InputStateOnOverview) {
- if (m_cachedIsSlicingActivated) {
- m_cachedScene->setSlicingActive(false);
+ if (m_cachedSelectionMode == QDataVis::SelectionNone
+ || visiblePoint == Surface3DController::noSelectionPoint()) {
m_selectionActive = false;
- m_cachedSelectionId = 0;
+ } else {
+ // TODO: Need separate selection ball for slice and main surface view QTRD-2515
+ if (m_cachedIsSlicingActivated)
+ updateSliceDataModel(visiblePoint);
+ if (m_cachedSelectionMode.testFlag(QDataVis::SelectionItem))
+ surfacePointSelected(visiblePoint);
+ m_selectionActive = true;
}
+
+ m_selectionDirty = false;
}
}
@@ -1771,12 +1776,10 @@ bool Surface3DRenderer::updateSmoothStatus(bool enable)
return m_cachedSmoothSurface;
}
-void Surface3DRenderer::updateSelectionMode(QDataVis::SelectionMode mode)
+void Surface3DRenderer::updateSelectedPoint(const QPoint &position)
{
- if (mode != m_cachedSelectionMode)
- m_selectionModeChanged = true;
-
- Abstract3DRenderer::updateSelectionMode(mode);
+ m_selectedPoint = position;
+ m_selectionDirty = true;
}
void Surface3DRenderer::updateSurfaceGridStatus(bool enable)
@@ -1824,13 +1827,10 @@ void Surface3DRenderer::handleResize()
Abstract3DRenderer::handleResize();
}
-void Surface3DRenderer::surfacePointSelected(int id)
+void Surface3DRenderer::surfacePointSelected(const QPoint &point)
{
- int column = (id - 1) % m_sampleSpace.width();
- int row = (id - 1) / m_sampleSpace.width();
-
- if (row < 0 || column < 0 || m_dataArray.size() < row || m_dataArray.at(row)->size() < column)
- return;
+ int row = point.x();
+ int column = point.y();
qreal value = qreal(m_dataArray.at(row)->at(column).y());
@@ -1838,18 +1838,20 @@ void Surface3DRenderer::surfacePointSelected(int id)
m_selectionPointer = new SelectionPointer(m_drawer);
QVector3D pos;
- if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
- pos = m_sliceSurfaceObj->vertexAt(column, 0);
- pos *= QVector3D(m_surfaceScaleX, 1.0f, 0.0f);
- pos += QVector3D(m_surfaceOffsetX, 0.0f, 0.0f);
- m_selectionPointer->updateBoundingRect(m_sliceViewPort);
- m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
- } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
- pos = m_sliceSurfaceObj->vertexAt(row, 0);
- pos *= QVector3D(m_surfaceScaleZ, 1.0f, 0.0f);
- pos += QVector3D(-m_surfaceOffsetZ, 0.0f, 0.0f);
- m_selectionPointer->updateBoundingRect(m_sliceViewPort);
- m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
+ if (m_cachedIsSlicingActivated) {
+ if (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow)) {
+ pos = m_sliceSurfaceObj->vertexAt(column, 0);
+ pos *= QVector3D(m_surfaceScaleX, 1.0f, 0.0f);
+ pos += QVector3D(m_surfaceOffsetX, 0.0f, 0.0f);
+ m_selectionPointer->updateBoundingRect(m_sliceViewPort);
+ m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
+ } else if (m_cachedSelectionMode.testFlag(QDataVis::SelectionColumn)) {
+ pos = m_sliceSurfaceObj->vertexAt(row, 0);
+ pos *= QVector3D(m_surfaceScaleZ, 1.0f, 0.0f);
+ pos += QVector3D(-m_surfaceOffsetZ, 0.0f, 0.0f);
+ m_selectionPointer->updateBoundingRect(m_sliceViewPort);
+ m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
+ }
} else {
pos = m_surfaceObj->vertexAt(column, row);
pos *= QVector3D(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);;
@@ -1861,9 +1863,14 @@ void Surface3DRenderer::surfacePointSelected(int id)
m_selectionPointer->setPosition(pos);
m_selectionPointer->setLabel(createSelectionLabel(value, column, row));
m_selectionPointer->updateScene(m_cachedScene);
+}
- //Put the selection pointer flag active
- m_selectionActive = true;
+// Maps selection Id to surface point in data array
+QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id)
+{
+ int column = ((id - 1) % m_sampleSpace.width()) + m_sampleSpace.x();
+ int row = ((id - 1) / m_sampleSpace.width()) + m_sampleSpace.y();
+ return QPoint(row, column);
}
QString Surface3DRenderer::createSelectionLabel(qreal value, int column, int row)
@@ -1968,6 +1975,8 @@ void Surface3DRenderer::updateSlicingActive(bool isSlicing)
#if !defined(QT_OPENGL_ES_2)
updateDepthBuffer(); // Re-init depth buffer as well
#endif
+
+ m_selectionDirty = true;
}
void Surface3DRenderer::setViewPorts()
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index c805e508..72a83692 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -70,6 +70,7 @@ public:
private:
bool m_cachedIsSlicingActivated;
+ QDataVis::InputState m_cachedInputState;
// Internal attributes purely related to how the scene is drawn with GL.
QRect m_mainViewPort;
@@ -124,9 +125,9 @@ private:
QRect m_sampleSpace;
GLint m_shadowQualityMultiplier;
QSizeF m_areaSize;
- uint m_cachedSelectionId;
- bool m_selectionModeChanged;
+ uint m_clickedPointId;
bool m_hasHeightAdjustmentChanged;
+ QPoint m_selectedPoint;
public:
explicit Surface3DRenderer(Surface3DController *controller);
@@ -146,11 +147,14 @@ public slots:
void updateSurfaceGridStatus(bool enable);
void updateSurfaceGradient(const QLinearGradient &gradient);
void updateSlicingActive(bool isSlicing);
- void updateSelectionMode(QDataVis::SelectionMode mode);
+ void updateSelectedPoint(const QPoint &position);
+
+signals:
+ void pointClicked(QPoint position);
private:
void setViewPorts();
- void updateSliceDataModel(int selectionId);
+ void updateSliceDataModel(const QPoint &point);
virtual void updateShadowQuality(QDataVis::ShadowQuality quality);
virtual void updateTextures();
virtual void initShaders(const QString &vertexShader, const QString &fragmentShader);
@@ -172,11 +176,13 @@ private:
void updateSelectionTexture();
void idToRGBA(uint id, uchar *r, uchar *g, uchar *b, uchar *a);
void fillIdCorner(uchar *p, uchar r, uchar g, uchar b, uchar a, int stride);
- void surfacePointSelected(int id);
+ void surfacePointSelected(const QPoint &point);
+ QPoint selectionIdToSurfacePoint(uint id);
QString createSelectionLabel(qreal value, int column, int row);
#if !defined(QT_OPENGL_ES_2)
void updateDepthBuffer();
#endif
+ void emitSelectedPointChanged(QPoint position);
Q_DISABLE_COPY(Surface3DRenderer)
};