summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-08-22 13:02:38 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-08-27 07:41:29 +0300
commite26bc838a8b2a5c6ce5013992a81c4b9ad040514 (patch)
treed57c5f93bd88491087ca5b3fac46e82909cb7b1f /src
parentfb11df914d9a548675916f51466822f5263b8ceb (diff)
Add selection signaling for scatter
+ Fix crashes associated with selection + Optimized selection color handling Task-number: QTRD-2132 Task-number: QTRD-2208 Change-Id: Ie38c6779591fb0467cffb052edf7609f6677278a Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/datavis3d/data/abstractrenderitem.cpp7
-rw-r--r--src/datavis3d/data/abstractrenderitem_p.h1
-rw-r--r--src/datavis3d/data/barrenderitem.cpp11
-rw-r--r--src/datavis3d/data/barrenderitem_p.h1
-rw-r--r--src/datavis3d/data/maprenderitem.cpp8
-rw-r--r--src/datavis3d/data/maprenderitem_p.h1
-rw-r--r--src/datavis3d/data/scatterrenderitem.cpp10
-rw-r--r--src/datavis3d/data/scatterrenderitem_p.h17
-rw-r--r--src/datavis3d/engine/bars3drenderer.cpp38
-rw-r--r--src/datavis3d/engine/bars3drenderer_p.h3
-rw-r--r--src/datavis3d/engine/q3dscatter.cpp18
-rw-r--r--src/datavis3d/engine/q3dscatter.h5
-rw-r--r--src/datavis3d/engine/scatter3dcontroller.cpp42
-rw-r--r--src/datavis3d/engine/scatter3dcontroller_p.h11
-rw-r--r--src/datavis3d/engine/scatter3drenderer.cpp155
-rw-r--r--src/datavis3d/engine/scatter3drenderer_p.h13
16 files changed, 216 insertions, 125 deletions
diff --git a/src/datavis3d/data/abstractrenderitem.cpp b/src/datavis3d/data/abstractrenderitem.cpp
index b97ea79e..296cebb4 100644
--- a/src/datavis3d/data/abstractrenderitem.cpp
+++ b/src/datavis3d/data/abstractrenderitem.cpp
@@ -25,6 +25,13 @@ AbstractRenderItem::AbstractRenderItem()
{
}
+AbstractRenderItem::AbstractRenderItem(const AbstractRenderItem &other)
+{
+ m_selectionLabel = other.m_selectionLabel;
+ m_translation = other.m_translation;
+ m_selectionLabelItem = 0;
+}
+
AbstractRenderItem::~AbstractRenderItem()
{
delete m_selectionLabelItem;
diff --git a/src/datavis3d/data/abstractrenderitem_p.h b/src/datavis3d/data/abstractrenderitem_p.h
index 669ba200..becacbe5 100644
--- a/src/datavis3d/data/abstractrenderitem_p.h
+++ b/src/datavis3d/data/abstractrenderitem_p.h
@@ -42,6 +42,7 @@ class AbstractRenderItem
{
public:
AbstractRenderItem();
+ AbstractRenderItem(const AbstractRenderItem &other);
virtual ~AbstractRenderItem();
// Position in 3D scene
diff --git a/src/datavis3d/data/barrenderitem.cpp b/src/datavis3d/data/barrenderitem.cpp
index 8cfb97d2..3530704b 100644
--- a/src/datavis3d/data/barrenderitem.cpp
+++ b/src/datavis3d/data/barrenderitem.cpp
@@ -29,6 +29,17 @@ BarRenderItem::BarRenderItem()
{
}
+BarRenderItem::BarRenderItem(const BarRenderItem &other)
+ : AbstractRenderItem(other)
+{
+ m_renderer = other.m_renderer;
+ m_value = other.m_value;
+ m_position = other.m_position;
+ m_height = other.m_height;
+ m_sliceLabel = other.m_sliceLabel;
+ m_sliceLabelItem = 0;
+}
+
BarRenderItem::~BarRenderItem()
{
delete m_sliceLabelItem;
diff --git a/src/datavis3d/data/barrenderitem_p.h b/src/datavis3d/data/barrenderitem_p.h
index d90c7e04..0b7dc639 100644
--- a/src/datavis3d/data/barrenderitem_p.h
+++ b/src/datavis3d/data/barrenderitem_p.h
@@ -39,6 +39,7 @@ class BarRenderItem : public AbstractRenderItem
{
public:
BarRenderItem();
+ BarRenderItem(const BarRenderItem &other);
virtual ~BarRenderItem();
// Position relative to data window (for bar label generation)
diff --git a/src/datavis3d/data/maprenderitem.cpp b/src/datavis3d/data/maprenderitem.cpp
index 062898aa..d737e6f6 100644
--- a/src/datavis3d/data/maprenderitem.cpp
+++ b/src/datavis3d/data/maprenderitem.cpp
@@ -28,6 +28,14 @@ MapRenderItem::MapRenderItem()
{
}
+MapRenderItem::MapRenderItem(const MapRenderItem &other)
+ : BarRenderItem(other)
+{
+ m_renderer = other.m_renderer;
+ m_mapPosition = other.m_mapPosition;
+ m_itemLabel = other.m_itemLabel;
+}
+
MapRenderItem::~MapRenderItem()
{
}
diff --git a/src/datavis3d/data/maprenderitem_p.h b/src/datavis3d/data/maprenderitem_p.h
index f3674ec5..f8f877af 100644
--- a/src/datavis3d/data/maprenderitem_p.h
+++ b/src/datavis3d/data/maprenderitem_p.h
@@ -40,6 +40,7 @@ class MapRenderItem : public BarRenderItem
{
public:
MapRenderItem();
+ MapRenderItem(const MapRenderItem &other);
virtual ~MapRenderItem();
inline const QPointF &mapPosition() const { return m_mapPosition; }
diff --git a/src/datavis3d/data/scatterrenderitem.cpp b/src/datavis3d/data/scatterrenderitem.cpp
index a7238310..4e6fbe9b 100644
--- a/src/datavis3d/data/scatterrenderitem.cpp
+++ b/src/datavis3d/data/scatterrenderitem.cpp
@@ -23,10 +23,18 @@
QT_DATAVIS3D_BEGIN_NAMESPACE
ScatterRenderItem::ScatterRenderItem()
- : BarRenderItem()
+ : AbstractRenderItem(),
+ m_renderer(0)
{
}
+ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other)
+ : AbstractRenderItem(other)
+{
+ m_renderer = other.m_renderer;
+ m_position = other.m_position;
+}
+
ScatterRenderItem::~ScatterRenderItem()
{
}
diff --git a/src/datavis3d/data/scatterrenderitem_p.h b/src/datavis3d/data/scatterrenderitem_p.h
index 4c9de38c..6fade03e 100644
--- a/src/datavis3d/data/scatterrenderitem_p.h
+++ b/src/datavis3d/data/scatterrenderitem_p.h
@@ -29,20 +29,21 @@
#ifndef SCATTERRENDERITEM_P_H
#define SCATTERRENDERITEM_P_H
-#include "barrenderitem_p.h"
+#include "abstractrenderitem_p.h"
QT_DATAVIS3D_BEGIN_NAMESPACE
class Scatter3DRenderer;
-class ScatterRenderItem : public BarRenderItem
+class ScatterRenderItem : public AbstractRenderItem
{
public:
ScatterRenderItem();
+ ScatterRenderItem(const ScatterRenderItem &other);
virtual ~ScatterRenderItem();
inline const QVector3D &position() const { return m_position; }
- inline void setPosition(const QVector3D &pos) { m_position = pos; }
+ inline void setPosition(const QVector3D &pos);
//inline void setSize(qreal size);
//inline qreal size() const { return m_size; }
@@ -59,6 +60,16 @@ protected:
friend class QScatterDataItem;
};
+void ScatterRenderItem::setPosition(const QVector3D &pos)
+{
+ if (m_position != pos) {
+ m_position = pos;
+ // Force reformatting on next access by setting label string to null string
+ if (!m_selectionLabel.isNull())
+ setSelectionLabel(QString());
+ }
+}
+
typedef QVector<ScatterRenderItem> ScatterRenderItemArray;
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/bars3drenderer.cpp b/src/datavis3d/engine/bars3drenderer.cpp
index 17e1d098..049d9003 100644
--- a/src/datavis3d/engine/bars3drenderer.cpp
+++ b/src/datavis3d/engine/bars3drenderer.cpp
@@ -50,7 +50,6 @@ Bars3dRenderer::Bars3dRenderer(Bars3dController *controller)
: Abstract3DRenderer(controller),
m_controller(controller),
m_selectedBar(0),
- m_previouslySelectedBar(0),
m_sliceSelection(0),
m_sliceCache(0),
m_sliceTitleItem(0),
@@ -709,6 +708,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
// Draw bars
bool barSelectionFound = false;
+ BarRenderItem *selectedBar(0);
for (int row = startRow; row != stopRow; row += stepRow) {
for (int bar = startBar; bar != stopBar; bar += stepBar) {
BarRenderItem &item = m_renderItemArray[row][bar];
@@ -756,8 +756,8 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
lightStrength = m_cachedTheme.m_highlightLightStrength;
// Insert position data into render item. We have no ownership, don't delete the previous one
if (!m_cachedIsSlicingActivated) {
- m_selectedBar = &item;
- m_selectedBar->setPosition(QPoint(row, bar));
+ selectedBar = &item;
+ selectedBar->setPosition(QPoint(row, bar));
item.setTranslation(modelMatrix.column(3).toVector3D());
barSelectionFound = true;
}
@@ -1335,9 +1335,9 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
// Print value of selected bar
glDisable(GL_DEPTH_TEST);
// Draw the selection label
- LabelItem &labelItem = m_selectedBar->selectionLabelItem();
- if (m_previouslySelectedBar != m_selectedBar || m_updateLabels || !labelItem.textureId()) {
- QString labelText = m_selectedBar->selectionLabel();
+ LabelItem &labelItem = selectedBar->selectionLabelItem();
+ if (m_selectedBar != selectedBar || m_updateLabels || !labelItem.textureId()) {
+ QString labelText = selectedBar->selectionLabel();
if (labelText.isNull()) {
static const QString rowIndexTag(QStringLiteral("@rowIdx"));
static const QString rowLabelTag(QStringLiteral("@rowLabel"));
@@ -1349,30 +1349,30 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
static const QString valueLabelTag(QStringLiteral("@valueLabel"));
// Custom format expects printf format specifier. There is no tag for it.
- labelText = generateValueLabel(itemLabelFormat(), m_selectedBar->value());
+ labelText = generateValueLabel(itemLabelFormat(), selectedBar->value());
- labelText.replace(rowIndexTag, QString::number(m_selectedBar->position().x()));
- labelText.replace(rowLabelTag, m_axisCacheX.labels().at(m_selectedBar->position().x()));
+ labelText.replace(rowIndexTag, QString::number(selectedBar->position().x()));
+ labelText.replace(rowLabelTag, m_axisCacheX.labels().at(selectedBar->position().x()));
labelText.replace(rowTitleTag, m_axisCacheX.title());
- labelText.replace(colIndexTag, QString::number(m_selectedBar->position().y()));
- labelText.replace(colLabelTag, m_axisCacheZ.labels().at(m_selectedBar->position().y()));
+ labelText.replace(colIndexTag, QString::number(selectedBar->position().y()));
+ labelText.replace(colLabelTag, m_axisCacheZ.labels().at(selectedBar->position().y()));
labelText.replace(colTitleTag, m_axisCacheZ.title());
labelText.replace(valueTitleTag, m_axisCacheY.title());
if (labelText.contains(valueLabelTag)) {
- QString valueLabelText = generateValueLabel(m_axisCacheY.labelFormat(), m_selectedBar->value());
+ QString valueLabelText = generateValueLabel(m_axisCacheY.labelFormat(), selectedBar->value());
labelText.replace(valueLabelTag, valueLabelText);
}
- m_selectedBar->setSelectionLabel(labelText);
+ selectedBar->setSelectionLabel(labelText);
}
m_drawer->generateLabelItem(labelItem, labelText);
- m_previouslySelectedBar = m_selectedBar;
+ m_selectedBar = selectedBar;
}
- m_drawer->drawLabel(*m_selectedBar, labelItem, viewMatrix, projectionMatrix,
+ m_drawer->drawLabel(*selectedBar, labelItem, viewMatrix, projectionMatrix,
QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_selectedBar->height(),
+ QVector3D(0.0f, 0.0f, 0.0f), selectedBar->height(),
m_cachedSelectionMode, m_labelShader,
m_labelObj, camera, true, false);
@@ -1497,12 +1497,12 @@ void Bars3dRenderer::updateBackgroundEnabled(bool enable)
}
}
-void Bars3dRenderer::updateSelectedBarPos(QPoint selectedBarPos)
+void Bars3dRenderer::updateSelectedBarPos(QPoint position)
{
- if (selectedBarPos == Bars3dController::noSelectionPoint())
+ if (position == Bars3dController::noSelectionPoint())
m_selection = selectionSkipColor;
else
- m_selection = QVector3D(selectedBarPos.x(), selectedBarPos.y(), 0);
+ m_selection = QVector3D(position.x(), position.y(), 0);
}
void Bars3dRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
diff --git a/src/datavis3d/engine/bars3drenderer_p.h b/src/datavis3d/engine/bars3drenderer_p.h
index 5426a5ae..5cd33809 100644
--- a/src/datavis3d/engine/bars3drenderer_p.h
+++ b/src/datavis3d/engine/bars3drenderer_p.h
@@ -63,7 +63,6 @@ private:
// Internal state
BarRenderItem *m_selectedBar; // points to renderitem array
- BarRenderItem *m_previouslySelectedBar; // points to renderitem array
QList<BarRenderItem *> *m_sliceSelection;
AxisRenderCache *m_sliceCache; // not owned
const LabelItem *m_sliceTitleItem; // not owned
@@ -127,7 +126,7 @@ public slots:
void updateSlicingActive(bool isSlicing);
void updateSampleSpace(int rowCount, int columnCount);
void updateBackgroundEnabled(bool enable);
- void updateSelectedBarPos(QPoint selectedBarPos);
+ void updateSelectedBarPos(QPoint position);
// Overloaded from abstract renderer
virtual void updateAxisRange(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
diff --git a/src/datavis3d/engine/q3dscatter.cpp b/src/datavis3d/engine/q3dscatter.cpp
index 30a5eb81..7fc6f628 100644
--- a/src/datavis3d/engine/q3dscatter.cpp
+++ b/src/datavis3d/engine/q3dscatter.cpp
@@ -78,6 +78,8 @@ Q3DScatter::Q3DScatter()
: d_ptr(new Q3DScatterPrivate(this, geometry()))
{
d_ptr->m_shared->initializeOpenGL();
+ QObject::connect(d_ptr->m_shared, &Scatter3DController::selectedItemIndexChanged, this,
+ &Q3DScatter::selectedItemIndexChanged);
}
/*!
@@ -327,6 +329,22 @@ bool Q3DScatter::isBackgroundVisible() const
}
/*!
+ * \property Q3DScatter::selectedItemIndex
+ *
+ * Selects an item in the \a index. Only one item can be selected at a time.
+ * To clear selection, specify an illegal \a index, e.g. -1.
+ */
+void Q3DScatter::setSelectedItemIndex(int index)
+{
+ d_ptr->m_shared->setSelectedItemIndex(index);
+}
+
+int Q3DScatter::selectedItemIndex() const
+{
+ return d_ptr->m_shared->selectedItemIndex();
+}
+
+/*!
* \property Q3DScatter::shadowQuality
*
* Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to
diff --git a/src/datavis3d/engine/q3dscatter.h b/src/datavis3d/engine/q3dscatter.h
index 2094bb5d..26e3da08 100644
--- a/src/datavis3d/engine/q3dscatter.h
+++ b/src/datavis3d/engine/q3dscatter.h
@@ -40,6 +40,7 @@ class QT_DATAVIS3D_EXPORT Q3DScatter : 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(int selectedItemIndex READ selectedItemIndex WRITE setSelectedItemIndex NOTIFY selectedItemIndexChanged)
Q_ENUMS(QtDataVis3D::QDataVis::SelectionMode)
Q_ENUMS(QtDataVis3D::QDataVis::ShadowQuality)
Q_ENUMS(QtDataVis3D::QDataVis::LabelTransparency)
@@ -79,6 +80,9 @@ public:
void setBackgroundVisible(bool visible);
bool isBackgroundVisible() const;
+ void setSelectedItemIndex(int index);
+ int selectedItemIndex() const;
+
void setShadowQuality(QDataVis::ShadowQuality quality);
QDataVis::ShadowQuality shadowQuality() const;
@@ -96,6 +100,7 @@ public:
signals:
void shadowQualityChanged(QDataVis::ShadowQuality quality);
+ void selectedItemIndexChanged(int index);
protected:
void render();
diff --git a/src/datavis3d/engine/scatter3dcontroller.cpp b/src/datavis3d/engine/scatter3dcontroller.cpp
index ef56fc23..3b0a2c1f 100644
--- a/src/datavis3d/engine/scatter3dcontroller.cpp
+++ b/src/datavis3d/engine/scatter3dcontroller.cpp
@@ -35,7 +35,8 @@ Scatter3DController::Scatter3DController(QRect boundRect)
m_mousePos(QPoint(0, 0)),
m_isSlicingActivated(false),
m_renderer(0),
- m_data(0)
+ m_data(0),
+ m_selectedItemIndex(noSelectionIndex())
{
// Default axes
setAxisX(new QValueAxis());
@@ -62,6 +63,9 @@ void Scatter3DController::initializeOpenGL()
m_renderer = new Scatter3DRenderer(this);
setRenderer(m_renderer);
synchDataToRenderer();
+
+ QObject::connect(m_renderer, &Scatter3DRenderer::selectedItemIndexChanged, this,
+ &Scatter3DController::handleSelectedItemIndexChanged, Qt::QueuedConnection);
}
void Scatter3DController::synchDataToRenderer()
@@ -77,6 +81,11 @@ void Scatter3DController::synchDataToRenderer()
m_changeTracker.slicingActiveChanged = false;
}
+ if (m_changeTracker.selectedItemIndexChanged) {
+ m_renderer->updateSelectedItemIndex(m_selectedItemIndex);
+ m_changeTracker.selectedItemIndexChanged = false;
+ }
+
if (m_isDataDirty) {
m_renderer->updateDataModel(m_data);
m_isDataDirty = false;
@@ -243,6 +252,7 @@ void Scatter3DController::setDataProxy(QScatterDataProxy *proxy)
adjustValueAxisRange();
m_isDataDirty = true;
+ setSelectedItemIndex(noSelectionIndex());
}
QScatterDataProxy *Scatter3DController::dataProxy()
@@ -255,6 +265,7 @@ void Scatter3DController::handleArrayReset()
setSlicingActive(false);
adjustValueAxisRange();
m_isDataDirty = true;
+ setSelectedItemIndex(noSelectionIndex());
}
void Scatter3DController::handleItemsAdded(int startIndex, int count)
@@ -282,6 +293,8 @@ void Scatter3DController::handleItemsRemoved(int startIndex, int count)
// TODO should dirty only affected values?
adjustValueAxisRange();
m_isDataDirty = true;
+ if (startIndex >= m_data->itemCount())
+ setSelectedItemIndex(noSelectionIndex());
}
void Scatter3DController::handleItemsInserted(int startIndex, int count)
@@ -293,6 +306,14 @@ void Scatter3DController::handleItemsInserted(int startIndex, int count)
m_isDataDirty = true;
}
+void Scatter3DController::handleSelectedItemIndexChanged(int index)
+{
+ if (index != m_selectedItemIndex) {
+ m_selectedItemIndex = index;
+ emit selectedItemIndexChanged(index);
+ }
+}
+
void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation(
QAbstractAxis::AxisOrientation orientation, bool autoAdjust)
{
@@ -329,6 +350,25 @@ void Scatter3DController::setSelectionMode(QDataVis::SelectionMode mode)
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 >= m_data->itemCount())
+ index = noSelectionIndex();
+
+ if (index != m_selectedItemIndex) {
+ m_selectedItemIndex = index;
+ m_changeTracker.selectedItemIndexChanged = true;
+ emit selectedItemIndexChanged(index);
+ }
+}
+
+int Scatter3DController::selectedItemIndex() const
+{
+ return m_selectedItemIndex;
+}
+
QPoint Scatter3DController::mousePosition()
{
return m_mousePos;
diff --git a/src/datavis3d/engine/scatter3dcontroller_p.h b/src/datavis3d/engine/scatter3dcontroller_p.h
index 437664b7..9d847852 100644
--- a/src/datavis3d/engine/scatter3dcontroller_p.h
+++ b/src/datavis3d/engine/scatter3dcontroller_p.h
@@ -41,9 +41,11 @@ class QScatterDataProxy;
struct Scatter3DChangeBitField {
bool slicingActiveChanged : 1;
+ bool selectedItemIndexChanged : 1;
Scatter3DChangeBitField() :
- slicingActiveChanged(true)
+ slicingActiveChanged(true),
+ selectedItemIndexChanged(true)
{
}
};
@@ -63,6 +65,7 @@ private:
// Rendering
Scatter3DRenderer *m_renderer;
QScatterDataProxy *m_data;
+ int m_selectedItemIndex;
public:
explicit Scatter3DController(QRect rect);
@@ -85,6 +88,10 @@ public:
// Change selection mode
void setSelectionMode(QDataVis::SelectionMode mode);
+ void setSelectedItemIndex(int index);
+ int selectedItemIndex() const;
+ static inline int noSelectionIndex() { return -1; }
+
#if defined(Q_OS_ANDROID)
void mouseDoubleClickEvent(QMouseEvent *event);
void touchEvent(QTouchEvent *event);
@@ -108,9 +115,11 @@ public slots:
void handleItemsChanged(int startIndex, int count);
void handleItemsRemoved(int startIndex, int count);
void handleItemsInserted(int startIndex, int count);
+ void handleSelectedItemIndexChanged(int index);
signals:
void slicingActiveChanged(bool isSlicing);
+ void selectedItemIndexChanged(int index);
private:
void adjustValueAxisRange();
diff --git a/src/datavis3d/engine/scatter3drenderer.cpp b/src/datavis3d/engine/scatter3drenderer.cpp
index 93e7cca1..096de7ed 100644
--- a/src/datavis3d/engine/scatter3drenderer.cpp
+++ b/src/datavis3d/engine/scatter3drenderer.cpp
@@ -52,7 +52,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
: Abstract3DRenderer(controller),
m_controller(controller),
m_selectedItem(0),
- m_previouslySelectedItem(0),
m_xFlipped(false),
m_zFlipped(false),
m_yFlipped(false),
@@ -76,6 +75,7 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_heightNormalizer(1.0f),
m_scaleFactor(0),
m_selection(selectionSkipColor),
+ m_previousSelection(selectionSkipColor),
m_areaSize(QSizeF(0.0, 0.0)),
m_dotSizeScale(1.0f),
m_hasHeightAdjustmentChanged(true)
@@ -143,15 +143,12 @@ void Scatter3DRenderer::updateDataModel(QScatterDataProxy *dataProxy)
int dataSize = dataArray.size();
m_renderItemArray.resize(dataSize);
for (int i = 0; i < dataSize ; i++) {
- qreal value = dataArray.at(i).position().y();
- m_renderItemArray[i].setValue(value);
m_renderItemArray[i].setPosition(dataArray.at(i).position());
- //m_renderItemArray[i].setHeight(value / m_heightNormalizer);
- //m_renderItemArray[i].setItemLabel(dataArray.at(i).label());
calculateTranslation(m_renderItemArray[i]);
m_renderItemArray[i].setRenderer(this);
}
m_dotSizeScale = (GLfloat)qBound(0.01, (2.0 / qSqrt((qreal)dataSize)), 0.1);
+ m_selectedItem = 0;
Abstract3DRenderer::updateDataModel(dataProxy);
}
@@ -402,14 +399,15 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
// Draw dots to selection buffer
glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
- glClearColor(selectionSkipColor.x() / 255, selectionSkipColor.y() / 255,
- selectionSkipColor.z() / 255, 1.0f); // Set clear color to white (= skipColor)
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Set clear color to white (= skipColor)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
- GLint dotIdxRed = 0;
- GLint dotIdxGreen = 0;
- GLint dotIdxBlue = 0;
- for (int dot = 0; dot < m_renderItemArray.size(); dot++, dotIdxRed++) {
+
+ int arraySize = m_renderItemArray.size();
+ if (arraySize > 0xfffffe) // Max possible different selection colors, 0xffffff being skipColor
+ qFatal("Too many objects");
+
+ for (int dot = 0; dot < arraySize; dot++) {
const ScatterRenderItem &item = m_renderItemArray.at(dot);
QMatrix4x4 modelMatrix;
@@ -427,20 +425,8 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
- if (dotIdxRed > 0 && dotIdxRed % 256 == 0) {
- dotIdxRed = 0;
- dotIdxGreen++;
- }
- if (dotIdxGreen > 0 && dotIdxGreen % 256 == 0) {
- dotIdxGreen = 0;
- dotIdxBlue++;
- }
- if (dotIdxBlue > 255)
- qFatal("Too many objects");
-
- QVector3D dotColor = QVector3D((GLfloat)dotIdxRed / 255.0f,
- (GLfloat)dotIdxGreen / 255.0f,
- (GLfloat)dotIdxBlue / 255.0f);
+ QVector3D dotColor = indexToSelectionColor(dot);
+ dotColor /= 255.0f;
m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
m_selectionShader->setUniformValue(m_selectionShader->color(), dotColor);
@@ -501,6 +487,22 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
// 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);
+
for (int dot = 0; dot < m_renderItemArray.size(); dot++) {
ScatterRenderItem &item = m_renderItemArray[dot];
@@ -539,28 +541,12 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QVector3D dotColor = baseColor + heightColor;
GLfloat lightStrength = m_cachedTheme.m_lightStrength;
- if (m_cachedSelectionMode > QDataVis::ModeNone) {
- Scatter3DController::SelectionType selectionType = isSelected(dot, m_selection);
- switch (selectionType) {
- case Scatter3DController::SelectionItem: {
- 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
- m_selectedItem = &item;
- dotSelectionFound = true;
- break;
- }
- case Scatter3DController::SelectionNone: {
- // Current dot is not selected, nor on a row or column
- // do nothing
- break;
- }
- default: {
- // Unsupported selection mode
- // do nothing
- break;
- }
- }
+ if (m_cachedSelectionMode > QDataVis::ModeNone && (selectedIndex == 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
+ selectedItem = &item;
+ dotSelectionFound = true;
}
// Set shader bindings
@@ -1214,10 +1200,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
} else {
glDisable(GL_DEPTH_TEST);
// Draw the selection label
- LabelItem &labelItem = m_selectedItem->selectionLabelItem();
- if (m_previouslySelectedItem != m_selectedItem || m_updateLabels
+ LabelItem &labelItem = selectedItem->selectionLabelItem();
+ if (m_selectedItem != selectedItem || m_updateLabels
|| !labelItem.textureId()) {
- QString labelText = m_selectedItem->selectionLabel();
+ QString labelText = selectedItem->selectionLabel();
if (labelText.isNull()) {
static const QString xTitleTag(QStringLiteral("@xTitle"));
static const QString yTitleTag(QStringLiteral("@yTitle"));
@@ -1234,29 +1220,29 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
if (labelText.contains(xLabelTag)) {
QString valueLabelText = generateValueLabel(m_axisCacheX.labelFormat(),
- m_selectedItem->position().x());
+ selectedItem->position().x());
labelText.replace(xLabelTag, valueLabelText);
}
if (labelText.contains(yLabelTag)) {
QString valueLabelText = generateValueLabel(m_axisCacheY.labelFormat(),
- m_selectedItem->position().y());
+ selectedItem->position().y());
labelText.replace(yLabelTag, valueLabelText);
}
if (labelText.contains(zLabelTag)) {
QString valueLabelText = generateValueLabel(m_axisCacheZ.labelFormat(),
- m_selectedItem->position().z());
+ selectedItem->position().z());
labelText.replace(zLabelTag, valueLabelText);
}
- m_selectedItem->setSelectionLabel(labelText);
+ selectedItem->setSelectionLabel(labelText);
}
m_drawer->generateLabelItem(labelItem, labelText);
- m_previouslySelectedItem = m_selectedItem;
+ m_selectedItem = selectedItem;
}
- m_drawer->drawLabel(*m_selectedItem, labelItem, viewMatrix, projectionMatrix,
+ m_drawer->drawLabel(*selectedItem, labelItem, viewMatrix, projectionMatrix,
QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_selectedItem->height(),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
m_labelObj, camera, true, false, Drawer::LabelMid);
@@ -1273,6 +1259,14 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
m_labelShader->release();
}
+void Scatter3DRenderer::updateSelectedItemIndex(int index)
+{
+ if (index == Scatter3DController::noSelectionIndex())
+ m_selection = selectionSkipColor;
+ else
+ m_selection = indexToSelectionColor(index);
+}
+
void Scatter3DRenderer::handleResize()
{
//qDebug() << __FUNCTION__;
@@ -1395,44 +1389,6 @@ void Scatter3DRenderer::calculateSceneScalingFactors()
//qDebug() << m_heightNormalizer << m_areaSize << m_scaleFactor << m_axisCacheY.max() << m_axisCacheX.max() << m_axisCacheZ.max();
}
-Scatter3DController::SelectionType Scatter3DRenderer::isSelected(GLint dot,
- const QVector3D &selection)
-{
- //qDebug() << __FUNCTION__;
- GLubyte dotIdxRed = 0;
- GLubyte dotIdxGreen = 0;
- GLubyte dotIdxBlue = 0;
- //static QVector3D prevSel = selection; // TODO: For debugging
- Scatter3DController::SelectionType isSelectedType = Scatter3DController::SelectionNone;
-
- if (selection == selectionSkipColor)
- return isSelectedType; // skip window
-
- if (dot <= 255) {
- dotIdxRed = dot;
- } else if (dot <= 65535) {
- dotIdxGreen = dot / 256;
- dotIdxRed = dot % 256;
- } else {
- dotIdxBlue = dot / 65535;
- dotIdxGreen = dot % 65535;
- dotIdxRed = dot % 256;
- }
-
- QVector3D current = QVector3D(dotIdxRed, dotIdxGreen, dotIdxBlue);
-
- // TODO: For debugging
- //if (selection != prevSel) {
- // qDebug() << selection.x() << selection .y() << selection.z();
- // prevSel = selection;
- //}
-
- if (current == selection)
- isSelectedType = Scatter3DController::SelectionItem;
-
- return isSelectedType;
-}
-
QRect Scatter3DRenderer::mainViewPort()
{
//qDebug() << __FUNCTION__;
@@ -1534,4 +1490,13 @@ void Scatter3DRenderer::initLabelShaders(const QString &vertexShader, const QStr
m_labelShader->initialize();
}
+QVector3D Scatter3DRenderer::indexToSelectionColor(GLint index)
+{
+ GLubyte dotIdxRed = index & 0xff;
+ GLubyte dotIdxGreen = (index & 0xff00) >> 8;
+ GLubyte dotIdxBlue = (index & 0xff0000) >> 16;
+
+ return QVector3D(dotIdxRed, dotIdxGreen, dotIdxBlue);
+}
+
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/scatter3drenderer_p.h b/src/datavis3d/engine/scatter3drenderer_p.h
index 2fb81855..12fa7a04 100644
--- a/src/datavis3d/engine/scatter3drenderer_p.h
+++ b/src/datavis3d/engine/scatter3drenderer_p.h
@@ -60,7 +60,6 @@ private:
// Internal state
ScatterRenderItem *m_selectedItem; // points to renderitem array
- ScatterRenderItem *m_previouslySelectedItem; // points to renderitem array
bool m_xFlipped;
bool m_zFlipped;
bool m_yFlipped;
@@ -85,6 +84,7 @@ private:
GLfloat m_heightNormalizer;
GLfloat m_scaleFactor;
QVector3D m_selection;
+ QVector3D m_previousSelection;
QSizeF m_areaSize;
GLfloat m_dotSizeScale;
@@ -127,7 +127,6 @@ private:
#endif
void calculateTranslation(ScatterRenderItem &item);
void calculateSceneScalingFactors();
- Scatter3DController::SelectionType isSelected(GLint dot, const QVector3D &selection);
Q_DISABLE_COPY(Scatter3DRenderer)
@@ -138,8 +137,16 @@ public slots:
// Overloaded from abstract renderer
virtual void updateAxisRange(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
-};
+ void updateSelectedItemIndex(int index);
+
+signals:
+ void selectionUpdated(QVector3D selection);
+ void selectedItemIndexChanged(int index);
+
+private:
+ QVector3D indexToSelectionColor(GLint index);
+};
QT_DATAVIS3D_END_NAMESPACE