summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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();