summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--examples/audiolevels/audiolevels.cpp2
-rw-r--r--examples/bars/graphmodifier.cpp7
-rw-r--r--examples/bars/main.cpp31
-rw-r--r--examples/customproxy/rainfallgraph.cpp2
-rw-r--r--examples/itemmodel/doc/src/itemmodel.qdoc2
-rw-r--r--examples/itemmodel/main.cpp8
-rw-r--r--examples/qmlbars/qml/qmlbars/main.qml6
-rw-r--r--examples/qmlsurface/qml/qmlsurface/main.qml2
-rw-r--r--examples/surface/surfacegraph.h10
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc2
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization.qdoc2
-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
-rw-r--r--src/datavisualization/global/qdatavisualizationenums.h23
-rw-r--r--src/datavisualization/global/qtdatavisualizationenums.qdoc42
-rw-r--r--src/datavisualizationqml2/abstractdeclarative.cpp4
-rw-r--r--src/datavisualizationqml2/abstractdeclarative_p.h11
-rw-r--r--src/datavisualizationqml2/declarativebars.cpp12
-rw-r--r--src/datavisualizationqml2/declarativebars_p.h8
-rw-r--r--tests/barstest/chart.cpp36
-rw-r--r--tests/barstest/chart.h2
-rw-r--r--tests/barstest/main.cpp2
-rw-r--r--tests/kinectsurface/surfacedata.cpp4
-rw-r--r--tests/qmlcamera/qml/qmlcamera/main.qml4
-rw-r--r--tests/scattertest/scatterchart.cpp2
-rw-r--r--tests/spectrum/spectrumapp/main.cpp2
-rw-r--r--tests/surfacetest/graphmodifier.cpp49
-rw-r--r--tests/surfacetest/graphmodifier.h5
-rw-r--r--tests/surfacetest/main.cpp38
51 files changed, 800 insertions, 560 deletions
diff --git a/examples/audiolevels/audiolevels.cpp b/examples/audiolevels/audiolevels.cpp
index 0922e664..307240c5 100644
--- a/examples/audiolevels/audiolevels.cpp
+++ b/examples/audiolevels/audiolevels.cpp
@@ -44,7 +44,7 @@ AudioLevels::AudioLevels(Q3DBars *graph, QObject *parent)
m_graph->valueAxis()->setSegmentCount(20);
m_graph->valueAxis()->setLabelFormat(QStringLiteral("%d%%"));
m_graph->setShadowQuality(QDataVis::ShadowQualityNone);
- m_graph->setSelectionMode(QDataVis::SelectionModeNone);
+ m_graph->setSelectionMode(QDataVis::SelectionNone);
m_graph->scene()->activeCamera()->setCameraPosition(-25.0, 10.0, 190.0);
m_graph->setTheme(QDataVis::ThemeIsabelle);
m_graph->setBarType(QDataVis::MeshStyleBars);
diff --git a/examples/bars/graphmodifier.cpp b/examples/bars/graphmodifier.cpp
index e2ace423..89c651ff 100644
--- a/examples/bars/graphmodifier.cpp
+++ b/examples/bars/graphmodifier.cpp
@@ -23,6 +23,7 @@
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
#include <QTime>
+#include <QComboBox>
QT_DATAVISUALIZATION_USE_NAMESPACE
@@ -167,7 +168,11 @@ void GraphModifier::changeLabelStyle()
void GraphModifier::changeSelectionMode(int selectionMode)
{
- m_graph->setSelectionMode((QDataVis::SelectionMode)selectionMode);
+ QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
+ if (comboBox) {
+ int flags = comboBox->itemData(selectionMode).toInt();
+ m_graph->setSelectionMode(QDataVis::SelectionFlags(flags));
+ }
}
void GraphModifier::changeFont(const QFont &font)
diff --git a/examples/bars/main.cpp b/examples/bars/main.cpp
index 158244b4..fc3737f6 100644
--- a/examples/bars/main.cpp
+++ b/examples/bars/main.cpp
@@ -84,13 +84,30 @@ int main(int argc, char **argv)
cameraButton->setText(QStringLiteral("Change camera preset"));
QComboBox *selectionModeList = new QComboBox(widget);
- selectionModeList->addItem(QStringLiteral("None"));
- selectionModeList->addItem(QStringLiteral("Bar"));
- selectionModeList->addItem(QStringLiteral("Bar and Row"));
- selectionModeList->addItem(QStringLiteral("Bar and Column"));
- selectionModeList->addItem(QStringLiteral("Bar, Row and Column"));
- selectionModeList->addItem(QStringLiteral("Slice into Row"));
- selectionModeList->addItem(QStringLiteral("Slice into Column"));
+ selectionModeList->addItem(QStringLiteral("None"),
+ int(QDataVis::SelectionNone));
+ selectionModeList->addItem(QStringLiteral("Bar"),
+ int(QDataVis::SelectionItem));
+ selectionModeList->addItem(QStringLiteral("Row"),
+ int(QDataVis::SelectionRow));
+ selectionModeList->addItem(QStringLiteral("Bar and Row"),
+ int(QDataVis::SelectionItemAndRow));
+ selectionModeList->addItem(QStringLiteral("Column"),
+ int(QDataVis::SelectionColumn));
+ selectionModeList->addItem(QStringLiteral("Bar and Column"),
+ int(QDataVis::SelectionItemAndColumn));
+ selectionModeList->addItem(QStringLiteral("Row and Column"),
+ int(QDataVis::SelectionRowAndColumn));
+ selectionModeList->addItem(QStringLiteral("Bar, Row and Column"),
+ int(QDataVis::SelectionItemRowAndColumn));
+ selectionModeList->addItem(QStringLiteral("Slice into Row"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionRow));
+ selectionModeList->addItem(QStringLiteral("Slice into Row and Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndRow));
+ selectionModeList->addItem(QStringLiteral("Slice into Column"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionColumn));
+ selectionModeList->addItem(QStringLiteral("Slice into Column and Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndColumn));
selectionModeList->setCurrentIndex(1);
QCheckBox *backgroundCheckBox = new QCheckBox(widget);
diff --git a/examples/customproxy/rainfallgraph.cpp b/examples/customproxy/rainfallgraph.cpp
index 3a9f820a..0327ecb9 100644
--- a/examples/customproxy/rainfallgraph.cpp
+++ b/examples/customproxy/rainfallgraph.cpp
@@ -69,7 +69,7 @@ RainfallGraph::RainfallGraph(Q3DBars *rainfall)
m_graph->setFont(QFont("Century Gothic", 30));
// Set selection mode to bar and column
- m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn);
+ m_graph->setSelectionMode(QDataVis::SelectionItemAndColumn | QDataVis::SelectionSlice);
// Set theme
m_graph->setTheme(QDataVis::ThemeArmyBlue);
diff --git a/examples/itemmodel/doc/src/itemmodel.qdoc b/examples/itemmodel/doc/src/itemmodel.qdoc
index 682ebb1f..6c192f6f 100644
--- a/examples/itemmodel/doc/src/itemmodel.qdoc
+++ b/examples/itemmodel/doc/src/itemmodel.qdoc
@@ -164,7 +164,7 @@
Now we'll find out what these were for.
The first one connects a signal from Q3DBars to the GraphDataGenerator. Signal
- Q3DBars::selectedBarPosChanged() is emitted when a bar is selected from the graph. We connect
+ Q3DBars::selectedBarChanged() is emitted when a bar is selected from the graph. We connect
that to a method in the data generator that selects the same data item in the table widget:
\snippet ../examples/itemmodel/main.cpp 13
diff --git a/examples/itemmodel/main.cpp b/examples/itemmodel/main.cpp
index fac6b442..5964992d 100644
--- a/examples/itemmodel/main.cpp
+++ b/examples/itemmodel/main.cpp
@@ -90,7 +90,7 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid
m_tableWidget->setColumnCount(m_columnCount);
// Set selection mode to full
- m_graph->setSelectionMode(QDataVis::SelectionModeItemRowAndColumn);
+ m_graph->setSelectionMode(QDataVis::SelectionItemRowAndColumn);
// Hide axis labels by explicitly setting one empty string as label list
m_graph->rowAxis()->setCategoryLabels(QStringList(QString()));
@@ -101,7 +101,7 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid
//! [6]
// Set selection mode to slice row
- m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow);
+ m_graph->setSelectionMode(QDataVis::SelectionItemAndRow | QDataVis::SelectionSlice);
// Set font
m_graph->setFont(QFont("Impact", 20));
@@ -222,7 +222,7 @@ void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn,
{
Q_UNUSED(previousRow)
Q_UNUSED(previousColumn)
- m_graph->setSelectedBarPos(QPoint(currentRow, currentColumn));
+ m_graph->setSelectedBar(QPoint(currentRow, currentColumn));
}
//! [14]
@@ -273,7 +273,7 @@ int main(int argc, char **argv)
//! [3]
GraphDataGenerator generator(graph, tableWidget);
- QObject::connect(graph, &Q3DBars::selectedBarPosChanged, &generator,
+ QObject::connect(graph, &Q3DBars::selectedBarChanged, &generator,
&GraphDataGenerator::selectFromTable);
QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator,
&GraphDataGenerator::selectedFromTable);
diff --git a/examples/qmlbars/qml/qmlbars/main.qml b/examples/qmlbars/qml/qmlbars/main.qml
index 5b1cc006..3d8aa7e0 100644
--- a/examples/qmlbars/qml/qmlbars/main.qml
+++ b/examples/qmlbars/qml/qmlbars/main.qml
@@ -46,7 +46,7 @@ Item {
width: dataView.width
height: dataView.height
shadowQuality: AbstractGraph3D.ShadowQualityMedium
- selectionMode: AbstractGraph3D.SelectionModeItem
+ selectionMode: AbstractGraph3D.SelectionItem
font.pointSize: 35
theme: AbstractGraph3D.ThemeRetro
labelStyle: AbstractGraph3D.LabelStyleFromTheme
@@ -59,7 +59,7 @@ Item {
valueAxis: graphAxes.expenses
itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel"
- onSelectedBarPosChanged: {
+ onSelectedBarChanged: {
// Set tableView current row to selected bar
var rowRole = graphData.proxy.rowLabels[position.x];
var colRole = graphData.proxy.columnLabels[position.y];
@@ -161,7 +161,7 @@ Item {
onCurrentRowChanged: {
var rowIndex = graphData.proxy.activeMapping.rowCategoryIndex(graphData.model.get(currentRow).year)
var colIndex = graphData.proxy.activeMapping.columnCategoryIndex(graphData.model.get(currentRow).month)
- testGraph.selectedBarPos = Qt.point(rowIndex, colIndex)
+ testGraph.selectedBar = Qt.point(rowIndex, colIndex)
}
//! [2]
}
diff --git a/examples/qmlsurface/qml/qmlsurface/main.qml b/examples/qmlsurface/qml/qmlsurface/main.qml
index bc8d9499..b4ea17f6 100644
--- a/examples/qmlsurface/qml/qmlsurface/main.qml
+++ b/examples/qmlsurface/qml/qmlsurface/main.qml
@@ -51,7 +51,7 @@ Item {
height: surfaceView.height
theme: AbstractGraph3D.ThemeStoneMoss
shadowQuality: AbstractGraph3D.ShadowQualityMedium
- selectionMode: AbstractGraph3D.SelectionModeSliceRow
+ selectionMode: AbstractGraph3D.SelectionSlice | AbstractGraph3D.SelectionItemAndRow
smoothSurfaceEnabled: true
surfaceGridEnabled: false
font.family: "STCaiyun"
diff --git a/examples/surface/surfacegraph.h b/examples/surface/surfacegraph.h
index ac297bf6..ff0e5fc4 100644
--- a/examples/surface/surfacegraph.h
+++ b/examples/surface/surfacegraph.h
@@ -37,10 +37,12 @@ public:
void enableSqrtSinModel();
//! [0]
- void toggleModeNone() { m_graph->setSelectionMode(QDataVis::SelectionModeNone); }
- void toggleModeItem() { m_graph->setSelectionMode(QDataVis::SelectionModeItem); }
- void toggleModeSliceRow() { m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow); }
- void toggleModeSliceColumn() { m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn); }
+ void toggleModeNone() { m_graph->setSelectionMode(QDataVis::SelectionNone); }
+ void toggleModeItem() { m_graph->setSelectionMode(QDataVis::SelectionItem); }
+ void toggleModeSliceRow() { m_graph->setSelectionMode(QDataVis::SelectionItemAndRow
+ | QDataVis::SelectionSlice); }
+ void toggleModeSliceColumn() { m_graph->setSelectionMode(QDataVis::SelectionItemAndColumn
+ | QDataVis::SelectionSlice); }
//! [0]
void setBlackToYellowGradient();
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
index 5e6ef522..5d2178cf 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
@@ -130,7 +130,7 @@
*/
/*!
- * \qmlproperty point Bars3D::selectedBarPos
+ * \qmlproperty point Bars3D::selectedBar
* Position of the selected bar in data window. Only one bar can be selected at a time.
* To clear selection, specify an illegal position, e.g. Qt.point(-1.0, -1.0).
*/
diff --git a/src/datavisualization/doc/src/qtdatavisualization.qdoc b/src/datavisualization/doc/src/qtdatavisualization.qdoc
index 02c303d6..77596dfa 100644
--- a/src/datavisualization/doc/src/qtdatavisualization.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization.qdoc
@@ -261,7 +261,7 @@
All visualization types support selecting a single data item - a bar, a scatter item, or a surface
vertex - using mouse, touch, and programmatically via the graph APIs. The selected item is highlighted
in the rendered graph, and selecting causes emission of a graph specific signal for this purpose,
- for example, Q3DBars::selectedBarPosChanged(), which the application can handle.
+ for example, Q3DBars::selectedBarChanged(), which the application can handle.
\note The surface graph doesn't have a fully implemented selection API yet. It only supports
selection with mouse and touch in the technology preview version.
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)
};
diff --git a/src/datavisualization/global/qdatavisualizationenums.h b/src/datavisualization/global/qdatavisualizationenums.h
index 3d765ff2..22599fbb 100644
--- a/src/datavisualization/global/qdatavisualizationenums.h
+++ b/src/datavisualization/global/qdatavisualizationenums.h
@@ -31,9 +31,9 @@ class QT_DATAVISUALIZATION_EXPORT QDataVis : public QObject
Q_ENUMS(MeshStyle)
Q_ENUMS(CameraPreset)
Q_ENUMS(Theme)
- Q_ENUMS(SelectionMode)
Q_ENUMS(ShadowQuality)
Q_ENUMS(LabelStyle)
+ Q_FLAGS(SelectionFlag SelectionFlags)
public:
enum InputState {
@@ -95,15 +95,18 @@ public:
ThemeIsabelle
};
- enum SelectionMode {
- SelectionModeNone = 0,
- SelectionModeItem,
- SelectionModeItemAndRow,
- SelectionModeItemAndColumn,
- SelectionModeItemRowAndColumn,
- SelectionModeSliceRow,
- SelectionModeSliceColumn
+ enum SelectionFlag {
+ SelectionNone = 0,
+ SelectionItem = 1,
+ SelectionRow = 2,
+ SelectionItemAndRow = SelectionItem | SelectionRow,
+ SelectionColumn = 4,
+ SelectionItemAndColumn = SelectionItem | SelectionColumn,
+ SelectionRowAndColumn = SelectionRow | SelectionColumn,
+ SelectionItemRowAndColumn = SelectionItem | SelectionRow | SelectionColumn,
+ SelectionSlice = 8
};
+ Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)
enum ShadowQuality {
ShadowQualityNone = 0,
@@ -121,6 +124,8 @@ public:
LabelStyleTransparent
};
};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDataVis::SelectionFlags)
}
#endif
diff --git a/src/datavisualization/global/qtdatavisualizationenums.qdoc b/src/datavisualization/global/qtdatavisualizationenums.qdoc
index d448953d..c3569ee4 100644
--- a/src/datavisualization/global/qtdatavisualizationenums.qdoc
+++ b/src/datavisualization/global/qtdatavisualizationenums.qdoc
@@ -130,29 +130,31 @@
*/
/*!
- \enum QtDataVisualization::QDataVis::SelectionMode
+ \enum QtDataVisualization::QDataVis::SelectionFlag
- Item selection modes.
+ Item selection modes. Values of this enumeration can be combined with OR operator.
- \value SelectionModeNone
+ \value SelectionNone
Selection mode disabled.
- \value SelectionModeItem
- Selection selects a single item.
- \value SelectionModeItemAndRow
- Selection selects a single item and highlights the row it is on. In Q3DBars only.
- \value SelectionModeItemAndColumn
- Selection selects a single item and highlights the column it is on. In Q3DBars only.
- \value SelectionModeItemRowAndColumn
- Selection selects a single item and highlights the row and the column it is on. In
- Q3DBars only.
- \value SelectionModeSliceRow
- Selection selects a single item and displays the row it is on in a separate view. The
- original view is shrunk into upper left corner. Original view is restored by clicking
- on it. In Q3DBars only.
- \value SelectionModeSliceColumn
- Selection selects a single item and displays the column it is on in a separate view. The
- original view is shrunk into upper left corner. Original view is restored by clicking
- on it. In Q3DBars only.
+ \value SelectionItem
+ Selection highlights a single item.
+ \value SelectionRow
+ Selection highlights a single row.
+ \value SelectionItemAndRow
+ Combination flag for highlighting both item and row with different colors.
+ \value SelectionColumn
+ Selection highlights a single column.
+ \value SelectionItemAndColumn
+ Combination flag for highlighting both item and column with different colors.
+ \value SelectionRowAndColumn
+ Combination flag for highlighting both row and column.
+ \value SelectionItemRowAndColumn
+ Combination flag for highlighting item, row, and column.
+ \value SelectionSlice
+ Setting this mode flag indicates that the graph should take care of the slice view handling
+ automatically. If you wish to control the slice view yourself via Q3DScene, do not set this
+ flag. When setting this mode flag, either \c SelectionRow or \c SelectionColumn must also
+ be set, but not both. Slicing is supported by Q3DBars and Q3DSurface only.
*/
/*!
diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp
index e853ff9c..d4b5c7b7 100644
--- a/src/datavisualizationqml2/abstractdeclarative.cpp
+++ b/src/datavisualizationqml2/abstractdeclarative.cpp
@@ -47,12 +47,12 @@ QDataVis::Theme AbstractDeclarative::theme() const
return m_controller->theme().theme();
}
-void AbstractDeclarative::setSelectionMode(QDataVis::SelectionMode mode)
+void AbstractDeclarative::setSelectionMode(QDataVis::SelectionFlags mode)
{
m_controller->setSelectionMode(mode);
}
-QDataVis::SelectionMode AbstractDeclarative::selectionMode() const
+QDataVis::SelectionFlags AbstractDeclarative::selectionMode() const
{
return m_controller->selectionMode();
}
diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h
index 41d4a4da..842dbf4b 100644
--- a/src/datavisualizationqml2/abstractdeclarative_p.h
+++ b/src/datavisualizationqml2/abstractdeclarative_p.h
@@ -42,7 +42,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class AbstractDeclarative : public QQuickItem
{
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(Q3DScene* scene READ scene NOTIFY sceneChanged)
@@ -52,11 +52,6 @@ class AbstractDeclarative : public QQuickItem
Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat)
- Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
- Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
- Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
- Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
- Q_ENUMS(QtDataVisualization::QDataVis::Theme)
public:
explicit AbstractDeclarative(QQuickItem *parent = 0);
@@ -70,8 +65,8 @@ public:
virtual void setTheme(QDataVis::Theme theme);
virtual QDataVis::Theme theme() const;
- virtual void setSelectionMode(QDataVis::SelectionMode mode);
- virtual QDataVis::SelectionMode selectionMode() const;
+ virtual void setSelectionMode(QDataVis::SelectionFlags mode);
+ virtual QDataVis::SelectionFlags selectionMode() const;
virtual void setFont(const QFont &font);
virtual QFont font() const;
diff --git a/src/datavisualizationqml2/declarativebars.cpp b/src/datavisualizationqml2/declarativebars.cpp
index 9ed80106..52b19807 100644
--- a/src/datavisualizationqml2/declarativebars.cpp
+++ b/src/datavisualizationqml2/declarativebars.cpp
@@ -41,8 +41,8 @@ DeclarativeBars::DeclarativeBars(QQuickItem *parent)
// Create the shared component on the main GUI thread.
m_shared = new Bars3DController(boundingRect().toRect());
AbstractDeclarative::setSharedController(m_shared);
- QObject::connect(m_shared, &Bars3DController::selectedBarPosChanged, this,
- &DeclarativeBars::selectedBarPosChanged);
+ QObject::connect(m_shared, &Bars3DController::selectedBarChanged, this,
+ &DeclarativeBars::selectedBarChanged);
QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy;
m_shared->setActiveDataProxy(proxy);
@@ -201,14 +201,14 @@ QString DeclarativeBars::meshFileName() const
return m_shared->meshFileName();
}
-void DeclarativeBars::setSelectedBarPos(const QPointF &position)
+void DeclarativeBars::setSelectedBar(const QPointF &position)
{
- m_shared->setSelectedBarPos(position.toPoint());
+ m_shared->setSelectedBar(position.toPoint());
}
-QPointF DeclarativeBars::selectedBarPos() const
+QPointF DeclarativeBars::selectedBar() const
{
- return QPointF(m_shared->selectedBarPos());
+ return QPointF(m_shared->selectedBar());
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualizationqml2/declarativebars_p.h b/src/datavisualizationqml2/declarativebars_p.h
index dfbf9934..f71d9ad3 100644
--- a/src/datavisualizationqml2/declarativebars_p.h
+++ b/src/datavisualizationqml2/declarativebars_p.h
@@ -57,7 +57,7 @@ class DeclarativeBars : public AbstractDeclarative
Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative)
Q_PROPERTY(bool barSmoothingEnabled READ isBarSmoothingEnabled WRITE setBarSmoothingEnabled)
Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
- Q_PROPERTY(QPointF selectedBarPos READ selectedBarPos WRITE setSelectedBarPos NOTIFY selectedBarPosChanged)
+ Q_PROPERTY(QPointF selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged)
Q_ENUMS(QtDataVisualization::QDataVis::MeshStyle)
public:
@@ -94,11 +94,11 @@ public:
void setMeshFileName(const QString &objFileName);
QString meshFileName() const;
- void setSelectedBarPos(const QPointF &position);
- QPointF selectedBarPos() const;
+ void setSelectedBar(const QPointF &position);
+ QPointF selectedBar() const;
signals:
- void selectedBarPosChanged(const QPointF &position);
+ void selectedBarChanged(const QPointF &position);
protected:
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp
index ad27d83c..d71f60b4 100644
--- a/tests/barstest/chart.cpp
+++ b/tests/barstest/chart.cpp
@@ -42,7 +42,7 @@ GraphModifier::GraphModifier(Q3DBars *barchart)
m_subSegments(3),
m_minval(-20.0), // TODO Barchart Y-axis currently only properly supports zero-centered ranges
m_maxval(20.0),
- m_selectedBarPos(-1, -1),
+ m_selectedBar(-1, -1),
m_autoAdjustingAxis(new Q3DValueAxis),
m_fixedRangeAxis(new Q3DValueAxis),
m_temperatureAxis(new Q3DValueAxis),
@@ -142,7 +142,7 @@ void GraphModifier::restart(bool dynamicData)
m_chart->setRowAxis(m_yearAxis);
m_chart->setColumnAxis(m_monthAxis);
- m_chart->setSelectionMode(QDataVis::SelectionModeItem);
+ m_chart->setSelectionMode(QDataVis::SelectionItem);
} else {
m_chart->setActiveDataProxy(m_genericData);
@@ -152,7 +152,7 @@ void GraphModifier::restart(bool dynamicData)
m_chart->setRowAxis(m_genericRowAxis);
m_chart->setColumnAxis(m_genericColumnAxis);
- m_chart->setSelectionMode(QDataVis::SelectionModeItem);
+ m_chart->setSelectionMode(QDataVis::SelectionItem);
}
}
@@ -160,10 +160,10 @@ void GraphModifier::selectBar()
{
QPoint targetBar(5, 5);
QPoint noSelection(-1, -1);
- if (m_selectedBarPos != targetBar)
- m_chart->setSelectedBarPos(targetBar);
+ if (m_selectedBar != targetBar)
+ m_chart->setSelectedBar(targetBar);
else
- m_chart->setSelectedBarPos(noSelection);
+ m_chart->setSelectedBar(noSelection);
}
void GraphModifier::swapAxis()
@@ -317,7 +317,7 @@ void GraphModifier::insertRow()
(*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % 100));
// TODO Needs to be changed to account for data window offset once it is implemented.
- int row = qMax(m_selectedBarPos.x(), 0);
+ int row = qMax(m_selectedBar.x(), 0);
QString label = QStringLiteral("Insert %1").arg(insertCounter++);
m_chart->activeDataProxy()->insertRow(row, dataRow, label);
}
@@ -337,7 +337,7 @@ void GraphModifier::insertRows()
}
// TODO Needs to be changed to account for data window offset once it is implemented.
- int row = qMax(m_selectedBarPos.x(), 0);
+ int row = qMax(m_selectedBar.x(), 0);
m_chart->activeDataProxy()->insertRows(row, dataArray, labels);
qDebug() << "Inserted" << m_rowCount << "rows, time:" << timer.elapsed();
}
@@ -345,8 +345,8 @@ void GraphModifier::insertRows()
void GraphModifier::changeItem()
{
// TODO Needs to be changed to account for data window offset once it is implemented.
- int row = m_selectedBarPos.x();
- int column = m_selectedBarPos.y();
+ int row = m_selectedBar.x();
+ int column = m_selectedBar.y();
if (row >= 0 && column >= 0) {
QBarDataItem item(qreal(rand() % 100));
m_chart->activeDataProxy()->setItem(row, column, item);
@@ -356,7 +356,7 @@ void GraphModifier::changeItem()
void GraphModifier::changeRow()
{
// TODO Needs to be changed to account for data window offset once it is implemented.
- int row = m_selectedBarPos.x();
+ int row = m_selectedBar.x();
if (row >= 0) {
QBarDataRow *newRow = new QBarDataRow(m_chart->activeDataProxy()->rowAt(row)->size());
for (int i = 0; i < newRow->size(); i++)
@@ -369,7 +369,7 @@ void GraphModifier::changeRow()
void GraphModifier::changeRows()
{
// TODO Needs to be changed to account for data window offset once it is implemented.
- int row = m_selectedBarPos.x();
+ int row = m_selectedBar.x();
if (row >= 0) {
int startRow = qMax(row - 2, 0);
QBarDataArray newArray;
@@ -388,7 +388,7 @@ void GraphModifier::changeRows()
void GraphModifier::removeRow()
{
// TODO Needs to be changed to account for data window offset once it is implemented.
- int row = m_selectedBarPos.x();
+ int row = m_selectedBar.x();
if (row >= 0)
m_chart->activeDataProxy()->removeRows(row, 1);
}
@@ -396,7 +396,7 @@ void GraphModifier::removeRow()
void GraphModifier::removeRows()
{
// TODO Needs to be changed to account for data window offset once it is implemented.
- int row = m_selectedBarPos.x();
+ int row = m_selectedBar.x();
if (row >= 0) {
int startRow = qMax(row - 2, 0);
m_chart->activeDataProxy()->removeRows(startRow, 3);
@@ -477,10 +477,10 @@ void GraphModifier::changeSelectionMode()
{
static int selectionMode = m_chart->selectionMode();
- if (++selectionMode > QDataVis::SelectionModeSliceColumn)
- selectionMode = QDataVis::SelectionModeNone;
+ if (++selectionMode > (QDataVis::SelectionItemAndColumn | QDataVis::SelectionSlice))
+ selectionMode = QDataVis::SelectionNone;
- m_chart->setSelectionMode((QDataVis::SelectionMode)selectionMode);
+ m_chart->setSelectionMode((QDataVis::SelectionFlag)selectionMode);
}
void GraphModifier::changeFont(const QFont &font)
@@ -507,7 +507,7 @@ void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
void GraphModifier::handleSelectionChange(const QPoint &position)
{
- m_selectedBarPos = position;
+ m_selectedBar = position;
qDebug() << "Selected bar position:" << position;
}
diff --git a/tests/barstest/chart.h b/tests/barstest/chart.h
index e4e96ffb..6d33bacb 100644
--- a/tests/barstest/chart.h
+++ b/tests/barstest/chart.h
@@ -96,7 +96,7 @@ private:
qreal m_maxval;
QStringList m_months;
QStringList m_years;
- QPoint m_selectedBarPos;
+ QPoint m_selectedBar;
Q3DValueAxis *m_autoAdjustingAxis;
Q3DValueAxis *m_fixedRangeAxis;
Q3DValueAxis *m_temperatureAxis;
diff --git a/tests/barstest/main.cpp b/tests/barstest/main.cpp
index 7742cb0e..0d3838a8 100644
--- a/tests/barstest/main.cpp
+++ b/tests/barstest/main.cpp
@@ -287,7 +287,7 @@ int main(int argc, char **argv)
&QComboBox::setCurrentIndex);
QObject::connect(widgetchart, &Q3DBars::shadowQualityChanged, modifier,
&GraphModifier::shadowQualityUpdatedByVisual);
- QObject::connect(widgetchart, &Q3DBars::selectedBarPosChanged, modifier,
+ QObject::connect(widgetchart, &Q3DBars::selectedBarChanged, modifier,
&GraphModifier::handleSelectionChange);
QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
diff --git a/tests/kinectsurface/surfacedata.cpp b/tests/kinectsurface/surfacedata.cpp
index b11be8d5..79489fc8 100644
--- a/tests/kinectsurface/surfacedata.cpp
+++ b/tests/kinectsurface/surfacedata.cpp
@@ -45,7 +45,7 @@ SurfaceData::SurfaceData(Q3DSurface *surface, Q3DScatter *scatter, Q3DBars *bars
gradient.setColorAt(0.33, Qt::blue);
gradient.setColorAt(0.67, Qt::red);
gradient.setColorAt(1.0, Qt::yellow);
- m_surface->setSelectionMode(QDataVis::SelectionModeNone);
+ m_surface->setSelectionMode(QDataVis::SelectionNone);
m_surface->setGridVisible(false);
m_surface->setGradient(gradient);
m_surface->axisY()->setMax(255);
@@ -57,7 +57,7 @@ SurfaceData::SurfaceData(Q3DSurface *surface, Q3DScatter *scatter, Q3DBars *bars
// Initialize scatter
m_scatter->setTheme(QDataVis::ThemeStoneMoss);
- m_scatter->setSelectionMode(QDataVis::SelectionModeNone);
+ m_scatter->setSelectionMode(QDataVis::SelectionNone);
m_scatter->setGridVisible(false);
m_scatter->setObjectType(QDataVis::MeshStyleDots, false);
m_scatter->setShadowQuality(QDataVis::ShadowQualitySoftLow);
diff --git a/tests/qmlcamera/qml/qmlcamera/main.qml b/tests/qmlcamera/qml/qmlcamera/main.qml
index 72d2a45f..dbe11b8e 100644
--- a/tests/qmlcamera/qml/qmlcamera/main.qml
+++ b/tests/qmlcamera/qml/qmlcamera/main.qml
@@ -46,7 +46,7 @@ Item {
width: dataView.width
height: dataView.height
shadowQuality: Bars3D.ShadowQualityMedium
- selectionMode: Bars3D.SelectionModeItem
+ selectionMode: Bars3D.SelectionItem
font.pointSize: 35
theme: Bars3D.ThemeRetro
labelStyle: Bars3D.LabelStyleFromTheme
@@ -59,7 +59,7 @@ Item {
valueAxis: chartAxes.expenses
itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel"
- onSelectedBarPosChanged: {
+ onSelectedBarChanged: {
// Set camControlArea current row to selected bar
var rowRole = chartData.proxy.rowLabels[position.x];
var colRole = chartData.proxy.columnLabels[position.y];
diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp
index f23ee99d..48f1d999 100644
--- a/tests/scattertest/scatterchart.cpp
+++ b/tests/scattertest/scatterchart.cpp
@@ -48,6 +48,8 @@ ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
proxy->setItemLabelFormat("@xTitle: @xLabel @yTitle: @yLabel @zTitle: @zLabel");
m_chart->setActiveDataProxy(proxy);
+ m_chart->setSelectionMode(QDataVis::SelectionItemAndColumn);
+
connect(&m_timer, &QTimer::timeout, this, &ScatterDataModifier::timeout);
}
diff --git a/tests/spectrum/spectrumapp/main.cpp b/tests/spectrum/spectrumapp/main.cpp
index 3d2e2bf1..31bdb0f1 100644
--- a/tests/spectrum/spectrumapp/main.cpp
+++ b/tests/spectrum/spectrumapp/main.cpp
@@ -99,7 +99,7 @@ MainApp::MainApp(Q3DBars *window)
// Set color scheme
m_chart->setBarColor(QColor(Qt::red), false);
// Disable selection
- m_chart->setSelectionMode(QDataVis::SelectionModeNone);
+ m_chart->setSelectionMode(QDataVis::SelectionNone);
QObject::connect(m_engine, &Engine::changedSpectrum, this, &MainApp::spectrumChanged);
QObject::connect(m_engine, &Engine::stateChanged, this, &MainApp::stateChanged);
m_restartTimer->setSingleShot(true);
diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp
index d4e99031..bd6ec920 100644
--- a/tests/surfacetest/graphmodifier.cpp
+++ b/tests/surfacetest/graphmodifier.cpp
@@ -23,11 +23,12 @@
#include <qmath.h>
#include <QLinearGradient>
#include <QDebug>
+#include <QComboBox>
QT_DATAVISUALIZATION_USE_NAMESPACE
//#define JITTER_PLANE
-//#define WONKY_PLANE
+#define WONKY_PLANE
GraphModifier::GraphModifier(Q3DSurface *graph)
: m_graph(graph),
@@ -55,6 +56,7 @@ GraphModifier::GraphModifier(Q3DSurface *graph)
changeStyle();
connect(&m_timer, &QTimer::timeout, this, &GraphModifier::timeout);
+ connect(m_graph, &Q3DSurface::selectedPointChanged, this, &GraphModifier::selectedPointChanged);
}
GraphModifier::~GraphModifier()
@@ -137,6 +139,7 @@ void GraphModifier::togglePlane(bool enable)
float halfZ = m_zCount / 2;
float wonkyFactor = 0.01f;
float maxStepX = 0.0f;
+ float add = 0.0f;
for (float i = 0; i < m_zCount; i++) {
QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
if (i < halfZ) {
@@ -145,15 +148,17 @@ void GraphModifier::togglePlane(bool enable)
} else {
stepX -= wonkyFactor;
}
+ add = 0.0f;
for (float j = 0; j < m_xCount; j++) {
(*newRow)[j].setPosition(QVector3D(j * stepX + minX, -0.04f,
- i * stepZ + minZ));
+ i * stepZ + minZ + add));
+ add += 0.5f;
}
*m_planeArray << newRow;
}
- resetArrayAndSliders(m_planeArray, minZ, maxZ, minX, m_xCount * maxStepX + minZ);
+ resetArrayAndSliders(m_planeArray, minZ, maxZ + add, minX, m_xCount * maxStepX + minX);
#else
for (float i = 0; i < m_zCount; i++) {
QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
@@ -303,6 +308,20 @@ void GraphModifier::changeStyle()
style = QDataVis::LabelStyleOpaque;
}
+void GraphModifier::selectButtonClicked()
+{
+ int row = rand() % m_graph->activeDataProxy()->rowCount();
+ int col = rand() % m_graph->activeDataProxy()->columnCount();
+
+ m_graph->setSelectedPoint(QPoint(row, col));
+}
+
+void GraphModifier::selectedPointChanged(const QPoint &point)
+{
+ QString labelText = QStringLiteral("Selected row: %1, column: %2").arg(point.x()).arg(point.y());
+ m_selectionInfoLabel->setText(labelText);
+}
+
void GraphModifier::changeTheme(int theme)
{
m_graph->setTheme((QDataVis::Theme)theme);
@@ -347,26 +366,10 @@ void GraphModifier::changeShadowQuality(int quality)
void GraphModifier::changeSelectionMode(int mode)
{
- switch (mode) {
- case 0:
- qDebug() << "QDataVis::SelectionModeNone";
- m_graph->setSelectionMode(QDataVis::SelectionModeNone);
- break;
- case 1:
- qDebug() << "QDataVis::SelectionModeItem";
- m_graph->setSelectionMode(QDataVis::SelectionModeItem);
- break;
- case 2:
- qDebug() << "QDataVis::SelectionModeSliceRow";
- m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow);
- break;
- case 3:
- qDebug() << "QDataVis::SelectionModeSliceColumn";
- m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn);
- break;
- default:
- qDebug() << __FUNCTION__ << " Unsupported selection mode.";
- break;
+ QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
+ if (comboBox) {
+ int flags = comboBox->itemData(mode).toInt();
+ m_graph->setSelectionMode(QDataVis::SelectionFlags(flags));
}
}
diff --git a/tests/surfacetest/graphmodifier.h b/tests/surfacetest/graphmodifier.h
index 83b1873b..ed94b372 100644
--- a/tests/surfacetest/graphmodifier.h
+++ b/tests/surfacetest/graphmodifier.h
@@ -23,6 +23,7 @@
#include <QtDataVisualization/QSurfaceDataProxy>
#include <QSlider>
#include <QTimer>
+#include <QLabel>
using namespace QtDataVisualization;
@@ -61,6 +62,9 @@ public:
void gradientPressed();
void changeFont(const QFont &font);
void changeStyle();
+ void selectButtonClicked();
+ void setSelectionInfoLabel(QLabel *label) {m_selectionInfoLabel = label; }
+ void selectedPointChanged(const QPoint &point);
public slots:
void changeShadowQuality(int quality);
@@ -90,6 +94,7 @@ private:
qreal m_minZ;
QTimer m_timer;
QSurfaceDataArray *m_planeArray;
+ QLabel *m_selectionInfoLabel;
};
#endif
diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp
index 19f30e5d..e4283b3e 100644
--- a/tests/surfacetest/main.cpp
+++ b/tests/surfacetest/main.cpp
@@ -167,12 +167,37 @@ int main(int argc, char *argv[])
// shadowQuality->addItem(QStringLiteral("High Soft"));
// shadowQuality->setCurrentIndex(3);
QComboBox *selectionMode = new QComboBox(widget);
- selectionMode->addItem(QStringLiteral("SelectionModeNone"));
- selectionMode->addItem(QStringLiteral("SelectionModeItem"));
- selectionMode->addItem(QStringLiteral("SelectionModeSliceRow"));
- selectionMode->addItem(QStringLiteral("SelectionModeSliceColumn"));
+ selectionMode->addItem(QStringLiteral("None"),
+ int(QDataVis::SelectionNone));
+ selectionMode->addItem(QStringLiteral("Item"),
+ int(QDataVis::SelectionItem));
+ selectionMode->addItem(QStringLiteral("Row"),
+ int(QDataVis::SelectionRow));
+ selectionMode->addItem(QStringLiteral("Item and Row"),
+ int(QDataVis::SelectionItemAndRow));
+ selectionMode->addItem(QStringLiteral("Column"),
+ int(QDataVis::SelectionColumn));
+ selectionMode->addItem(QStringLiteral("Item and Column"),
+ int(QDataVis::SelectionItemAndColumn));
+ selectionMode->addItem(QStringLiteral("Row and Column"),
+ int(QDataVis::SelectionRowAndColumn));
+ selectionMode->addItem(QStringLiteral("Item, Row and Column"),
+ int(QDataVis::SelectionItemRowAndColumn));
+ selectionMode->addItem(QStringLiteral("Slice into Row"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionRow));
+ selectionMode->addItem(QStringLiteral("Slice into Row and Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndRow));
+ selectionMode->addItem(QStringLiteral("Slice into Column"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionColumn));
+ selectionMode->addItem(QStringLiteral("Slice into Column and Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndColumn));
selectionMode->setCurrentIndex(1);
+ QPushButton *selectButton = new QPushButton(widget);
+ selectButton->setText(QStringLiteral("Select random point"));
+
+ QLabel *selectionInfoLabel = new QLabel(widget);
+
// Add controls to the layout
vLayout->addWidget(smoothCB);
vLayout->addWidget(surfaceGridCB);
@@ -200,6 +225,8 @@ int main(int argc, char *argv[])
// vLayout->addWidget(shadowQuality);
vLayout->addWidget(new QLabel(QStringLiteral("Selection Mode")));
vLayout->addWidget(selectionMode);
+ vLayout->addWidget(selectButton);
+ vLayout->addWidget(selectionInfoLabel);
widget->show();
@@ -242,6 +269,8 @@ int main(int argc, char *argv[])
// modifier, SLOT(changeShadowQuality(int)));
QObject::connect(selectionMode, SIGNAL(currentIndexChanged(int)),
modifier, SLOT(changeSelectionMode(int)));
+ QObject::connect(selectButton, &QPushButton::clicked,
+ modifier, &GraphModifier::selectButtonClicked);
modifier->setGridSliderZ(gridSliderZ);
modifier->setGridSliderX(gridSliderX);
@@ -250,6 +279,7 @@ int main(int argc, char *argv[])
modifier->setAxisMinSliderX(axisMinSliderX);
modifier->setAxisMinSliderZ(axisMinSliderZ);
modifier->toggleGridSliderLock(gridSlidersLockCB->checkState());
+ modifier->setSelectionInfoLabel(selectionInfoLabel);
sqrtSinCB->setChecked(true);
return app.exec();