summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine/abstract3dcontroller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/engine/abstract3dcontroller.cpp')
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp270
1 files changed, 238 insertions, 32 deletions
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
index 30434dca..275d0fe2 100644
--- a/src/datavisualization/engine/abstract3dcontroller.cpp
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -25,6 +25,7 @@
#include "thememanager_p.h"
#include "q3dtheme_p.h"
#include "qcustom3ditem_p.h"
+#include "utils_p.h"
#include <QtCore/QThread>
#include <QtGui/QOpenGLFramebufferObject>
@@ -37,8 +38,12 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen
m_selectionMode(QAbstract3DGraph::SelectionItem),
m_shadowQuality(QAbstract3DGraph::ShadowQualityMedium),
m_useOrthoProjection(false),
- m_aspectRatio(2.0f),
+ m_aspectRatio(2.0),
+ m_horizontalAspectRatio(0.0),
m_optimizationHints(QAbstract3DGraph::OptimizationDefault),
+ m_reflectionEnabled(false),
+ m_reflectivity(0.5),
+ m_locale(QLocale::c()),
m_scene(scene),
m_activeInputHandler(0),
m_axisX(0),
@@ -50,12 +55,19 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen
m_isCustomItemDirty(true),
m_isSeriesVisualsDirty(true),
m_renderPending(false),
+ m_isPolar(false),
+ m_radialLabelOffset(1.0f),
m_measureFps(false),
m_numFrames(0),
- m_currentFps(0.0)
+ m_currentFps(0.0),
+ m_clickedType(QAbstract3DGraph::ElementNone),
+ m_selectedLabelIndex(-1),
+ m_selectedCustomItemIndex(-1),
+ m_margin(-1.0)
{
if (!m_scene)
m_scene = new Q3DScene;
+ m_scene->setParent(this);
// Set initial theme
Q3DTheme *defaultTheme = new Q3DTheme(Q3DTheme::ThemeQt);
@@ -72,10 +84,6 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen
inputHandler = new QTouch3DInputHandler();
inputHandler->d_ptr->m_isDefaultHandler = true;
setActiveInputHandler(inputHandler);
- connect(inputHandler, &QAbstract3DInputHandler::inputViewChanged, this,
- &Abstract3DController::handleInputViewChanged);
- connect(inputHandler, &QAbstract3DInputHandler::positionChanged, this,
- &Abstract3DController::handleInputPositionChanged);
connect(m_scene->d_ptr.data(), &Q3DScenePrivate::needRender, this,
&Abstract3DController::emitNeedRender);
}
@@ -93,7 +101,7 @@ Abstract3DController::~Abstract3DController()
void Abstract3DController::destroyRenderer()
{
// Renderer can be in another thread, don't delete it directly in that case
- if (m_renderer && m_renderer->thread() != QThread::currentThread())
+ if (m_renderer && m_renderer->thread() && m_renderer->thread() != this->thread())
m_renderer->deleteLater();
else
delete m_renderer;
@@ -107,6 +115,13 @@ void Abstract3DController::destroyRenderer()
void Abstract3DController::setRenderer(Abstract3DRenderer *renderer)
{
m_renderer = renderer;
+
+ // If renderer is created in different thread than controller, make sure renderer gets
+ // destroyed before the render thread finishes.
+ if (renderer->thread() != this->thread()) {
+ QObject::connect(renderer->thread(), &QThread::finished, this,
+ &Abstract3DController::destroyRenderer, Qt::DirectConnection);
+ }
}
void Abstract3DController::addSeries(QAbstract3DSeries *series)
@@ -163,11 +178,14 @@ void Abstract3DController::synchDataToRenderer()
{
// Subclass implementations check for renderer validity already, so no need to check here.
- // If there is a pending click from renderer, handle that first.
- if (m_renderer->isClickPending()) {
+ m_renderPending = false;
+
+ // If there are pending queries, handle those first
+ if (m_renderer->isGraphPositionQueryResolved())
+ handlePendingGraphPositionQuery();
+
+ if (m_renderer->isClickQueryResolved())
handlePendingClick();
- m_renderer->clearClickPending();
- }
startRecordingRemovesAndInserts();
@@ -176,6 +194,16 @@ void Abstract3DController::synchDataToRenderer()
m_renderer->updateTheme(m_themeManager->activeTheme());
+ if (m_changeTracker.polarChanged) {
+ m_renderer->updatePolar(m_isPolar);
+ m_changeTracker.polarChanged = false;
+ }
+
+ if (m_changeTracker.radialLabelOffsetChanged) {
+ m_renderer->updateRadialLabelOffset(m_radialLabelOffset);
+ m_changeTracker.radialLabelOffsetChanged = false;
+ }
+
if (m_changeTracker.shadowQualityChanged) {
m_renderer->updateShadowQuality(m_shadowQuality);
m_changeTracker.shadowQualityChanged = false;
@@ -192,15 +220,31 @@ void Abstract3DController::synchDataToRenderer()
}
if (m_changeTracker.aspectRatioChanged) {
- m_renderer->updateAspectRatio(m_aspectRatio);
+ m_renderer->updateAspectRatio(float(m_aspectRatio));
m_changeTracker.aspectRatioChanged = false;
}
+ if (m_changeTracker.horizontalAspectRatioChanged) {
+ m_renderer->updateHorizontalAspectRatio(float(m_horizontalAspectRatio));
+ m_changeTracker.horizontalAspectRatioChanged = false;
+ }
+
if (m_changeTracker.optimizationHintChanged) {
m_renderer->updateOptimizationHint(m_optimizationHints);
m_changeTracker.optimizationHintChanged = false;
}
+ if (m_changeTracker.reflectionChanged) {
+ m_renderer->m_reflectionEnabled = m_reflectionEnabled;
+ m_changeTracker.reflectionChanged = false;
+ }
+
+ if (m_changeTracker.reflectivityChanged) {
+ // Invert value to match functionality to the property description
+ m_renderer->m_reflectivity = -(m_reflectivity - 1.0);
+ m_changeTracker.reflectivityChanged = false;
+ }
+
if (m_changeTracker.axisXFormatterChanged) {
m_changeTracker.axisXFormatterChanged = false;
if (m_axisX->type() & QAbstract3DAxis::AxisTypeValue) {
@@ -445,6 +489,11 @@ void Abstract3DController::synchDataToRenderer()
m_changeTracker.axisZTitleFixedChanged = false;
}
+ if (m_changeTracker.marginChanged) {
+ m_renderer->updateMargin(float(m_margin));
+ m_changeTracker.marginChanged = false;
+ }
+
if (m_changedSeriesList.size()) {
m_renderer->modifiedSeriesList(m_changedSeriesList);
m_changedSeriesList.clear();
@@ -475,8 +524,6 @@ void Abstract3DController::synchDataToRenderer()
void Abstract3DController::render(const GLuint defaultFboHandle)
{
- m_renderPending = false;
-
// If not initialized, do nothing.
if (!m_renderer)
return;
@@ -765,8 +812,9 @@ void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputH
m_inputHandlers.removeAll(m_activeInputHandler);
delete m_activeInputHandler;
} else {
- // Disconnect the old input handler from the scene
+ // Disconnect the old input handler
m_activeInputHandler->setScene(0);
+ QObject::disconnect(m_activeInputHandler, 0, this, 0);
}
}
@@ -775,9 +823,16 @@ void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputH
addInputHandler(inputHandler);
m_activeInputHandler = inputHandler;
- if (m_activeInputHandler)
+ if (m_activeInputHandler) {
m_activeInputHandler->setScene(m_scene);
+ // Connect the input handler
+ QObject::connect(m_activeInputHandler, &QAbstract3DInputHandler::inputViewChanged, this,
+ &Abstract3DController::handleInputViewChanged);
+ QObject::connect(m_activeInputHandler, &QAbstract3DInputHandler::positionChanged, this,
+ &Abstract3DController::handleInputPositionChanged);
+ }
+
// Notify change of input handler
emit activeInputHandlerChanged(m_activeInputHandler);
}
@@ -886,11 +941,7 @@ QAbstract3DGraph::OptimizationHints Abstract3DController::optimizationHints() co
bool Abstract3DController::shadowsSupported() const
{
-#if defined(QT_OPENGL_ES_2)
- return false;
-#else
- return true;
-#endif
+ return !isOpenGLES();
}
bool Abstract3DController::isSlicingActive() const
@@ -989,6 +1040,11 @@ void Abstract3DController::releaseCustomItem(QCustom3DItem *item)
}
}
+QList<QCustom3DItem *> Abstract3DController::customItems() const
+{
+ return m_customItems;
+}
+
void Abstract3DController::updateCustomItem()
{
m_isCustomItemDirty = true;
@@ -1303,6 +1359,11 @@ void Abstract3DController::markSeriesItemLabelsDirty()
m_seriesList.at(i)->d_ptr->markItemLabelDirty();
}
+bool Abstract3DController::isOpenGLES() const
+{
+ return Utils::isOpenGLES();
+}
+
void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orientation,
QAbstract3DAxis *axis, QAbstract3DAxis **axisPtr)
{
@@ -1381,6 +1442,8 @@ void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orient
handleAxisLabelFormatChangedBySender(valueAxis);
handleAxisReversedChangedBySender(valueAxis);
handleAxisFormatterDirtyBySender(valueAxis->dptr());
+
+ valueAxis->formatter()->setLocale(m_locale);
}
}
@@ -1427,13 +1490,37 @@ void Abstract3DController::emitNeedRender()
void Abstract3DController::handlePendingClick()
{
- QAbstract3DGraph::ElementType type = m_renderer->clickedType();
- emit elementSelected(type);
+ m_clickedType = m_renderer->clickedType();
+ m_selectedLabelIndex = m_renderer->m_selectedLabelIndex;
+ m_selectedCustomItemIndex = m_renderer->m_selectedCustomItemIndex;
+
+ // Invalidate query position to indicate the query has been handled, unless another
+ // point has been queried.
+ if (m_renderer->cachedClickQuery() == m_scene->selectionQueryPosition())
+ m_scene->setSelectionQueryPosition(Q3DScene::invalidSelectionPoint());
+
+ m_renderer->clearClickQueryResolved();
+
+ emit elementSelected(m_clickedType);
+}
+
+void Abstract3DController::handlePendingGraphPositionQuery()
+{
+ m_queriedGraphPosition = m_renderer->queriedGraphPosition();
+
+ // Invalidate query position to indicate the query has been handled, unless another
+ // point has been queried.
+ if (m_renderer->cachedGraphPositionQuery() == m_scene->graphPositionQuery())
+ m_scene->setGraphPositionQuery(Q3DScene::invalidSelectionPoint());
+
+ m_renderer->clearGraphPositionQueryResolved();
+
+ emit queriedGraphPositionChanged(m_queriedGraphPosition);
}
int Abstract3DController::selectedLabelIndex() const
{
- int index = m_renderer->m_selectedLabelIndex;
+ int index = m_selectedLabelIndex;
QAbstract3DAxis *axis = selectedAxis();
if (axis && axis->labels().count() <= index)
index = -1;
@@ -1443,7 +1530,7 @@ int Abstract3DController::selectedLabelIndex() const
QAbstract3DAxis *Abstract3DController::selectedAxis() const
{
QAbstract3DAxis *axis = 0;
- QAbstract3DGraph::ElementType type = m_renderer->clickedType();
+ QAbstract3DGraph::ElementType type = m_clickedType;
switch (type) {
case QAbstract3DGraph::ElementAxisXLabel:
axis = axisX();
@@ -1464,7 +1551,7 @@ QAbstract3DAxis *Abstract3DController::selectedAxis() const
int Abstract3DController::selectedCustomItemIndex() const
{
- int index = m_renderer->m_selectedCustomItemIndex;
+ int index = m_selectedCustomItemIndex;
if (m_customItems.count() <= index)
index = -1;
return index;
@@ -1481,10 +1568,7 @@ QCustom3DItem *Abstract3DController::selectedCustomItem() const
QAbstract3DGraph::ElementType Abstract3DController::selectedElement() const
{
- if (m_renderer)
- return m_renderer->clickedType();
- else
- return QAbstract3DGraph::ElementNone;
+ return m_clickedType;
}
void Abstract3DController::setOrthoProjection(bool enable)
@@ -1505,7 +1589,7 @@ bool Abstract3DController::isOrthoProjection() const
return m_useOrthoProjection;
}
-void Abstract3DController::setAspectRatio(float ratio)
+void Abstract3DController::setAspectRatio(qreal ratio)
{
if (m_aspectRatio != ratio) {
m_aspectRatio = ratio;
@@ -1516,9 +1600,131 @@ void Abstract3DController::setAspectRatio(float ratio)
}
}
-float Abstract3DController::aspectRatio()
+qreal Abstract3DController::aspectRatio()
{
return m_aspectRatio;
}
+void Abstract3DController::setHorizontalAspectRatio(qreal ratio)
+{
+ if (m_horizontalAspectRatio != ratio) {
+ m_horizontalAspectRatio = ratio;
+ m_changeTracker.horizontalAspectRatioChanged = true;
+ emit horizontalAspectRatioChanged(m_horizontalAspectRatio);
+ m_isDataDirty = true;
+ emitNeedRender();
+ }
+}
+
+qreal Abstract3DController::horizontalAspectRatio() const
+{
+ return m_horizontalAspectRatio;
+}
+
+void Abstract3DController::setReflection(bool enable)
+{
+ if (m_reflectionEnabled != enable) {
+ m_reflectionEnabled = enable;
+ m_changeTracker.reflectionChanged = true;
+ emit reflectionChanged(m_reflectionEnabled);
+ emitNeedRender();
+ }
+}
+
+bool Abstract3DController::reflection() const
+{
+ return m_reflectionEnabled;
+}
+
+void Abstract3DController::setReflectivity(qreal reflectivity)
+{
+ if (m_reflectivity != reflectivity) {
+ m_reflectivity = reflectivity;
+ m_changeTracker.reflectivityChanged = true;
+ emit reflectivityChanged(m_reflectivity);
+ emitNeedRender();
+ }
+}
+
+qreal Abstract3DController::reflectivity() const
+{
+ return m_reflectivity;
+}
+
+void Abstract3DController::setPolar(bool enable)
+{
+ if (enable != m_isPolar) {
+ m_isPolar = enable;
+ m_changeTracker.polarChanged = true;
+ m_isDataDirty = true;
+ emit polarChanged(m_isPolar);
+ emitNeedRender();
+ }
+}
+
+bool Abstract3DController::isPolar() const
+{
+ return m_isPolar;
+}
+
+void Abstract3DController::setRadialLabelOffset(float offset)
+{
+ if (m_radialLabelOffset != offset) {
+ m_radialLabelOffset = offset;
+ m_changeTracker.radialLabelOffsetChanged = true;
+ emit radialLabelOffsetChanged(m_radialLabelOffset);
+ emitNeedRender();
+ }
+}
+
+float Abstract3DController::radialLabelOffset() const
+{
+ return m_radialLabelOffset;
+}
+
+void Abstract3DController::setLocale(const QLocale &locale)
+{
+ if (m_locale != locale) {
+ m_locale = locale;
+
+ // Value axis formatters need to be updated
+ QValue3DAxis *axis = qobject_cast<QValue3DAxis *>(m_axisX);
+ if (axis)
+ axis->formatter()->setLocale(m_locale);
+ axis = qobject_cast<QValue3DAxis *>(m_axisY);
+ if (axis)
+ axis->formatter()->setLocale(m_locale);
+ axis = qobject_cast<QValue3DAxis *>(m_axisZ);
+ if (axis)
+ axis->formatter()->setLocale(m_locale);
+ emit localeChanged(m_locale);
+ }
+}
+
+QLocale Abstract3DController::locale() const
+{
+ return m_locale;
+}
+
+QVector3D Abstract3DController::queriedGraphPosition() const
+{
+ return m_queriedGraphPosition;
+}
+
+void Abstract3DController::setMargin(qreal margin)
+{
+ if (m_margin != margin) {
+ m_margin = margin;
+ m_changeTracker.marginChanged = true;
+ emit marginChanged(margin);
+ emitNeedRender();
+ }
+}
+
+qreal Abstract3DController::margin() const
+{
+ return m_margin;
+}
+
+
QT_END_NAMESPACE_DATAVISUALIZATION