summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine/q3dscene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/engine/q3dscene.cpp')
-rw-r--r--src/datavisualization/engine/q3dscene.cpp123
1 files changed, 106 insertions, 17 deletions
diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp
index 9464bc8d..e4015c2b 100644
--- a/src/datavisualization/engine/q3dscene.cpp
+++ b/src/datavisualization/engine/q3dscene.cpp
@@ -96,9 +96,33 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty point Scene3D::graphPositionQuery
+ *
+ * This property contains the coordinates for the user input that should be processed
+ * by the scene as a graph position query. If this is set to value other than
+ * invalidSelectionPoint, the graph tries to match a graph position to the given \a point
+ * within the primary viewport.
+ * After the rendering pass this property is returned to its default state of
+ * invalidSelectionPoint. The queried graph position can be read from
+ * AbstractGraph3D::queriedGraphPosition property after the next render pass.
+ *
+ * There isn't a single correct 3D coordinate to match to each specific screen position, so to be
+ * consistent, the queries are always done against the inner sides of an invisible box surrounding
+ * the graph.
+ *
+ * \note Bar graphs allow graph position queries only at the graph floor level.
+ *
+ * \sa AbstractGraph3D::queriedGraphPosition
+ */
+
+/*!
* \qmlproperty bool Scene3D::slicingActive
*
- * This property contains whether 2D slicing view is currently active or not.
+ * This property contains whether 2D slicing view is currently active or not. If setting it, you
+ * must make sure AbstractGraph3D::selectionMode has either
+ * \l{QAbstract3DGraph::SelectionRow}{AbstractGraph3D.SelectionRow} or
+ * \l{QAbstract3DGraph::SelectionColumn}{AbstractGraph3D.SelectionColumn} flag set, and there is a
+ * valid selection.
* \note Not all visualizations support the 2D slicing view.
*/
@@ -135,7 +159,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* A constant property providing an invalid point for selection.
*/
-
/*!
* Constructs a basic scene with one light and one camera in it. An
* optional \a parent parameter can be given and is then passed to QObject constructor.
@@ -195,33 +218,35 @@ void Q3DScene::setPrimarySubViewport(const QRect &primarySubViewport)
/*!
* Returns whether the given \a point resides inside the primary subview or not.
* \return \c true if the point is inside the primary subview.
+ * \note If subviews are superimposed, and the given \a point resides inside both, result is
+ * \c true only when the primary subview is on top.
*/
bool Q3DScene::isPointInPrimarySubView(const QPoint &point)
{
int x = point.x();
int y = point.y();
- int areaMinX = d_ptr->m_primarySubViewport.x();
- int areaMaxX = d_ptr->m_primarySubViewport.x() + d_ptr->m_primarySubViewport.width();
- int areaMinY = d_ptr->m_primarySubViewport.y();
- int areaMaxY = d_ptr->m_primarySubViewport.y() + d_ptr->m_primarySubViewport.height();
-
- return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY );
+ bool isInSecondary = d_ptr->isInArea(d_ptr->m_secondarySubViewport, x, y);
+ if (!isInSecondary || (isInSecondary && !d_ptr->m_isSecondarySubviewOnTop))
+ return d_ptr->isInArea(d_ptr->m_primarySubViewport, x, y);
+ else
+ return false;
}
/*!
* Returns whether the given \a point resides inside the secondary subview or not.
* \return \c true if the point is inside the secondary subview.
+ * \note If subviews are superimposed, and the given \a point resides inside both, result is
+ * \c true only when the secondary subview is on top.
*/
bool Q3DScene::isPointInSecondarySubView(const QPoint &point)
{
int x = point.x();
int y = point.y();
- int areaMinX = d_ptr->m_secondarySubViewport.x();
- int areaMaxX = d_ptr->m_secondarySubViewport.x() + d_ptr->m_secondarySubViewport.width();
- int areaMinY = d_ptr->m_secondarySubViewport.y();
- int areaMaxY = d_ptr->m_secondarySubViewport.y() + d_ptr->m_secondarySubViewport.height();
-
- return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY );
+ bool isInPrimary = d_ptr->isInArea(d_ptr->m_primarySubViewport, x, y);
+ if (!isInPrimary || (isInPrimary && d_ptr->m_isSecondarySubviewOnTop))
+ return d_ptr->isInArea(d_ptr->m_secondarySubViewport, x, y);
+ else
+ return false;
}
/*!
@@ -254,7 +279,7 @@ void Q3DScene::setSecondarySubViewport(const QRect &secondarySubViewport)
* \property Q3DScene::selectionQueryPosition
*
* This property contains the coordinates for the user input that should be processed
- * by the scene as selection. If this is set to value other than invalidSelectionPoint() the
+ * by the scene as a selection. If this is set to value other than invalidSelectionPoint(), the
* graph tries to select a data item, axis label, or a custom item at the given \a point within
* the primary viewport.
* After the rendering pass the property is returned to its default state of
@@ -289,9 +314,47 @@ QPoint Q3DScene::invalidSelectionPoint()
}
/*!
+ * \property Q3DScene::graphPositionQuery
+ *
+ * This property contains the coordinates for the user input that should be processed
+ * by the scene as a graph position query. If this is set to value other than
+ * invalidSelectionPoint(), the graph tries to match a graph position to the given \a point
+ * within the primary viewport.
+ * After the rendering pass this property is returned to its default state of
+ * invalidSelectionPoint(). The queried graph position can be read from
+ * QAbstract3DGraph::queriedGraphPosition property after the next render pass.
+ *
+ * There isn't a single correct 3D coordinate to match to each specific screen position, so to be
+ * consistent, the queries are always done against the inner sides of an invisible box surrounding
+ * the graph.
+ *
+ * \note Bar graphs allow graph position queries only at the graph floor level.
+ *
+ * \sa QAbstract3DGraph::queriedGraphPosition
+ */
+void Q3DScene::setGraphPositionQuery(const QPoint &point)
+{
+ if (point != d_ptr->m_graphPositionQueryPosition) {
+ d_ptr->m_graphPositionQueryPosition = point;
+ d_ptr->m_changeTracker.graphPositionQueryPositionChanged = true;
+ d_ptr->m_sceneDirty = true;
+
+ emit graphPositionQueryChanged(point);
+ emit d_ptr->needRender();
+ }
+}
+
+QPoint Q3DScene::graphPositionQuery() const
+{
+ return d_ptr->m_graphPositionQueryPosition;
+}
+
+/*!
* \property Q3DScene::slicingActive
*
- * This property contains whether 2D slicing view is currently active or not.
+ * This property contains whether 2D slicing view is currently active or not. If setting it, you
+ * must make sure QAbstract3DGraph::selectionMode has either QAbstract3DGraph::SelectionRow or
+ * QAbstract3DGraph::SelectionColumn flag set, and there is a valid selection.
* \note Not all visualizations support the 2D slicing view.
*/
bool Q3DScene::isSlicingActive() const
@@ -306,6 +369,10 @@ void Q3DScene::setSlicingActive(bool isSlicing)
d_ptr->m_changeTracker.slicingActivatedChanged = true;
d_ptr->m_sceneDirty = true;
+ // Set secondary subview behind primary to achieve default functionality (= clicking on
+ // primary disables slice)
+ setSecondarySubviewOnTop(!isSlicing);
+
d_ptr->calculateSubViewports();
emit slicingActiveChanged(isSlicing);
emit d_ptr->needRender();
@@ -447,7 +514,9 @@ Q3DScenePrivate::Q3DScenePrivate(Q3DScene *q) :
m_light(),
m_isUnderSideCameraEnabled(false),
m_isSlicingActive(false),
- m_selectionQueryPosition(Q3DScene::invalidSelectionPoint())
+ m_selectionQueryPosition(Q3DScene::invalidSelectionPoint()),
+ m_graphPositionQueryPosition(Q3DScene::invalidSelectionPoint()),
+ m_sceneDirty(true)
{
}
@@ -491,6 +560,11 @@ void Q3DScenePrivate::sync(Q3DScenePrivate &other)
m_changeTracker.selectionQueryPositionChanged = false;
other.m_changeTracker.selectionQueryPositionChanged = false;
}
+ if (m_changeTracker.graphPositionQueryPositionChanged) {
+ other.q_ptr->setGraphPositionQuery(q_ptr->graphPositionQuery());
+ m_changeTracker.graphPositionQueryPositionChanged = false;
+ other.m_changeTracker.graphPositionQueryPositionChanged = false;
+ }
if (m_changeTracker.cameraChanged) {
m_camera->setDirty(true);
m_changeTracker.cameraChanged = false;
@@ -649,4 +723,19 @@ void Q3DScenePrivate::setLightPositionRelativeToCamera(const QVector3D &relative
distanceModifier));
}
+void Q3DScenePrivate::markDirty()
+{
+ m_sceneDirty = true;
+ emit needRender();
+}
+
+bool Q3DScenePrivate::isInArea(const QRect &area, int x, int y) const
+{
+ int areaMinX = area.x();
+ int areaMaxX = area.x() + area.width();
+ int areaMinY = area.y();
+ int areaMaxY = area.y() + area.height();
+ return ( x >= areaMinX && x <= areaMaxX && y >= areaMinY && y <= areaMaxY );
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION