From d9cb05d0f46efc58e508c233a3c67542a4c177fa Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 23 May 2014 16:06:28 +0300 Subject: Optionally show axis titles on the graph MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-2961 Change-Id: I6a344156bd29fa8fb1ede0546af4d0e67e5e2db4 Reviewed-by: Tomi Korpipää --- examples/datavisualization/bars/graphmodifier.cpp | 30 ++- examples/datavisualization/bars/graphmodifier.h | 3 + examples/datavisualization/bars/main.cpp | 27 ++- examples/datavisualization/itemmodel/main.cpp | 3 + src/datavisualization/axis/qabstract3daxis.cpp | 74 +++++- src/datavisualization/axis/qabstract3daxis.h | 10 + src/datavisualization/axis/qabstract3daxis_p.h | 2 + .../engine/abstract3dcontroller.cpp | 77 +++++++ .../engine/abstract3dcontroller_p.h | 18 +- .../engine/abstract3drenderer.cpp | 252 ++++++++++++++++++++- .../engine/abstract3drenderer_p.h | 31 +++ src/datavisualization/engine/axisrendercache.cpp | 4 +- src/datavisualization/engine/axisrendercache_p.h | 6 + src/datavisualization/engine/bars3drenderer.cpp | 61 ++--- src/datavisualization/engine/bars3drenderer_p.h | 8 - src/datavisualization/engine/drawer.cpp | 9 +- src/datavisualization/engine/drawer_p.h | 2 + src/datavisualization/engine/scatter3drenderer.cpp | 60 +++-- src/datavisualization/engine/scatter3drenderer_p.h | 10 - src/datavisualization/engine/surface3drenderer.cpp | 61 +++-- src/datavisualization/engine/surface3drenderer_p.h | 10 - .../global/datavisualizationglobal_p.h | 1 + tests/scattertest/main.cpp | 28 ++- tests/scattertest/scatterchart.cpp | 27 ++- tests/scattertest/scatterchart.h | 4 +- tests/surfacetest/graphmodifier.cpp | 21 ++ tests/surfacetest/graphmodifier.h | 3 + tests/surfacetest/main.cpp | 25 ++ 28 files changed, 727 insertions(+), 140 deletions(-) diff --git a/examples/datavisualization/bars/graphmodifier.cpp b/examples/datavisualization/bars/graphmodifier.cpp index dc5d92c9..9c280bfb 100644 --- a/examples/datavisualization/bars/graphmodifier.cpp +++ b/examples/datavisualization/bars/graphmodifier.cpp @@ -68,12 +68,15 @@ GraphModifier::GraphModifier(Q3DBars *bargraph) m_temperatureAxis->setSubSegmentCount(m_subSegments); m_temperatureAxis->setRange(m_minval, m_maxval); m_temperatureAxis->setLabelFormat(QString(QStringLiteral("%.1f ") + celsiusString)); - m_temperatureAxis->setLabelAutoRotation(90.0f); + m_temperatureAxis->setLabelAutoRotation(30.0f); + m_temperatureAxis->setTitleVisible(true); m_yearAxis->setTitle("Year"); - m_yearAxis->setLabelAutoRotation(40.0f); + m_yearAxis->setLabelAutoRotation(30.0f); + m_yearAxis->setTitleVisible(true); m_monthAxis->setTitle("Month"); - m_monthAxis->setLabelAutoRotation(40.0f); + m_monthAxis->setLabelAutoRotation(30.0f); + m_monthAxis->setTitleVisible(true); m_graph->setValueAxis(m_temperatureAxis); m_graph->setRowAxis(m_yearAxis); @@ -239,6 +242,27 @@ void GraphModifier::shadowQualityUpdatedByVisual(QAbstract3DGraph::ShadowQuality emit shadowQualityChanged(quality); } +void GraphModifier::changeLabelRotation(int rotation) +{ + m_temperatureAxis->setLabelAutoRotation(float(rotation)); + m_monthAxis->setLabelAutoRotation(float(rotation)); + m_yearAxis->setLabelAutoRotation(float(rotation)); +} + +void GraphModifier::setAxisTitleVisibility(bool enabled) +{ + m_temperatureAxis->setTitleVisible(enabled); + m_monthAxis->setTitleVisible(enabled); + m_yearAxis->setTitleVisible(enabled); +} + +void GraphModifier::setAxisTitleFixed(bool enabled) +{ + m_temperatureAxis->setTitleFixed(enabled); + m_monthAxis->setTitleFixed(enabled); + m_yearAxis->setTitleFixed(enabled); +} + void GraphModifier::changeShadowQuality(int quality) { QAbstract3DGraph::ShadowQuality sq = QAbstract3DGraph::ShadowQuality(quality); diff --git a/examples/datavisualization/bars/graphmodifier.h b/examples/datavisualization/bars/graphmodifier.h index e1aacaf7..107ffbab 100644 --- a/examples/datavisualization/bars/graphmodifier.h +++ b/examples/datavisualization/bars/graphmodifier.h @@ -57,6 +57,9 @@ public slots: void changeTheme(int theme); void changeShadowQuality(int quality); void shadowQualityUpdatedByVisual(QAbstract3DGraph::ShadowQuality shadowQuality); + void changeLabelRotation(int rotation); + void setAxisTitleVisibility(bool enabled); + void setAxisTitleFixed(bool enabled); signals: void shadowQualityChanged(int quality); diff --git a/examples/datavisualization/bars/main.cpp b/examples/datavisualization/bars/main.cpp index 79b2967a..96abdc51 100644 --- a/examples/datavisualization/bars/main.cpp +++ b/examples/datavisualization/bars/main.cpp @@ -183,6 +183,21 @@ int main(int argc, char **argv) rangeList->addItem(QStringLiteral("All")); rangeList->setCurrentIndex(8); + QCheckBox *axisTitlesVisibleCB = new QCheckBox(widget); + axisTitlesVisibleCB->setText(QStringLiteral("Axis titles visible")); + axisTitlesVisibleCB->setChecked(true); + + QCheckBox *axisTitlesFixedCB = new QCheckBox(widget); + axisTitlesFixedCB->setText(QStringLiteral("Axis titles fixed")); + axisTitlesFixedCB->setChecked(true); + + QSlider *axisLabelRotationSlider = new QSlider(Qt::Horizontal, widget); + axisLabelRotationSlider->setTickInterval(10); + axisLabelRotationSlider->setTickPosition(QSlider::TicksBelow); + axisLabelRotationSlider->setMinimum(0); + axisLabelRotationSlider->setValue(30); + axisLabelRotationSlider->setMaximum(90); + //! [5] vLayout->addWidget(new QLabel(QStringLiteral("Rotate horizontally"))); vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop); @@ -196,6 +211,8 @@ int main(int argc, char **argv) vLayout->addWidget(smoothCheckBox); vLayout->addWidget(seriesCheckBox); vLayout->addWidget(reverseValueAxisCheckBox); + vLayout->addWidget(axisTitlesVisibleCB); + vLayout->addWidget(axisTitlesFixedCB); vLayout->addWidget(new QLabel(QStringLiteral("Show year"))); vLayout->addWidget(rangeList); vLayout->addWidget(new QLabel(QStringLiteral("Change bar style"))); @@ -209,7 +226,9 @@ int main(int argc, char **argv) vLayout->addWidget(new QLabel(QStringLiteral("Change font"))); vLayout->addWidget(fontList); vLayout->addWidget(new QLabel(QStringLiteral("Adjust font size"))); - vLayout->addWidget(fontSizeSlider, 1, Qt::AlignTop); + vLayout->addWidget(fontSizeSlider); + vLayout->addWidget(new QLabel(QStringLiteral("Axis label rotation"))); + vLayout->addWidget(axisLabelRotationSlider, 1, Qt::AlignTop); //! [2] GraphModifier *modifier = new GraphModifier(widgetgraph); @@ -271,6 +290,12 @@ int main(int argc, char **argv) QObject::connect(modifier, &GraphModifier::fontChanged, fontList, &QFontComboBox::setCurrentFont); + QObject::connect(axisTitlesVisibleCB, &QCheckBox::stateChanged, modifier, + &GraphModifier::setAxisTitleVisibility); + QObject::connect(axisTitlesFixedCB, &QCheckBox::stateChanged, modifier, + &GraphModifier::setAxisTitleFixed); + QObject::connect(axisLabelRotationSlider, &QSlider::valueChanged, modifier, + &GraphModifier::changeLabelRotation); //! [3] widget->show(); return app.exec(); diff --git a/examples/datavisualization/itemmodel/main.cpp b/examples/datavisualization/itemmodel/main.cpp index ad9f0112..f00702eb 100644 --- a/examples/datavisualization/itemmodel/main.cpp +++ b/examples/datavisualization/itemmodel/main.cpp @@ -167,8 +167,11 @@ void GraphDataGenerator::setupModel() // Add labels //! [10] m_graph->rowAxis()->setTitle("Week of year"); + m_graph->rowAxis()->setTitleVisible(true); m_graph->columnAxis()->setTitle("Day of week"); + m_graph->columnAxis()->setTitleVisible(true); m_graph->valueAxis()->setTitle("Hours spent on the Internet"); + m_graph->valueAxis()->setTitleVisible(true); m_graph->valueAxis()->setLabelFormat("%.1f h"); //! [10] diff --git a/src/datavisualization/axis/qabstract3daxis.cpp b/src/datavisualization/axis/qabstract3daxis.cpp index 27951f4c..681c435f 100644 --- a/src/datavisualization/axis/qabstract3daxis.cpp +++ b/src/datavisualization/axis/qabstract3daxis.cpp @@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \qmlproperty string AbstractAxis3D::title * Defines the title for the axis. + * + * \sa titleVisible, titleFixed */ /*! @@ -99,6 +101,27 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * the specified angle. */ +/*! + * \qmlproperty bool AbstractAxis3D::titleVisible + * + * Defines if the axis title is visible in the primary graph view. The default value is \c{false}. + * + * \sa title, titleFixed + */ + +/*! + * \qmlproperty bool AbstractAxis3D::titleFixed + * + * If \c{true}, axis titles in the primary graph view will be rotated towards the camera similarly + * to the axis labels. + * If \c{false}, axis titles are only rotated around their axis but are not otherwise oriented + * towards the camera. + * This property doesn't have any effect if labelAutoRotation property value is zero. + * Default value is \c{true}. + * + * \sa labelAutoRotation, title, titleVisible + */ + /*! * \enum QAbstract3DAxis::AxisOrientation * @@ -160,6 +183,8 @@ QAbstract3DAxis::AxisType QAbstract3DAxis::type() const * \property QAbstract3DAxis::title * * Defines the title for the axis. + * + * \sa titleVisible, titleFixed */ void QAbstract3DAxis::setTitle(const QString &title) { @@ -228,6 +253,51 @@ float QAbstract3DAxis::labelAutoRotation() const return d_ptr->m_labelAutoRotation; } +/*! + * \property QAbstract3DAxis::titleVisible + * + * Defines if the axis title is visible in the primary graph view. The default value is \c{false}. + * + * \sa title, titleFixed + */ +void QAbstract3DAxis::setTitleVisible(bool visible) +{ + if (d_ptr->m_titleVisible != visible) { + d_ptr->m_titleVisible = visible; + emit titleVisibilityChanged(visible); + } +} + +bool QAbstract3DAxis::isTitleVisible() const +{ + return d_ptr->m_titleVisible; +} + +/*! + * \property QAbstract3DAxis::titleFixed + * + * If \c{true}, axis titles in the primary graph view will be rotated towards the camera similarly + * to the axis labels. + * If \c{false}, axis titles are only rotated around their axis but are not otherwise oriented + * towards the camera. + * This property doesn't have any effect if labelAutoRotation property value is zero. + * Default value is \c{true}. + * + * \sa labelAutoRotation, title, titleVisible + */ +void QAbstract3DAxis::setTitleFixed(bool fixed) +{ + if (d_ptr->m_titleFixed != fixed) { + d_ptr->m_titleFixed = fixed; + emit titleFixedChanged(fixed); + } +} + +bool QAbstract3DAxis::isTitleFixed() const +{ + return d_ptr->m_titleFixed; +} + /*! * \property QAbstract3DAxis::min * @@ -302,7 +372,9 @@ QAbstract3DAxisPrivate::QAbstract3DAxisPrivate(QAbstract3DAxis *q, QAbstract3DAx m_min(0.0f), m_max(10.0f), m_autoAdjust(true), - m_labelAutoRotation(0.0f) + m_labelAutoRotation(0.0f), + m_titleVisible(false), + m_titleFixed(true) { } diff --git a/src/datavisualization/axis/qabstract3daxis.h b/src/datavisualization/axis/qabstract3daxis.h index 286e87bd..a9f75550 100644 --- a/src/datavisualization/axis/qabstract3daxis.h +++ b/src/datavisualization/axis/qabstract3daxis.h @@ -41,6 +41,8 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DAxis : public QObject Q_PROPERTY(float max READ max WRITE setMax NOTIFY maxChanged) Q_PROPERTY(bool autoAdjustRange READ isAutoAdjustRange WRITE setAutoAdjustRange NOTIFY autoAdjustRangeChanged) Q_PROPERTY(float labelAutoRotation READ labelAutoRotation WRITE setLabelAutoRotation NOTIFY labelAutoRotationChanged REVISION 1) + Q_PROPERTY(bool titleVisible READ isTitleVisible WRITE setTitleVisible NOTIFY titleVisibilityChanged REVISION 1) + Q_PROPERTY(bool titleFixed READ isTitleFixed WRITE setTitleFixed NOTIFY titleFixedChanged REVISION 1) public: enum AxisOrientation { @@ -85,6 +87,12 @@ public: void setLabelAutoRotation(float angle); float labelAutoRotation() const; + void setTitleVisible(bool visible); + bool isTitleVisible() const; + + void setTitleFixed(bool fixed); + bool isTitleFixed() const; + signals: void titleChanged(const QString &newTitle); void labelsChanged(); @@ -94,6 +102,8 @@ signals: void rangeChanged(float min, float max); void autoAdjustRangeChanged(bool autoAdjust); Q_REVISION(1) void labelAutoRotationChanged(float angle); + Q_REVISION(1) void titleVisibilityChanged(bool visible); + Q_REVISION(1) void titleFixedChanged(bool fixed); protected: QScopedPointer d_ptr; diff --git a/src/datavisualization/axis/qabstract3daxis_p.h b/src/datavisualization/axis/qabstract3daxis_p.h index eea3593c..72e5b15d 100644 --- a/src/datavisualization/axis/qabstract3daxis_p.h +++ b/src/datavisualization/axis/qabstract3daxis_p.h @@ -68,6 +68,8 @@ protected: float m_max; bool m_autoAdjust; float m_labelAutoRotation; + bool m_titleVisible; + bool m_titleFixed; friend class QAbstract3DAxis; friend class QValue3DAxis; diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 7e310ab8..ea084f9f 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -416,6 +416,37 @@ void Abstract3DController::synchDataToRenderer() m_changeTracker.axisZLabelAutoRotationChanged = false; } + if (m_changeTracker.axisXTitleVisibilityChanged) { + m_renderer->updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientationX, + m_axisX->isTitleVisible()); + m_changeTracker.axisXTitleVisibilityChanged = false; + } + if (m_changeTracker.axisYTitleVisibilityChanged) { + m_renderer->updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientationY, + m_axisY->isTitleVisible()); + m_changeTracker.axisYTitleVisibilityChanged = false; + } + if (m_changeTracker.axisZTitleVisibilityChanged) { + m_renderer->updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientationZ, + m_axisZ->isTitleVisible()); + m_changeTracker.axisZTitleVisibilityChanged = false; + } + if (m_changeTracker.axisXTitleFixedChanged) { + m_renderer->updateAxisTitleFixed(QAbstract3DAxis::AxisOrientationX, + m_axisX->isTitleFixed()); + m_changeTracker.axisXTitleFixedChanged = false; + } + if (m_changeTracker.axisYTitleFixedChanged) { + m_renderer->updateAxisTitleFixed(QAbstract3DAxis::AxisOrientationY, + m_axisY->isTitleFixed()); + m_changeTracker.axisYTitleFixedChanged = false; + } + if (m_changeTracker.axisZTitleFixedChanged) { + m_renderer->updateAxisTitleFixed(QAbstract3DAxis::AxisOrientationZ, + m_axisZ->isTitleFixed()); + m_changeTracker.axisZTitleFixedChanged = false; + } + if (m_changedSeriesList.size()) { m_renderer->modifiedSeriesList(m_changedSeriesList); m_changedSeriesList.clear(); @@ -1085,6 +1116,18 @@ void Abstract3DController::handleAxisLabelAutoRotationChanged(float angle) handleAxisLabelAutoRotationChangedBySender(sender()); } +void Abstract3DController::handleAxisTitleVisibilityChanged(bool visible) +{ + Q_UNUSED(visible) + handleAxisTitleVisibilityChangedBySender(sender()); +} + +void Abstract3DController::handleAxisTitleFixedChanged(bool fixed) +{ + Q_UNUSED(fixed) + handleAxisTitleFixedChangedBySender(sender()); +} + void Abstract3DController::handleInputViewChanged(QAbstract3DInputHandler::InputView view) { // When in automatic slicing mode, input view change to primary disables slice mode @@ -1198,6 +1241,34 @@ void Abstract3DController::handleAxisLabelAutoRotationChangedBySender(QObject *s emitNeedRender(); } +void Abstract3DController::handleAxisTitleVisibilityChangedBySender(QObject *sender) +{ + if (sender == m_axisX) + m_changeTracker.axisXTitleVisibilityChanged = true; + else if (sender == m_axisY) + m_changeTracker.axisYTitleVisibilityChanged = true; + else if (sender == m_axisZ) + m_changeTracker.axisZTitleVisibilityChanged = true; + else + qWarning() << __FUNCTION__ << "invoked for invalid axis"; + + emitNeedRender(); +} + +void Abstract3DController::handleAxisTitleFixedChangedBySender(QObject *sender) +{ + if (sender == m_axisX) + m_changeTracker.axisXTitleFixedChanged = true; + else if (sender == m_axisY) + m_changeTracker.axisYTitleFixedChanged = true; + else if (sender == m_axisZ) + m_changeTracker.axisZTitleFixedChanged = true; + else + qWarning() << __FUNCTION__ << "invoked for invalid axis"; + + emitNeedRender(); +} + void Abstract3DController::handleSeriesVisibilityChangedBySender(QObject *sender) { QAbstract3DSeries *series = static_cast(sender); @@ -1256,6 +1327,10 @@ void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orient this, &Abstract3DController::handleAxisAutoAdjustRangeChanged); QObject::connect(axis, &QAbstract3DAxis::labelAutoRotationChanged, this, &Abstract3DController::handleAxisLabelAutoRotationChanged); + QObject::connect(axis, &QAbstract3DAxis::titleVisibilityChanged, + this, &Abstract3DController::handleAxisTitleVisibilityChanged); + QObject::connect(axis, &QAbstract3DAxis::titleFixedChanged, + this, &Abstract3DController::handleAxisTitleFixedChanged); if (orientation == QAbstract3DAxis::AxisOrientationX) m_changeTracker.axisXTypeChanged = true; @@ -1270,6 +1345,8 @@ void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orient handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), axis->isAutoAdjustRange()); handleAxisLabelAutoRotationChangedBySender(axis); + handleAxisTitleVisibilityChangedBySender(axis); + handleAxisTitleFixedChangedBySender(axis); if (axis->type() & QAbstract3DAxis::AxisTypeValue) { QValue3DAxis *valueAxis = static_cast(axis); diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index 5869d388..e5d1154c 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -84,6 +84,12 @@ struct Abstract3DChangeBitField { bool axisYLabelAutoRotationChanged : 1; bool axisZLabelAutoRotationChanged : 1; bool aspectRatioChanged : 1; + bool axisXTitleVisibilityChanged : 1; + bool axisYTitleVisibilityChanged : 1; + bool axisZTitleVisibilityChanged : 1; + bool axisXTitleFixedChanged : 1; + bool axisYTitleFixedChanged : 1; + bool axisZTitleFixedChanged : 1; Abstract3DChangeBitField() : themeChanged(true), @@ -120,7 +126,13 @@ struct Abstract3DChangeBitField { axisXLabelAutoRotationChanged(true), axisYLabelAutoRotationChanged(true), axisZLabelAutoRotationChanged(true), - aspectRatioChanged(true) + aspectRatioChanged(true), + axisXTitleVisibilityChanged(true), + axisYTitleVisibilityChanged(true), + axisZTitleVisibilityChanged(true), + axisXTitleFixedChanged(true), + axisYTitleFixedChanged(true), + axisZTitleFixedChanged(true) { } }; @@ -278,6 +290,8 @@ public: virtual void handleAxisReversedChangedBySender(QObject *sender); virtual void handleAxisFormatterDirtyBySender(QObject *sender); virtual void handleAxisLabelAutoRotationChangedBySender(QObject *sender); + virtual void handleAxisTitleVisibilityChangedBySender(QObject *sender); + virtual void handleAxisTitleFixedChangedBySender(QObject *sender); virtual void handleSeriesVisibilityChangedBySender(QObject *sender); virtual void handlePendingClick() = 0; virtual void adjustAxisRanges() = 0; @@ -295,6 +309,8 @@ public slots: void handleAxisReversedChanged(bool enable); void handleAxisFormatterDirty(); void handleAxisLabelAutoRotationChanged(float angle); + void handleAxisTitleVisibilityChanged(bool visible); + void handleAxisTitleFixedChanged(bool fixed); void handleInputViewChanged(QAbstract3DInputHandler::InputView view); void handleInputPositionChanged(const QPoint &position); void handleSeriesVisibilityChanged(bool visible); diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index adba857b..cd03073d 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -53,8 +53,13 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_visibleSeriesCount(0), m_customItemShader(0), m_useOrthoProjection(false), - m_graphAspectRatio(2.0f) - + m_graphAspectRatio(2.0f), + m_xFlipped(false), + m_yFlipped(false), + m_zFlipped(false), + m_backgroundObj(0), + m_gridLineObj(0), + m_labelObj(0) { QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures); QObject::connect(this, &Abstract3DRenderer::needRender, controller, @@ -84,6 +89,10 @@ Abstract3DRenderer::~Abstract3DRenderer() } m_customRenderCache.clear(); + ObjectHelper::releaseObjectHelper(this, m_backgroundObj); + ObjectHelper::releaseObjectHelper(this, m_gridLineObj); + ObjectHelper::releaseObjectHelper(this, m_labelObj); + delete m_textureHelper; } @@ -397,6 +406,22 @@ void Abstract3DRenderer::updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrient cache.setLabelAutoRotation(angle); } +void Abstract3DRenderer::updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientation orientation, + bool visible) +{ + AxisRenderCache &cache = axisCacheForOrientation(orientation); + if (cache.isTitleVisible() != visible) + cache.setTitleVisible(visible); +} + +void Abstract3DRenderer::updateAxisTitleFixed(QAbstract3DAxis::AxisOrientation orientation, + bool fixed) +{ + AxisRenderCache &cache = axisCacheForOrientation(orientation); + if (cache.isTitleFixed() != fixed) + cache.setTitleFixed(fixed); +} + void Abstract3DRenderer::modifiedSeriesList(const QVector &seriesList) { foreach (QAbstract3DSeries *series, seriesList) { @@ -545,6 +570,229 @@ void Abstract3DRenderer::lowerShadowQuality() updateShadowQuality(newQuality); } +void Abstract3DRenderer::drawAxisTitleY(const QVector3D &sideLabelRotation, + const QVector3D &backLabelRotation, + const QVector3D &sideLabelTrans, + const QVector3D &backLabelTrans, + const QQuaternion &totalSideRotation, + const QQuaternion &totalBackRotation, + AbstractRenderItem &dummyItem, + const Q3DCamera *activeCamera, + float labelsMaxWidth, + const QMatrix4x4 &viewMatrix, + const QMatrix4x4 &projectionMatrix, + ShaderHelper *shader) +{ + float scaleFactor = m_drawer->scaledFontSize() / m_axisCacheY.titleItem().size().height(); + float titleOffset = 2.0f * (labelMargin + (labelsMaxWidth * scaleFactor)); + float yRotation; + QVector3D titleTrans; + QQuaternion totalRotation; + if (m_xFlipped == m_zFlipped) { + yRotation = backLabelRotation.y(); + titleTrans = backLabelTrans; + totalRotation = totalBackRotation; + } else { + yRotation = sideLabelRotation.y(); + titleTrans = sideLabelTrans; + totalRotation = totalSideRotation; + } + + QQuaternion offsetRotator = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation); + QVector3D titleOffsetVector = + offsetRotator.rotatedVector(QVector3D(-titleOffset, 0.0f, 0.0f)); + + QQuaternion titleRotation; + if (m_axisCacheY.isTitleFixed()) { + titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation) + * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f); + } else { + titleRotation = totalRotation + * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f); + } + dummyItem.setTranslation(titleTrans + titleOffsetVector); + + m_drawer->drawLabel(dummyItem, m_axisCacheY.titleItem(), viewMatrix, + projectionMatrix, zeroVector, titleRotation, 0, + m_cachedSelectionMode, shader, m_labelObj, activeCamera, + true, true, Drawer::LabelMid, Qt::AlignBottom); +} + +void Abstract3DRenderer::drawAxisTitleX(const QVector3D &labelRotation, + const QVector3D &labelTrans, + const QQuaternion &totalRotation, + AbstractRenderItem &dummyItem, + const Q3DCamera *activeCamera, + float labelsMaxWidth, + const QMatrix4x4 &viewMatrix, + const QMatrix4x4 &projectionMatrix, + ShaderHelper *shader) +{ + float scaleFactor = m_drawer->scaledFontSize() / m_axisCacheX.titleItem().size().height(); + float titleOffset = 2.0f * (labelMargin + (labelsMaxWidth * scaleFactor)); + float zRotation = 0.0f; + float yRotation = 0.0f; + float xRotation = -90.0f + labelRotation.z(); + float offsetRotation = labelRotation.z(); + float extraRotation = -90.0f; + Qt::AlignmentFlag alignment = Qt::AlignTop; + if (m_yFlipped) { + alignment = Qt::AlignBottom; + if (m_zFlipped) { + zRotation = 180.0f; + titleOffset = -titleOffset; + if (m_xFlipped) { + offsetRotation = -offsetRotation; + extraRotation = -extraRotation; + } else { + xRotation = -90.0f - labelRotation.z(); + } + } else { + zRotation = 180.0f; + yRotation = 180.0f; + if (m_xFlipped) { + offsetRotation = -offsetRotation; + xRotation = -90.0f - labelRotation.z(); + } else { + extraRotation = -extraRotation; + } + } + } else { + if (m_zFlipped) { + titleOffset = -titleOffset; + if (m_xFlipped) { + yRotation = 180.0f; + offsetRotation = -offsetRotation; + } else { + yRotation = 180.0f; + xRotation = -90.0f - labelRotation.z(); + extraRotation = -extraRotation; + } + } else { + if (m_xFlipped) { + offsetRotation = -offsetRotation; + xRotation = -90.0f - labelRotation.z(); + extraRotation = -extraRotation; + } + } + } + + if (offsetRotation == 180.0f || offsetRotation == -180.0f) + offsetRotation = 0.0f; + QQuaternion offsetRotator = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, offsetRotation); + QVector3D titleOffsetVector = + offsetRotator.rotatedVector(QVector3D(0.0f, 0.0f, titleOffset)); + + QQuaternion titleRotation; + if (m_axisCacheX.isTitleFixed()) { + titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, zRotation) + * QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation) + * QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, xRotation); + } else { + titleRotation = totalRotation + * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, extraRotation); + } + dummyItem.setTranslation(labelTrans + titleOffsetVector); + + m_drawer->drawLabel(dummyItem, m_axisCacheX.titleItem(), viewMatrix, + projectionMatrix, zeroVector, titleRotation, 0, + m_cachedSelectionMode, shader, m_labelObj, activeCamera, + true, true, Drawer::LabelMid, alignment); +} + +void Abstract3DRenderer::drawAxisTitleZ(const QVector3D &labelRotation, + const QVector3D &labelTrans, + const QQuaternion &totalRotation, + AbstractRenderItem &dummyItem, + const Q3DCamera *activeCamera, + float labelsMaxWidth, + const QMatrix4x4 &viewMatrix, + const QMatrix4x4 &projectionMatrix, + ShaderHelper *shader) +{ + float scaleFactor = m_drawer->scaledFontSize() / m_axisCacheZ.titleItem().size().height(); + float titleOffset = 2.0f * (labelMargin + (labelsMaxWidth * scaleFactor)); + float zRotation = labelRotation.z(); + float yRotation = -90.0f; + float xRotation = -90.0f; + float extraRotation = 90.0f; + Qt::AlignmentFlag alignment = Qt::AlignTop; + if (m_yFlipped) { + alignment = Qt::AlignBottom; + xRotation = -xRotation; + if (m_zFlipped) { + if (m_xFlipped) { + titleOffset = -titleOffset; + zRotation = -zRotation; + extraRotation = -extraRotation; + } else { + zRotation = -zRotation; + yRotation = -yRotation; + } + } else { + if (m_xFlipped) { + titleOffset = -titleOffset; + } else { + extraRotation = -extraRotation; + yRotation = -yRotation; + } + } + } else { + if (m_zFlipped) { + zRotation = -zRotation; + if (m_xFlipped) { + titleOffset = -titleOffset; + } else { + extraRotation = -extraRotation; + yRotation = -yRotation; + } + } else { + if (m_xFlipped) { + titleOffset = -titleOffset; + extraRotation = -extraRotation; + } else { + yRotation = -yRotation; + } + } + } + + float offsetRotation = zRotation; + if (offsetRotation == 180.0f || offsetRotation == -180.0f) + offsetRotation = 0.0f; + QQuaternion offsetRotator = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, offsetRotation); + QVector3D titleOffsetVector = + offsetRotator.rotatedVector(QVector3D(titleOffset, 0.0f, 0.0f)); + + QQuaternion titleRotation; + if (m_axisCacheZ.isTitleFixed()) { + titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, zRotation) + * QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation) + * QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, xRotation); + } else { + titleRotation = totalRotation + * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, extraRotation); + } + dummyItem.setTranslation(labelTrans + titleOffsetVector); + + m_drawer->drawLabel(dummyItem, m_axisCacheZ.titleItem(), viewMatrix, + projectionMatrix, zeroVector, titleRotation, 0, + m_cachedSelectionMode, shader, m_labelObj, activeCamera, + true, true, Drawer::LabelMid, alignment); +} + +void Abstract3DRenderer::loadGridLineMesh() +{ + ObjectHelper::resetObjectHelper(this, m_gridLineObj, + QStringLiteral(":/defaultMeshes/plane")); +} + +void Abstract3DRenderer::loadLabelMesh() +{ + ObjectHelper::resetObjectHelper(this, m_labelObj, + QStringLiteral(":/defaultMeshes/plane")); +} + + void Abstract3DRenderer::generateBaseColorTexture(const QColor &color, GLuint *texture) { m_textureHelper->deleteTexture(texture); diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index cd3608a8..35b6ff27 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -111,6 +111,10 @@ public: QValue3DAxisFormatter *formatter); virtual void updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientation orientation, float angle); + virtual void updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientation orientation, + bool visible); + virtual void updateAxisTitleFixed(QAbstract3DAxis::AxisOrientation orientation, + bool fixed); virtual void modifiedSeriesList(const QVector &seriesList); virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); @@ -162,6 +166,26 @@ protected: void fixGradient(QLinearGradient *gradient, GLuint *gradientTexture); void calculateZoomLevel(); + void drawAxisTitleY(const QVector3D &sideLabelRotation, const QVector3D &backLabelRotation, + const QVector3D &sideLabelTrans, const QVector3D &backLabelTrans, + const QQuaternion &totalSideRotation, const QQuaternion &totalBackRotation, + AbstractRenderItem &dummyItem, const Q3DCamera *activeCamera, + float labelsMaxWidth, + const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, + ShaderHelper *shader); + void drawAxisTitleX(const QVector3D &labelRotation, const QVector3D &labelTrans, + const QQuaternion &totalRotation, AbstractRenderItem &dummyItem, + const Q3DCamera *activeCamera, float labelsMaxWidth, + const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, + ShaderHelper *shader); + void drawAxisTitleZ(const QVector3D &labelRotation, const QVector3D &labelTrans, + const QQuaternion &totalRotation, AbstractRenderItem &dummyItem, + const Q3DCamera *activeCamera, float labelsMaxWidth, + const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, + ShaderHelper *shader); + + void loadGridLineMesh(); + void loadLabelMesh(); bool m_hasNegativeValues; Q3DTheme *m_cachedTheme; @@ -200,6 +224,13 @@ protected: ShaderHelper *m_customItemShader; bool m_useOrthoProjection; + bool m_xFlipped; + bool m_zFlipped; + bool m_yFlipped; + + ObjectHelper *m_backgroundObj; // Shared reference + ObjectHelper *m_gridLineObj; // Shared reference + ObjectHelper *m_labelObj; // Shared reference float m_graphAspectRatio; diff --git a/src/datavisualization/engine/axisrendercache.cpp b/src/datavisualization/engine/axisrendercache.cpp index a90c9557..bf661fe4 100644 --- a/src/datavisualization/engine/axisrendercache.cpp +++ b/src/datavisualization/engine/axisrendercache.cpp @@ -37,7 +37,9 @@ AxisRenderCache::AxisRenderCache() m_positionsDirty(true), m_translate(0.0f), m_scale(1.0f), - m_labelAutoRotation(0.0f) + m_labelAutoRotation(0.0f), + m_titleVisible(false), + m_titleFixed(false) { } diff --git a/src/datavisualization/engine/axisrendercache_p.h b/src/datavisualization/engine/axisrendercache_p.h index c7f6574d..0f82fda0 100644 --- a/src/datavisualization/engine/axisrendercache_p.h +++ b/src/datavisualization/engine/axisrendercache_p.h @@ -97,6 +97,10 @@ public: } inline float labelAutoRotation() const { return m_labelAutoRotation; } inline void setLabelAutoRotation(float angle) { m_labelAutoRotation = angle; } + inline bool isTitleVisible() const { return m_titleVisible; } + inline void setTitleVisible(bool visible) { m_titleVisible = visible; } + inline bool isTitleFixed() const { return m_titleFixed; } + inline void setTitleFixed(bool fixed) { m_titleFixed = fixed; } public slots: void updateTextures(); @@ -128,6 +132,8 @@ private: float m_translate; float m_scale; float m_labelAutoRotation; + bool m_titleVisible; + bool m_titleFixed; Q_DISABLE_COPY(AxisRenderCache) }; diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index db23460c..97589765 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -40,9 +40,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION -const GLfloat labelMargin = 0.05f; const GLfloat gridLineWidth = 0.005f; - const bool sliceGridLabels = true; Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) @@ -53,9 +51,6 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_selectedBar(0), m_sliceCache(0), m_sliceTitleItem(0), - m_xFlipped(false), - m_zFlipped(false), - m_yFlipped(false), m_updateLabels(false), m_barShader(0), m_barGradientShader(0), @@ -63,9 +58,6 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_selectionShader(0), m_backgroundShader(0), m_labelShader(0), - m_backgroundObj(0), - m_gridLineObj(0), - m_labelObj(0), m_bgrTexture(0), m_depthTexture(0), m_selectionTexture(0), @@ -120,9 +112,6 @@ Bars3DRenderer::~Bars3DRenderer() delete m_depthShader; delete m_selectionShader; delete m_backgroundShader; - ObjectHelper::releaseObjectHelper(this, m_backgroundObj); - ObjectHelper::releaseObjectHelper(this, m_gridLineObj); - ObjectHelper::releaseObjectHelper(this, m_labelObj); delete m_labelShader; } @@ -1884,6 +1873,7 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer float labelAngleFraction = labelAutoAngle / 90.0f; float fractionCamY = activeCamera->yRotation() * labelAngleFraction; float fractionCamX = activeCamera->xRotation() * labelAngleFraction; + float labelsMaxWidth = 0.0f; // Y Labels int labelNbr = 0; @@ -1958,20 +1948,31 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, totalBackRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, backAlignment); + true, true, Drawer::LabelMid, backAlignment, false, drawSelection); // Side wall m_dummyBarRenderItem.setTranslation(sideLabelTrans); m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, totalSideRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, sideAlignment); + true, true, Drawer::LabelMid, sideAlignment, false, drawSelection); + + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } labelNbr++; } + if (!drawSelection && m_axisCacheY.isTitleVisible()) { + sideLabelTrans.setY(m_backgroundAdjustment); + backLabelTrans.setY(m_backgroundAdjustment); + drawAxisTitleY(sideLabelRotation, backLabelRotation, sideLabelTrans, backLabelTrans, + totalSideRotation, totalBackRotation, m_dummyBarRenderItem, activeCamera, + labelsMaxWidth, viewMatrix, projectionMatrix, shader); + } + // Z labels // Calculate the positions for row and column labels and store them + labelsMaxWidth = 0.0f; labelAutoAngle = m_axisCacheZ.labelAutoRotation(); labelAngleFraction = labelAutoAngle / 90.0f; fractionCamY = activeCamera->yRotation() * labelAngleFraction; @@ -2077,10 +2078,18 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer shader, m_labelObj, activeCamera, true, true, Drawer::LabelMid, alignment, false, drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } } + if (!drawSelection && m_axisCacheZ.isTitleVisible()) { + QVector3D titleTrans(colPos, 0.0f, 0.0f); + drawAxisTitleZ(labelRotation, titleTrans, totalRotation, m_dummyBarRenderItem, + activeCamera, labelsMaxWidth, viewMatrix, projectionMatrix, shader); + } + // X labels + labelsMaxWidth = 0.0f; labelAutoAngle = m_axisCacheX.labelAutoRotation(); labelAngleFraction = labelAutoAngle / 90.0f; fractionCamY = activeCamera->yRotation() * labelAngleFraction; @@ -2180,20 +2189,28 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer zeroVector, totalRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, Drawer::LabelMid, alignment, false, drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } } + if (!drawSelection && m_axisCacheX.isTitleVisible()) { + QVector3D titleTrans(0.0f, 0.0f, rowPos); + drawAxisTitleX(labelRotation, titleTrans, totalRotation, m_dummyBarRenderItem, + activeCamera, labelsMaxWidth, viewMatrix, projectionMatrix, shader); + } + #if 0 // Debug label static LabelItem debugLabelItem; - QString debugLabelString(QStringLiteral("Flips: x:%1 y:%2 z:%3")); - QString finalDebugString = debugLabelString.arg(m_xFlipped).arg(m_yFlipped).arg(m_zFlipped); + QString debugLabelString(QStringLiteral("Flips: x:%1 y:%2 z:%3 xr:%4 yr:%5")); + QString finalDebugString = debugLabelString.arg(m_xFlipped).arg(m_yFlipped).arg(m_zFlipped) + .arg(activeCamera->xRotation()).arg(activeCamera->yRotation()); m_dummyBarRenderItem.setTranslation(QVector3D(m_xFlipped ? -1.5f : 1.5f, m_yFlipped ? 1.5f : -1.5f, m_zFlipped ? -1.5f : 1.5f)); m_drawer->generateLabelItem(debugLabelItem, finalDebugString); m_drawer->drawLabel(m_dummyBarRenderItem, debugLabelItem, viewMatrix, projectionMatrix, - zeroVector, labelRotation, 0, m_cachedSelectionMode, + zeroVector, identityQuaternion, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, false, Drawer::LabelMid, Qt::AlignHCenter, false, drawSelection); #endif @@ -2340,18 +2357,6 @@ void Bars3DRenderer::loadBackgroundMesh() QStringLiteral(":/defaultMeshes/backgroundNoFloor")); } -void Bars3DRenderer::loadGridLineMesh() -{ - ObjectHelper::resetObjectHelper(this, m_gridLineObj, - QStringLiteral(":/defaultMeshes/plane")); -} - -void Bars3DRenderer::loadLabelMesh() -{ - ObjectHelper::resetObjectHelper(this, m_labelObj, - QStringLiteral(":/defaultMeshes/plane")); -} - void Bars3DRenderer::updateTextures() { // Drawer has changed; this flag needs to be checked when checking if we need to update labels diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 4b544082..c4d25430 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -63,9 +63,6 @@ private: BarRenderItem *m_selectedBar; // points to renderitem array AxisRenderCache *m_sliceCache; // not owned const LabelItem *m_sliceTitleItem; // not owned - bool m_xFlipped; - bool m_zFlipped; - bool m_yFlipped; bool m_updateLabels; ShaderHelper *m_barShader; ShaderHelper *m_barGradientShader; @@ -73,9 +70,6 @@ private: ShaderHelper *m_selectionShader; ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; - ObjectHelper *m_backgroundObj; // Shared reference - ObjectHelper *m_gridLineObj; // Shared reference - ObjectHelper *m_labelObj; // Shared reference GLuint m_bgrTexture; GLuint m_depthTexture; GLuint m_selectionTexture; @@ -159,8 +153,6 @@ private: GLfloat rowScaleFactor, GLfloat columnScaleFactor); void loadBackgroundMesh(); - void loadGridLineMesh(); - void loadLabelMesh(); void initSelectionShader(); void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader); void initLabelShaders(const QString &vertexShader, const QString &fragmentShader); diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp index a14678ce..d6c9fdce 100644 --- a/src/datavisualization/engine/drawer.cpp +++ b/src/datavisualization/engine/drawer.cpp @@ -55,7 +55,8 @@ Drawer::Drawer(Q3DTheme *theme) : m_theme(theme), m_textureHelper(0), m_pointbuffer(0), - m_linebuffer(0) + m_linebuffer(0), + m_scaledFontSize(0.0f) { } @@ -79,6 +80,7 @@ void Drawer::initializeOpenGL() void Drawer::setTheme(Q3DTheme *theme) { m_theme = theme; + m_scaledFontSize = 0.05f + m_theme->font().pointSizeF() / 500.0f; emit drawerChanged(); } @@ -295,8 +297,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte } // Calculate scale factor to get uniform font size - GLfloat scaledFontSize = 0.05f + m_theme->font().pointSizeF() / 500.0f; - GLfloat scaleFactor = scaledFontSize / (GLfloat)textureSize.height(); + GLfloat scaleFactor = m_scaledFontSize / (GLfloat)textureSize.height(); // Apply alignment QVector3D anchorPoint; @@ -337,7 +338,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte // Scale label based on text size modelMatrix.scale(QVector3D((GLfloat)textureSize.width() * scaleFactor, - scaledFontSize, + m_scaledFontSize, 0.0f)); MVPMatrix = projectionmatrix * viewmatrix * modelMatrix; diff --git a/src/datavisualization/engine/drawer_p.h b/src/datavisualization/engine/drawer_p.h index cdda4f7d..966ccb85 100644 --- a/src/datavisualization/engine/drawer_p.h +++ b/src/datavisualization/engine/drawer_p.h @@ -71,6 +71,7 @@ public: void setTheme(Q3DTheme *theme); Q3DTheme *theme() const; QFont font() const; + inline GLfloat scaledFontSize() const { return m_scaledFontSize; } void drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId = 0, GLuint depthTextureId = 0); @@ -98,6 +99,7 @@ private: TextureHelper *m_textureHelper; GLuint m_pointbuffer; GLuint m_linebuffer; + GLfloat m_scaledFontSize; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index e37089a2..dd84139d 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -45,7 +45,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION //#define USE_UNIFORM_SCALING // Scale x and z uniformly, or based on autoscaled values -const GLfloat labelMargin = 0.05f; const GLfloat defaultMinSize = 0.01f; const GLfloat defaultMaxSize = 0.1f; const GLfloat itemScaler = 3.0f; @@ -54,9 +53,6 @@ const GLfloat gridLineWidth = 0.005f; Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) : Abstract3DRenderer(controller), m_selectedItem(0), - m_xFlipped(false), - m_zFlipped(false), - m_yFlipped(false), m_updateLabels(false), m_dotShader(0), m_dotGradientShader(0), @@ -67,11 +63,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_selectionShader(0), m_backgroundShader(0), m_labelShader(0), - m_backgroundObj(0), - #if !defined(QT_OPENGL_ES_2) - m_gridLineObj(0), - #endif - m_labelObj(0), m_bgrTexture(0), m_depthTexture(0), m_selectionTexture(0), @@ -117,11 +108,6 @@ Scatter3DRenderer::~Scatter3DRenderer() delete m_selectionShader; delete m_backgroundShader; delete m_labelShader; - ObjectHelper::releaseObjectHelper(this, m_backgroundObj); -#if !defined(QT_OPENGL_ES_2) - ObjectHelper::releaseObjectHelper(this, m_gridLineObj); -#endif - ObjectHelper::releaseObjectHelper(this, m_labelObj); } void Scatter3DRenderer::initializeOpenGL() @@ -1357,6 +1343,7 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa float labelAngleFraction = labelAutoAngle / 90.0f; float fractionCamY = activeCamera->yRotation() * labelAngleFraction; float fractionCamX = activeCamera->xRotation() * labelAngleFraction; + float labelsMaxWidth = 0.0f; // Z Labels if (m_axisCacheZ.segmentCount() > 0) { @@ -1458,13 +1445,21 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, totalRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, - Drawer::LabelMid, alignment); + Drawer::LabelMid, alignment, false, drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } labelNbr++; } + if (!drawSelection && m_axisCacheZ.isTitleVisible()) { + labelTrans.setZ(0.0f); + drawAxisTitleZ(labelRotation, labelTrans, totalRotation, m_dummyRenderItem, + activeCamera, labelsMaxWidth, viewMatrix, projectionMatrix, shader); + } } + // X Labels if (m_axisCacheX.segmentCount() > 0) { + labelsMaxWidth = 0.0f; labelAutoAngle = m_axisCacheX.labelAutoRotation(); labelAngleFraction = labelAutoAngle / 90.0f; fractionCamY = activeCamera->yRotation() * labelAngleFraction; @@ -1570,13 +1565,21 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, totalRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, - Drawer::LabelMid, alignment); + Drawer::LabelMid, alignment, false, drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } labelNbr++; } + if (!drawSelection && m_axisCacheX.isTitleVisible()) { + labelTrans.setX(0.0f); + drawAxisTitleX(labelRotation, labelTrans, totalRotation, m_dummyRenderItem, + activeCamera, labelsMaxWidth, viewMatrix, projectionMatrix, shader); + } } + // Y Labels if (m_axisCacheY.segmentCount() > 0) { + labelsMaxWidth = 0.0f; labelAutoAngle = m_axisCacheY.labelAutoRotation(); labelAngleFraction = labelAutoAngle / 90.0f; fractionCamY = activeCamera->yRotation() * labelAngleFraction; @@ -1660,7 +1663,7 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, totalBackRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, - Drawer::LabelMid, backAlignment); + Drawer::LabelMid, backAlignment, false, drawSelection); // Side wall labelTransSide.setY(labelYTrans); @@ -1668,10 +1671,17 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, zeroVector, totalSideRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, - Drawer::LabelMid, sideAlignment); + Drawer::LabelMid, sideAlignment, false, drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } labelNbr++; } + if (!drawSelection && m_axisCacheY.isTitleVisible()) { + drawAxisTitleY(sideLabelRotation, backLabelRotation, labelTransSide, labelTransBack, + totalSideRotation, totalBackRotation, m_dummyRenderItem, activeCamera, + labelsMaxWidth, viewMatrix, projectionMatrix, + shader); + } } glDisable(GL_POLYGON_OFFSET_FILL); } @@ -1739,20 +1749,6 @@ void Scatter3DRenderer::loadBackgroundMesh() QStringLiteral(":/defaultMeshes/background")); } -#if !(defined QT_OPENGL_ES_2) -void Scatter3DRenderer::loadGridLineMesh() -{ - ObjectHelper::resetObjectHelper(this, m_gridLineObj, - QStringLiteral(":/defaultMeshes/plane")); -} -#endif - -void Scatter3DRenderer::loadLabelMesh() -{ - ObjectHelper::resetObjectHelper(this, m_labelObj, - QStringLiteral(":/defaultMeshes/plane")); -} - void Scatter3DRenderer::updateTextures() { // Drawer has changed; this flag needs to be checked when checking if we need to update labels diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index b6a110ff..373e0f38 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -55,9 +55,6 @@ class QT_DATAVISUALIZATION_EXPORT Scatter3DRenderer : public Abstract3DRenderer private: // Internal state ScatterRenderItem *m_selectedItem; // points to renderitem array - bool m_xFlipped; - bool m_zFlipped; - bool m_yFlipped; bool m_updateLabels; ShaderHelper *m_dotShader; ShaderHelper *m_dotGradientShader; @@ -68,11 +65,6 @@ private: ShaderHelper *m_selectionShader; ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; - ObjectHelper *m_backgroundObj; // Shared reference -#if !(defined QT_OPENGL_ES_2) - ObjectHelper *m_gridLineObj; // Shared reference -#endif - ObjectHelper *m_labelObj; // Shared reference GLuint m_bgrTexture; GLuint m_depthTexture; GLuint m_selectionTexture; @@ -130,13 +122,11 @@ private: const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix); void loadBackgroundMesh(); - void loadLabelMesh(); void initSelectionShader(); void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader); void initLabelShaders(const QString &vertexShader, const QString &fragmentShader); void initSelectionBuffer(); #if !defined(QT_OPENGL_ES_2) - void loadGridLineMesh(); void initDepthShader(); void updateDepthBuffer(); #else diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 54544396..83bf738c 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION // Margin for background (1.10 make it 10% larger to avoid // selection ball being drawn inside background) const GLfloat backgroundMargin = 1.1f; -const GLfloat labelMargin = 0.05f; const GLfloat gridLineWidth = 0.005f; const GLfloat sliceZScale = 0.1f; const GLfloat sliceUnits = 2.5f; @@ -75,11 +74,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_maxVisibleRowValue(0.0f), m_visibleColumnRange(0.0f), m_visibleRowRange(0.0f), - m_backgroundObj(0), - #if !defined(QT_OPENGL_ES_2) - m_gridLineObj(0), - #endif - m_labelObj(0), m_depthTexture(0), m_depthModelTexture(0), m_depthFrameBuffer(0), @@ -89,9 +83,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_shadowQualityToShader(33.3f), m_flatSupported(true), m_selectionActive(false), - m_xFlipped(false), - m_zFlipped(false), - m_yFlipped(false), m_shadowQualityMultiplier(3), m_hasHeightAdjustmentChanged(true), m_selectedPoint(Surface3DController::invalidSelectionPosition()), @@ -140,12 +131,6 @@ Surface3DRenderer::~Surface3DRenderer() delete m_surfaceSliceFlatShader; delete m_surfaceSliceSmoothShader; delete m_labelShader; - - ObjectHelper::releaseObjectHelper(this, m_backgroundObj); -#if !defined(QT_OPENGL_ES_2) - ObjectHelper::releaseObjectHelper(this, m_gridLineObj); -#endif - ObjectHelper::releaseObjectHelper(this, m_labelObj); } void Surface3DRenderer::initializeOpenGL() @@ -1843,6 +1828,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa float labelAngleFraction = labelAutoAngle / 90.0f; float fractionCamY = activeCamera->yRotation() * labelAngleFraction; float fractionCamX = activeCamera->xRotation() * labelAngleFraction; + float labelsMaxWidth = 0.0f; // Z Labels QVector3D positionZComp(0.0f, 0.0f, 0.0f); @@ -1941,13 +1927,20 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, positionZComp, totalRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, alignment); + true, true, Drawer::LabelMid, alignment, false, drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } labelNbr++; } + if (!drawSelection && m_axisCacheZ.isTitleVisible()) { + labelTrans.setZ(0.0f); + drawAxisTitleZ(labelRotation, labelTrans, totalRotation, m_dummyRenderItem, + activeCamera, labelsMaxWidth, viewMatrix, projectionMatrix, shader); + } } // X Labels if (m_axisCacheX.segmentCount() > 0) { + labelsMaxWidth = 0.0f; labelAutoAngle = m_axisCacheX.labelAutoRotation(); labelAngleFraction = labelAutoAngle / 90.0f; fractionCamY = activeCamera->yRotation() * labelAngleFraction; @@ -2048,13 +2041,20 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, positionZComp, totalRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, alignment); + true, true, Drawer::LabelMid, alignment, false, drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } labelNbr++; } + if (!drawSelection && m_axisCacheX.isTitleVisible()) { + labelTrans.setX(0.0f); + drawAxisTitleX(labelRotation, labelTrans, totalRotation, m_dummyRenderItem, + activeCamera, labelsMaxWidth, viewMatrix, projectionMatrix, shader); + } } // Y Labels if (m_axisCacheY.segmentCount() > 0) { + labelsMaxWidth = 0.0f; labelAutoAngle = m_axisCacheY.labelAutoRotation(); labelAngleFraction = labelAutoAngle / 90.0f; fractionCamY = activeCamera->yRotation() * labelAngleFraction; @@ -2129,7 +2129,8 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, positionZComp, totalBackRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, backAlignment); + true, true, Drawer::LabelMid, backAlignment, false, + drawSelection); // Side wall labelTransSide.setY(labelYTrans); @@ -2137,10 +2138,18 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, positionZComp, totalSideRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, sideAlignment); + true, true, Drawer::LabelMid, sideAlignment, false, + drawSelection); + labelsMaxWidth = qMax(labelsMaxWidth, float(axisLabelItem.size().width())); } labelNbr++; } + if (!drawSelection && m_axisCacheY.isTitleVisible()) { + drawAxisTitleY(sideLabelRotation, backLabelRotation, labelTransSide, labelTransBack, + totalSideRotation, totalBackRotation, m_dummyRenderItem, activeCamera, + labelsMaxWidth, viewMatrix, projectionMatrix, + shader); + } } glDisable(GL_POLYGON_OFFSET_FILL); @@ -2314,14 +2323,6 @@ void Surface3DRenderer::loadBackgroundMesh() QStringLiteral(":/defaultMeshes/background")); } -#if !(defined QT_OPENGL_ES_2) -void Surface3DRenderer::loadGridLineMesh() -{ - ObjectHelper::resetObjectHelper(this, m_gridLineObj, - QStringLiteral(":/defaultMeshes/plane")); -} -#endif - void Surface3DRenderer::surfacePointSelected(const QPoint &point) { foreach (SeriesRenderCache *baseCache, m_renderCacheList) { @@ -2543,12 +2544,6 @@ void Surface3DRenderer::updateSlicingActive(bool isSlicing) } } -void Surface3DRenderer::loadLabelMesh() -{ - ObjectHelper::resetObjectHelper(this, m_labelObj, - QStringLiteral(":/defaultMeshes/plane")); -} - void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader) { Q_UNUSED(vertexShader); diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index e6c66a90..9af3f47d 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -73,11 +73,6 @@ private: GLfloat m_maxVisibleRowValue; GLfloat m_visibleColumnRange; GLfloat m_visibleRowRange; - ObjectHelper *m_backgroundObj; // Shared reference -#if !(defined QT_OPENGL_ES_2) - ObjectHelper *m_gridLineObj; // Shared reference -#endif - ObjectHelper *m_labelObj; // Shared reference GLuint m_depthTexture; GLuint m_depthModelTexture; GLuint m_depthFrameBuffer; @@ -87,9 +82,6 @@ private: GLfloat m_shadowQualityToShader; bool m_flatSupported; bool m_selectionActive; - bool m_xFlipped; - bool m_zFlipped; - bool m_yFlipped; AbstractRenderItem m_dummyRenderItem; GLint m_shadowQualityMultiplier; QSizeF m_areaSize; @@ -139,7 +131,6 @@ private: void initShaders(const QString &vertexShader, const QString &fragmentShader); QRect calculateSampleRect(const QSurfaceDataArray &array); void loadBackgroundMesh(); - void loadLabelMesh(); void drawSlicedScene(); void drawScene(GLuint defaultFboHandle); @@ -161,7 +152,6 @@ private: void updateSelectionPoint(SurfaceSeriesRenderCache *cache, const QPoint &point, bool label); QPoint selectionIdToSurfacePoint(uint id); #if !defined(QT_OPENGL_ES_2) - void loadGridLineMesh(); void updateDepthBuffer(); #endif void emitSelectedPointChanged(QPoint position); diff --git a/src/datavisualization/global/datavisualizationglobal_p.h b/src/datavisualization/global/datavisualizationglobal_p.h index 612b7bea..abdac998 100644 --- a/src/datavisualization/global/datavisualizationglobal_p.h +++ b/src/datavisualization/global/datavisualizationglobal_p.h @@ -68,6 +68,7 @@ static const GLfloat gradientTextureHeight = 1024.0f; static const GLfloat gradientTextureWidth = 2.0f; static const GLfloat uniformTextureHeight = 64.0f; static const GLfloat uniformTextureWidth = 2.0f; +static const GLfloat labelMargin = 0.05f; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/tests/scattertest/main.cpp b/tests/scattertest/main.cpp index ad147b0d..50c73901 100644 --- a/tests/scattertest/main.cpp +++ b/tests/scattertest/main.cpp @@ -232,6 +232,21 @@ int main(int argc, char **argv) aspectRatioSlider->setValue(20); aspectRatioSlider->setMaximum(100); + QCheckBox *axisTitlesVisibleCB = new QCheckBox(widget); + axisTitlesVisibleCB->setText(QStringLiteral("Axis titles visible")); + axisTitlesVisibleCB->setChecked(false); + + QCheckBox *axisTitlesFixedCB = new QCheckBox(widget); + axisTitlesFixedCB->setText(QStringLiteral("Axis titles fixed")); + axisTitlesFixedCB->setChecked(true); + + QSlider *axisLabelRotationSlider = new QSlider(Qt::Horizontal, widget); + axisLabelRotationSlider->setTickInterval(10); + axisLabelRotationSlider->setTickPosition(QSlider::TicksBelow); + axisLabelRotationSlider->setMinimum(0); + axisLabelRotationSlider->setValue(0); + axisLabelRotationSlider->setMaximum(90); + vLayout->addWidget(themeButton, 0, Qt::AlignTop); vLayout->addWidget(labelButton, 0, Qt::AlignTop); vLayout->addWidget(styleButton, 0, Qt::AlignTop); @@ -276,9 +291,13 @@ int main(int argc, char **argv) vLayout2->addWidget(new QLabel(QStringLiteral("Change font"))); vLayout2->addWidget(fontList); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust font size"))); - vLayout2->addWidget(fontSizeSlider, 0, Qt::AlignTop); + vLayout2->addWidget(fontSizeSlider); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust aspect ratio"))); vLayout2->addWidget(aspectRatioSlider, 1, Qt::AlignTop); + vLayout2->addWidget(axisTitlesVisibleCB); + vLayout2->addWidget(axisTitlesFixedCB); + vLayout2->addWidget(new QLabel(QStringLiteral("Axis label rotation"))); + vLayout2->addWidget(axisLabelRotationSlider, 1, Qt::AlignTop); widget->show(); @@ -366,7 +385,12 @@ int main(int argc, char **argv) &ScatterDataModifier::setMaxY); QObject::connect(maxSliderZ, &QSlider::valueChanged, modifier, &ScatterDataModifier::setMaxZ); - + QObject::connect(axisTitlesVisibleCB, &QCheckBox::stateChanged, modifier, + &ScatterDataModifier::toggleAxisTitleVisibility); + QObject::connect(axisTitlesFixedCB, &QCheckBox::stateChanged, modifier, + &ScatterDataModifier::toggleAxisTitleFixed); + QObject::connect(axisLabelRotationSlider, &QSlider::valueChanged, modifier, + &ScatterDataModifier::changeLabelRotation); QObject::connect(aspectRatioSlider, &QSlider::valueChanged, modifier, &ScatterDataModifier::setAspectRatio); diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp index 3f900909..dce73e61 100644 --- a/tests/scattertest/scatterchart.cpp +++ b/tests/scattertest/scatterchart.cpp @@ -478,9 +478,9 @@ void ScatterDataModifier::testAxisReverse() void ScatterDataModifier::addData() { // Add labels - m_chart->axisX()->setTitle("X"); - m_chart->axisY()->setTitle("Y"); - m_chart->axisZ()->setTitle("Z"); + m_chart->axisX()->setTitle("X - Axis"); + m_chart->axisY()->setTitle("Y - Axis"); + m_chart->axisZ()->setTitle("Z - Axis"); m_chart->axisX()->setRange(-50.0f, 50.0f); m_chart->axisY()->setRange(-1.0f, 1.2f); m_chart->axisZ()->setRange(-50.0f, 50.0f); @@ -921,6 +921,27 @@ void ScatterDataModifier::handleFpsChange(qreal fps) m_fpsLabel->setText(fpsPrefix + QString::number(qRound(fps))); } +void ScatterDataModifier::changeLabelRotation(int rotation) +{ + m_chart->axisX()->setLabelAutoRotation(float(rotation)); + m_chart->axisY()->setLabelAutoRotation(float(rotation)); + m_chart->axisZ()->setLabelAutoRotation(float(rotation)); +} + +void ScatterDataModifier::toggleAxisTitleVisibility(bool enabled) +{ + m_chart->axisX()->setTitleVisible(enabled); + m_chart->axisY()->setTitleVisible(enabled); + m_chart->axisZ()->setTitleVisible(enabled); +} + +void ScatterDataModifier::toggleAxisTitleFixed(bool enabled) +{ + m_chart->axisX()->setTitleFixed(enabled); + m_chart->axisY()->setTitleFixed(enabled); + m_chart->axisZ()->setTitleFixed(enabled); +} + void ScatterDataModifier::changeShadowQuality(int quality) { QAbstract3DGraph::ShadowQuality sq = QAbstract3DGraph::ShadowQuality(quality); diff --git a/tests/scattertest/scatterchart.h b/tests/scattertest/scatterchart.h index 34826aba..420c68e3 100644 --- a/tests/scattertest/scatterchart.h +++ b/tests/scattertest/scatterchart.h @@ -85,11 +85,13 @@ public slots: void removeSeries(); void toggleSeriesVisibility(); void changeSeriesName(); - void handleAxisXChanged(QValue3DAxis *axis); void handleAxisYChanged(QValue3DAxis *axis); void handleAxisZChanged(QValue3DAxis *axis); void handleFpsChange(qreal fps); + void changeLabelRotation(int rotation); + void toggleAxisTitleVisibility(bool enabled); + void toggleAxisTitleFixed(bool enabled); signals: void shadowQualityChanged(int quality); diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp index 442e7742..13cf9fad 100644 --- a/tests/surfacetest/graphmodifier.cpp +++ b/tests/surfacetest/graphmodifier.cpp @@ -700,6 +700,27 @@ void GraphModifier::handleFpsChange(qreal fps) qDebug() << "FPS:" << fps; } +void GraphModifier::changeLabelRotation(int rotation) +{ + m_graph->axisX()->setLabelAutoRotation(float(rotation)); + m_graph->axisY()->setLabelAutoRotation(float(rotation)); + m_graph->axisZ()->setLabelAutoRotation(float(rotation)); +} + +void GraphModifier::toggleAxisTitleVisibility(bool enabled) +{ + m_graph->axisX()->setTitleVisible(enabled); + m_graph->axisY()->setTitleVisible(enabled); + m_graph->axisZ()->setTitleVisible(enabled); +} + +void GraphModifier::toggleAxisTitleFixed(bool enabled) +{ + m_graph->axisX()->setTitleFixed(enabled); + m_graph->axisY()->setTitleFixed(enabled); + m_graph->axisZ()->setTitleFixed(enabled); +} + void GraphModifier::resetArrayAndSliders(QSurfaceDataArray *array, float minZ, float maxZ, float minX, float maxX) { m_axisMinSliderX->setValue(minX); diff --git a/tests/surfacetest/graphmodifier.h b/tests/surfacetest/graphmodifier.h index ff0b325e..1cf13b97 100644 --- a/tests/surfacetest/graphmodifier.h +++ b/tests/surfacetest/graphmodifier.h @@ -126,6 +126,9 @@ public slots: void handleAxisYChanged(QValue3DAxis *axis); void handleAxisZChanged(QValue3DAxis *axis); void handleFpsChange(qreal fps); + void changeLabelRotation(int rotation); + void toggleAxisTitleVisibility(bool enabled); + void toggleAxisTitleFixed(bool enabled); private: void fillSeries(); diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp index 7444a66a..0b146678 100644 --- a/tests/surfacetest/main.cpp +++ b/tests/surfacetest/main.cpp @@ -370,6 +370,21 @@ int main(int argc, char *argv[]) line3->setFrameShape(QFrame::HLine); line3->setFrameShadow(QFrame::Sunken); + QCheckBox *axisTitlesVisibleCB = new QCheckBox(widget); + axisTitlesVisibleCB->setText(QStringLiteral("Axis titles visible")); + axisTitlesVisibleCB->setChecked(false); + + QCheckBox *axisTitlesFixedCB = new QCheckBox(widget); + axisTitlesFixedCB->setText(QStringLiteral("Axis titles fixed")); + axisTitlesFixedCB->setChecked(true); + + QSlider *axisLabelRotationSlider = new QSlider(Qt::Horizontal, widget); + axisLabelRotationSlider->setTickInterval(10); + axisLabelRotationSlider->setTickPosition(QSlider::TicksBelow); + axisLabelRotationSlider->setMinimum(0); + axisLabelRotationSlider->setValue(0); + axisLabelRotationSlider->setMaximum(90); + // Add controls to the layout #ifdef MULTI_SERIES vLayout->addWidget(series1CB); @@ -450,6 +465,10 @@ int main(int argc, char *argv[]) vLayout2->addWidget(massiveDataTestButton); vLayout2->addWidget(testReverseButton); vLayout2->addWidget(testDataOrderingButton); + vLayout2->addWidget(axisTitlesVisibleCB); + vLayout2->addWidget(axisTitlesFixedCB); + vLayout2->addWidget(new QLabel(QStringLiteral("Axis label rotation"))); + vLayout2->addWidget(axisLabelRotationSlider, 1, Qt::AlignTop); widget->show(); @@ -611,6 +630,12 @@ int main(int argc, char *argv[]) modifier, &GraphModifier::testAxisReverse); QObject::connect(testDataOrderingButton, &QPushButton::clicked, modifier, &GraphModifier::testDataOrdering); + QObject::connect(axisTitlesVisibleCB, &QCheckBox::stateChanged, + modifier, &GraphModifier::toggleAxisTitleVisibility); + QObject::connect(axisTitlesFixedCB, &QCheckBox::stateChanged, + modifier, &GraphModifier::toggleAxisTitleFixed); + QObject::connect(axisLabelRotationSlider, &QSlider::valueChanged, modifier, + &GraphModifier::changeLabelRotation); QObject::connect(aspectRatioSlider, &QSlider::valueChanged, modifier, &GraphModifier::setAspectRatio); -- cgit v1.2.3