diff options
author | Keränen Pasi <pasi.keranen@digia.com> | 2013-09-27 09:05:53 +0300 |
---|---|---|
committer | Pasi Keränen <pasi.keranen@digia.com> | 2013-10-08 10:50:41 +0300 |
commit | 66e1b09592efe77f839a0878ec6165a02408ca6f (patch) | |
tree | 709736fc6693c014abc0467a7c1ac766c1c62c4f | |
parent | 0daa4359bdaba6372bc8235550892afdef003120 (diff) |
Added Camera QML API and Example
Change-Id: Ibc790ac6c720b6d22d68f662ff2f50e74a9abaae
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
53 files changed, 1441 insertions, 314 deletions
diff --git a/examples/audiolevels/audiolevels.cpp b/examples/audiolevels/audiolevels.cpp index 0d227a31..5171492f 100644 --- a/examples/audiolevels/audiolevels.cpp +++ b/examples/audiolevels/audiolevels.cpp @@ -21,6 +21,8 @@ #include <QtDataVisualization/qbardataproxy.h> #include <QtDataVisualization/q3dvalueaxis.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <QAudioDeviceInfo> #include <QAudioInput> @@ -42,7 +44,7 @@ AudioLevels::AudioLevels(Q3DBars *graph, QObject *parent) m_graph->setBackgroundVisible(false); m_graph->valueAxis()->setRange(0.0, 1.0); m_graph->setShadowQuality(QDataVis::ShadowQualityNone); - m_graph->setCameraPosition(-20.0, 10.0, 10); + m_graph->scene()->activeCamera()->setCameraPosition(-20.0, 10.0, 10); m_graph->setTheme(QDataVis::ThemeIsabelle); QAudioFormat formatAudio; diff --git a/examples/bars/main.cpp b/examples/bars/main.cpp index e3ec17c5..6ab685ed 100644 --- a/examples/bars/main.cpp +++ b/examples/bars/main.cpp @@ -20,6 +20,8 @@ #include <QtDataVisualization/q3dcategoryaxis.h> #include <QtDataVisualization/qitemmodelbardataproxy.h> #include <QtDataVisualization/q3dvalueaxis.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <QApplication> #include <QVBoxLayout> @@ -113,7 +115,7 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid m_graph->setTheme(QDataVis::ThemeDigia); // Set preset camera position - m_graph->setCameraPreset(QDataVis::CameraPresetFront); + m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront); //! [7] } diff --git a/examples/qmlbars/qml/qmlbars/main.qml b/examples/qmlbars/qml/qmlbars/main.qml index aec3188c..d349ef97 100644 --- a/examples/qmlbars/qml/qmlbars/main.qml +++ b/examples/qmlbars/qml/qmlbars/main.qml @@ -54,7 +54,7 @@ Item { barThickness: 0.5 barSpacing: Qt.size(0.5, 0.5) barSpacingRelative: false - cameraPreset: Bars3D.CameraPresetRight + scene.activeCamera.cameraPreset: Bars3D.CameraPresetRight columnAxis: graphAxes.column valueAxis: graphAxes.expenses itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel" diff --git a/examples/rainfall/rainfallgraph.cpp b/examples/rainfall/rainfallgraph.cpp index 5cd70710..41f72464 100644 --- a/examples/rainfall/rainfallgraph.cpp +++ b/examples/rainfall/rainfallgraph.cpp @@ -19,6 +19,8 @@ #include "rainfallgraph.h" #include <QtDataVisualization/q3dcategoryaxis.h> #include <QtDataVisualization/q3dvalueaxis.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <QGuiApplication> #include <QFont> #include <QDebug> @@ -72,7 +74,7 @@ RainfallGraph::RainfallGraph(Q3DBars *rainfall) m_graph->setTheme(QDataVis::ThemeArmyBlue); // Set preset camera position - m_graph->setCameraPreset(QDataVis::CameraPresetIsometricRightHigh); + m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetIsometricRightHigh); // Disable grid m_graph->setGridVisible(false); diff --git a/examples/scatter/scatterdatamodifier.cpp b/examples/scatter/scatterdatamodifier.cpp index cf3296bb..d9fc5bc3 100644 --- a/examples/scatter/scatterdatamodifier.cpp +++ b/examples/scatter/scatterdatamodifier.cpp @@ -19,6 +19,8 @@ #include "scatterdatamodifier.h" #include <QtDataVisualization/qscatterdataproxy.h> #include <QtDataVisualization/q3dvalueaxis.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <qmath.h> using namespace QtDataVisualization; @@ -38,7 +40,7 @@ ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter) m_graph->setObjectType(QDataVis::MeshStyleSpheres, true); m_graph->setTheme(QDataVis::ThemeEbony); m_graph->setShadowQuality(QDataVis::ShadowQualityHigh); - m_graph->setCameraPreset(QDataVis::CameraPresetFront); + m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront); m_graph->setAxisX(new Q3DValueAxis); m_graph->setAxisY(new Q3DValueAxis); m_graph->setAxisZ(new Q3DValueAxis); @@ -113,7 +115,7 @@ void ScatterDataModifier::changePresetCamera() { static int preset = QDataVis::CameraPresetFrontLow; - m_graph->setCameraPreset((QDataVis::CameraPreset)preset); + m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset); if (++preset > QDataVis::CameraPresetDirectlyAboveCCW45) preset = QDataVis::CameraPresetFrontLow; diff --git a/examples/widget/graphmodifier.cpp b/examples/widget/graphmodifier.cpp index 7da3000b..c5b8be4a 100644 --- a/examples/widget/graphmodifier.cpp +++ b/examples/widget/graphmodifier.cpp @@ -20,6 +20,8 @@ #include <QtDataVisualization/q3dcategoryaxis.h> #include <QtDataVisualization/q3dvalueaxis.h> #include <QtDataVisualization/qbardataproxy.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <QTime> QT_DATAVISUALIZATION_USE_NAMESPACE @@ -134,7 +136,7 @@ void GraphModifier::changePresetCamera() { static int preset = QDataVis::CameraPresetFrontLow; - m_graph->setCameraPreset((QDataVis::CameraPreset)preset); + m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset); if (++preset > QDataVis::CameraPresetDirectlyBelow) preset = QDataVis::CameraPresetFrontLow; @@ -192,13 +194,13 @@ void GraphModifier::changeShadowQuality(int quality) void GraphModifier::rotateX(int rotation) { m_xRotation = rotation; - m_graph->setCameraPosition(m_xRotation, m_yRotation); + m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); } void GraphModifier::rotateY(int rotation) { m_yRotation = rotation; - m_graph->setCameraPosition(m_xRotation, m_yRotation); + m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); } void GraphModifier::setBackgroundEnabled(int enabled) diff --git a/src/datavisualization/data/scatterrenderitem_p.h b/src/datavisualization/data/scatterrenderitem_p.h index 46df6c85..58e91e96 100644 --- a/src/datavisualization/data/scatterrenderitem_p.h +++ b/src/datavisualization/data/scatterrenderitem_p.h @@ -45,7 +45,7 @@ public: inline const QVector3D &position() const { return m_position; } inline void setPosition(const QVector3D &pos); - inline const bool isVisible() const { return m_visible; } + inline bool isVisible() const { return m_visible; } inline void setVisible(bool visible) { m_visible = visible; } //inline void setSize(qreal size); diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 3631bad1..e4286465 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -35,8 +35,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : QObject(parent), m_boundingRect(boundRect.x(), boundRect.y(), boundRect.width(), boundRect.height()), - m_horizontalRotation(-45.0f), - m_verticalRotation(15.0f), m_theme(), m_font(QFont(QStringLiteral("Arial"))), m_selectionMode(QDataVis::SelectionModeItem), @@ -304,37 +302,49 @@ void Abstract3DController::render(const GLuint defaultFboHandle) void Abstract3DController::mouseDoubleClickEvent(QMouseEvent *event) { - m_activeInputHandler->mouseDoubleClickEvent(event); + if (m_activeInputHandler) + m_activeInputHandler->mouseDoubleClickEvent(event); + emitNeedRender(); } void Abstract3DController::touchEvent(QTouchEvent *event) { - m_activeInputHandler->touchEvent(event); + if (m_activeInputHandler) + m_activeInputHandler->touchEvent(event); + emitNeedRender(); } void Abstract3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) { - m_activeInputHandler->mousePressEvent(event, mousePos); + if (m_activeInputHandler) + m_activeInputHandler->mousePressEvent(event, mousePos); + emitNeedRender(); } void Abstract3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos) { - m_activeInputHandler->mouseReleaseEvent(event, mousePos); + if (m_activeInputHandler) + m_activeInputHandler->mouseReleaseEvent(event, mousePos); + emitNeedRender(); } void Abstract3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) { - m_activeInputHandler->mouseMoveEvent(event, mousePos); + if (m_activeInputHandler) + m_activeInputHandler->mouseMoveEvent(event, mousePos); + emitNeedRender(); } void Abstract3DController::wheelEvent(QWheelEvent *event) { - m_activeInputHandler->wheelEvent(event); + if (m_activeInputHandler) + m_activeInputHandler->wheelEvent(event); + emitNeedRender(); } @@ -609,6 +619,9 @@ void Abstract3DController::releaseInputHandler(QAbstract3DInputHandler *inputHan void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputHandler) { + if (inputHandler == m_activeInputHandler) + return; + // If existing input handler is the default input handler, delete it if (m_activeInputHandler) { if (m_activeInputHandler->d_ptr->m_isDefaultHandler) { @@ -621,10 +634,15 @@ void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputH } // Assume ownership and connect to this controller's scene - addInputHandler(inputHandler); + if (inputHandler) + addInputHandler(inputHandler); + m_activeInputHandler = inputHandler; if (m_activeInputHandler) m_activeInputHandler->setScene(m_scene); + + // Notify change of input handler + emit activeInputHandlerChanged(m_activeInputHandler); } QAbstract3DInputHandler* Abstract3DController::activeInputHandler() @@ -645,32 +663,6 @@ void Abstract3DController::setZoomLevel(int zoomLevel) emitNeedRender(); } -void Abstract3DController::setCameraPreset(QDataVis::CameraPreset preset) -{ - m_scene->activeCamera()->setCameraPreset(preset); - emitNeedRender(); -} - -QDataVis::CameraPreset Abstract3DController::cameraPreset() const -{ - return m_scene->activeCamera()->cameraPreset(); -} - -void Abstract3DController::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance) -{ - // disable camera movement if in slice view - if (scene()->isSlicingActive()) - return; - - m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f); - m_verticalRotation = qBound(0.0f, vertical, 90.0f); - m_scene->activeCamera()->setZoomLevel(qBound(10, distance, 500)); - m_scene->activeCamera()->setRotations(QPointF(m_horizontalRotation, - m_verticalRotation)); - //qDebug() << "camera rotation set to" << m_horizontalRotation << m_verticalRotation; - emitNeedRender(); -} - void Abstract3DController::setObjectColor(const QColor &baseColor, bool uniform) { m_theme.m_baseColor = baseColor; @@ -787,12 +779,18 @@ void Abstract3DController::setSlicingActive(bool isSlicing) QDataVis::InputState Abstract3DController::inputState() { - return m_activeInputHandler->inputState(); + if (m_activeInputHandler) + return m_activeInputHandler->inputState(); + else + return QDataVis::InputStateNone; } QPoint Abstract3DController::inputPosition() { - return m_activeInputHandler->inputPosition(); + if (m_activeInputHandler) + return m_activeInputHandler->inputPosition(); + else + return QPoint(0,0); } void Abstract3DController::setMeshFileName(const QString &fileName) diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index c857d5f1..f17c6c4d 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -29,8 +29,6 @@ #ifndef CONTROLLER3DBASE_H #define CONTROLLER3DBASE_H -#include <QObject> - #include "datavisualizationglobal_p.h" #include "theme_p.h" #include "q3dabstractaxis.h" @@ -40,6 +38,8 @@ #include "q3dscene.h" #include "q3dbox.h" +#include <QObject> + class QFont; QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -240,15 +240,6 @@ public: virtual int zoomLevel(); virtual void setZoomLevel(int zoomLevel); - // Select preset camera placement - virtual void setCameraPreset(QDataVis::CameraPreset preset); - virtual QDataVis::CameraPreset cameraPreset() const; - - // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and - // vertical (0...90) (or (-90...90) if there are negative values) angles and distance in - // percentage (10...500)) - virtual void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100); - // Set color if you don't want to use themes. virtual void setObjectColor(const QColor &baseColor, bool uniform = true); virtual QColor objectColor() const; @@ -324,6 +315,7 @@ public slots: signals: void shadowQualityChanged(QDataVis::ShadowQuality quality); + void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler); void needRender(); protected: diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 129ae924..38c4aa6a 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -209,7 +209,13 @@ void Bars3DRenderer::updateScene(Q3DScene *scene) // TODO: Move these to more suitable place e.g. controller should be controlling the viewports. scene->setSecondarySubViewport(m_sliceViewPort); scene->setPrimarySubViewport(m_mainViewPort); - scene->setUnderSideCameraEnabled(m_hasNegativeValues); + + // TODO: See QTRD-2374 + if (m_hasNegativeValues) + scene->activeCamera()->setMinYRotation(-90.0); + else + scene->activeCamera()->setMinYRotation(0.0); + if (m_hasHeightAdjustmentChanged) { // Set initial camera position. Also update if height adjustment has changed. scene->activeCamera()->setBaseOrientation(QVector3D(0.0f, 0.0f, cameraDistance + zComp), @@ -256,7 +262,7 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, GLfloat negativesComp = 1.0f; // Compensate bar scaling a bit to avoid drawing on axis titles when we have negative values - if (m_cachedScene->isUnderSideCameraEnabled()) + if (m_hasNegativeValues) negativesComp = 0.67f; // Specify viewport diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp index 35623c99..9d50186d 100644 --- a/src/datavisualization/engine/drawer.cpp +++ b/src/datavisualization/engine/drawer.cpp @@ -316,9 +316,10 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte if (useDepth && !rotateAlong) { qreal yComp = qreal(qRadiansToDegrees(qTan(positionComp.y() / cameraDistance))); // Apply negative camera rotations to keep labels facing camera - QPointF camRotations = camera->rotations(); - modelMatrix.rotate(-camRotations.x(), 0.0f, 1.0f, 0.0f); - modelMatrix.rotate(-camRotations.y() - yComp, 1.0f, 0.0f, 0.0f); + qreal camRotationX = camera->xRotation(); + qreal camRotationY = camera->yRotation(); + modelMatrix.rotate(-camRotationX, 0.0f, 1.0f, 0.0f); + modelMatrix.rotate(-camRotationY - yComp, 1.0f, 0.0f, 0.0f); } // Scale label based on text size diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp index ef0eb88b..6af18b1f 100644 --- a/src/datavisualization/engine/q3dbars.cpp +++ b/src/datavisualization/engine/q3dbars.cpp @@ -22,6 +22,7 @@ #include "q3dvalueaxis.h" #include "q3dcategoryaxis.h" #include "qbardataproxy.h" +#include "q3dcamera.h" #include <QMouseEvent> @@ -253,32 +254,6 @@ void Q3DBars::setBarType(QDataVis::MeshStyle style, bool smooth) } /*! - * \property Q3DBars::cameraPreset - * - * The \a preset position of the camera. The position can be one of \c QDataVis::CameraPreset. - */ -void Q3DBars::setCameraPreset(QDataVis::CameraPreset preset) -{ - d_ptr->m_shared->setCameraPreset(preset); -} - -QDataVis::CameraPreset Q3DBars::cameraPreset() const -{ - return d_ptr->m_shared->cameraPreset(); -} - -/*! - * Move camera to a wanted position based on \a horizontal and \a vertical angles. Angles are limited - * to -180...180 in horizontal direction and either -90...90 or 0...90 in vertical, depending - * on data values. Negative vertical angles are allowed only if there are negative bar values. - * \a distance is adjustable between 10 and 500, being \c 100 by default. - */ -void Q3DBars::setCameraPosition(qreal horizontal, qreal vertical, int distance) -{ - d_ptr->m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance)); -} - -/*! * Sets a predefined \a theme from \c QDataVis::Theme. It is preset to \c QDataVis::ThemeQt by * default. Theme affects bar colors, label colors, text color, background color, window color and * grid color. Lighting is also adjusted by themes. @@ -367,6 +342,16 @@ QFont Q3DBars::font() const } /*! + * \property Q3DBars::scene + * + * This property contains the read only Q3DScene that can be used to access e.g. camera object. + */ +Q3DScene *Q3DBars::scene() const +{ + return d_ptr->m_shared->scene(); +} + +/*! * \property Q3DBars::labelStyle * * Sets label \a style to one of \c QDataVis::LabelStyle. It is preset to diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h index b62ebd32..d0ddf3fb 100644 --- a/src/datavisualization/engine/q3dbars.h +++ b/src/datavisualization/engine/q3dbars.h @@ -30,6 +30,7 @@ class Q3DAbstractAxis; class Q3DCategoryAxis; class Q3DValueAxis; class QBarDataProxy; +class Q3DScene; class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow { @@ -37,7 +38,6 @@ class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) - Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset) Q_PROPERTY(qreal barThickness READ barThickness WRITE setBarThickness) Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing) Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative) @@ -46,6 +46,8 @@ class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible) Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible) Q_PROPERTY(QPoint selectedBarPos READ selectedBarPos WRITE setSelectedBarPos NOTIFY selectedBarPosChanged) + Q_PROPERTY(Q3DScene* scene READ scene) + Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode) Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality) Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle) @@ -57,11 +59,6 @@ public: void setBarType(QDataVis::MeshStyle style, bool smooth = false); - void setCameraPreset(QDataVis::CameraPreset preset); - QDataVis::CameraPreset cameraPreset() const; - - void setCameraPosition(qreal horizontal, qreal vertical, int distance = 100); - void setTheme(QDataVis::Theme theme); void setBarThickness(qreal thicknessRatio); @@ -85,6 +82,8 @@ public: void setFont(const QFont &font); QFont font() const; + Q3DScene *scene() const; + void setLabelStyle(QDataVis::LabelStyle style); QDataVis::LabelStyle labelStyle() const; diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp index 6b91cac8..51973e02 100644 --- a/src/datavisualization/engine/q3dcamera.cpp +++ b/src/datavisualization/engine/q3dcamera.cpp @@ -21,6 +21,7 @@ #include "q3dscene.h" #include "q3dbox.h" #include "q3dobject.h" +#include "utils_p.h" #include <qmath.h> #include <QVector3D> @@ -79,28 +80,201 @@ void Q3DCamera::copyValuesFrom(const Q3DCamera &source) d_ptr->m_xRotation = source.d_ptr->m_xRotation; d_ptr->m_yRotation = source.d_ptr->m_yRotation; + d_ptr->m_minXRotation = source.d_ptr->m_minXRotation; + d_ptr->m_minYRotation = source.d_ptr->m_minYRotation; + d_ptr->m_maxXRotation = source.d_ptr->m_maxXRotation; + d_ptr->m_maxYRotation = source.d_ptr->m_maxYRotation; + + d_ptr->m_wrapXRotation = source.d_ptr->m_wrapXRotation; + d_ptr->m_wrapYRotation = source.d_ptr->m_wrapYRotation; + d_ptr->m_zoomLevel = source.d_ptr->m_zoomLevel; d_ptr->m_activePreset = source.d_ptr->m_activePreset; } /*! - * \property Q3DCamera::rotations + * \property Q3DCamera::xRotation * - * This property contains the rotation angles of the camera around the target point in degrees starting from + * This property contains the X-rotation angle of the camera around the target point in degrees starting from * the current base position set by the setBaseOrientation() methods. */ -QPointF Q3DCamera::rotations() const +qreal Q3DCamera::xRotation() const { + return d_ptr->m_xRotation; +} + +void Q3DCamera::setXRotation(qreal rotation) { - QPointF rotations(d_ptr->m_xRotation, d_ptr->m_yRotation); - return rotations; + if (d_ptr->m_wrapXRotation) + rotation = Utils::wrapValue(rotation, d_ptr->m_minXRotation, d_ptr->m_maxXRotation); + else + rotation = qBound(qreal(d_ptr->m_minXRotation), qreal(rotation), qreal(d_ptr->m_maxXRotation)); + + if (d_ptr->m_xRotation != rotation) { + d_ptr->setXRotation(rotation); + if (d_ptr->m_activePreset != QDataVis::CameraPresetNone) { + d_ptr->m_activePreset = QDataVis::CameraPresetNone; + setDirty(true); + } + + emit xRotationChanged(d_ptr->m_xRotation); + } +} + +/*! + * \property Q3DCamera::yRotation + * + * This property contains the Y-rotation angle of the camera around the target point in degrees starting from + * the current base position set by the setBaseOrientation() methods. + */ +qreal Q3DCamera::yRotation() const { + return d_ptr->m_yRotation; } -void Q3DCamera::setRotations(const QPointF &rotation) +void Q3DCamera::setYRotation(qreal rotation) { - d_ptr->setRotations(rotation); - if (d_ptr->m_activePreset != QDataVis::CameraPresetNone) { - d_ptr->m_activePreset = QDataVis::CameraPresetNone; - setDirty(true); + if (d_ptr->m_wrapYRotation) + rotation = Utils::wrapValue(rotation, d_ptr->m_minYRotation, d_ptr->m_maxYRotation); + else + rotation = qBound(qreal(d_ptr->m_minYRotation), qreal(rotation), qreal(d_ptr->m_maxYRotation)); + + if (d_ptr->m_yRotation != rotation) { + d_ptr->setYRotation(rotation); + if (d_ptr->m_activePreset != QDataVis::CameraPresetNone) { + d_ptr->m_activePreset = QDataVis::CameraPresetNone; + setDirty(true); + } + + emit yRotationChanged(d_ptr->m_yRotation); + } +} + +/*! + * \property Q3DCamera::minXRotation + * + * This property contains the current minimum X-rotation for the camera. + * The full circle range is [-180,180] and the minimum value is limited to -180. + * Also the value can't be higher than maximum, and is adjusted if necessary. + * + * \sa wrapXRotation, maxXRotation + */ +qreal Q3DCamera::minXRotation() const +{ + return d_ptr->m_minXRotation; +} + +/*! + * \internal + */ +void Q3DCamera::setMinXRotation(qreal minRotation) +{ + minRotation = qBound(-180.0, minRotation, 180.0); + if (minRotation > d_ptr->m_maxXRotation) + minRotation = d_ptr->m_maxXRotation; + + if (d_ptr->m_minXRotation != minRotation) { + d_ptr->m_minXRotation = minRotation; + emit minXRotationChanged(minRotation); + + if (d_ptr->m_xRotation < d_ptr->m_minXRotation) + setXRotation(d_ptr->m_xRotation); + } +} + +/*! + * \property Q3DCamera::minYRotation + * + * This property contains the current minimum Y-rotation for the camera. + * The full Y angle range is [-90,90] and the minimum value is limited to -90. + * Also the value can't be higher than maximum, and is adjusted if necessary. + * + * \sa wrapYRotation, maxYRotation + */ +qreal Q3DCamera::minYRotation() const +{ + return d_ptr->m_minYRotation; +} + +/*! + * \internal + */ +void Q3DCamera::setMinYRotation(qreal minRotation) +{ + minRotation = qBound(-90.0, minRotation, 90.0); + if (minRotation > d_ptr->m_maxYRotation) + minRotation = d_ptr->m_maxYRotation; + + if (d_ptr->m_minYRotation != minRotation) { + d_ptr->m_minYRotation = minRotation; + emit minYRotationChanged(minRotation); + + if (d_ptr->m_yRotation < d_ptr->m_minYRotation) + setYRotation(d_ptr->m_yRotation); + } +} + +/*! + * \property Q3DCamera::maxXRotation + * + * This property contains the current maximum X-rotation for the camera. + * The full circle range is [-180,180] and the maximum value is limited to 180. + * Also the value can't be lower than minimum, and is adjusted if necessary. + * + * \sa wrapXRotation, minXRotation + */ +qreal Q3DCamera::maxXRotation() const +{ + return d_ptr->m_maxXRotation; +} + +/*! + * \internal + */ +void Q3DCamera::setMaxXRotation(qreal maxRotation) +{ + maxRotation = qBound(-180.0, maxRotation, 180.0); + + if (maxRotation < d_ptr->m_minXRotation) + maxRotation = d_ptr->m_minXRotation; + + if (d_ptr->m_maxXRotation != maxRotation) { + d_ptr->m_maxXRotation = maxRotation; + emit maxXRotationChanged(maxRotation); + + if (d_ptr->m_xRotation > d_ptr->m_maxXRotation) + setXRotation(d_ptr->m_xRotation); + } +} + +/*! + * \property Q3DCamera::maxYRotation + * + * This property contains the current maximum Y-rotation for the camera. + * The full Y angle range is [-90,90] and the maximum value is limited to 90. + * Also the value can't be lower than minimum, and is adjusted if necessary. + * + * \sa wrapYRotation, minYRotation + */ +qreal Q3DCamera::maxYRotation() const +{ + return d_ptr->m_maxYRotation; +} + +/*! + * \internal + */ +void Q3DCamera::setMaxYRotation(qreal maxRotation) +{ + maxRotation = qBound(-90.0, maxRotation, 90.0); + + if (maxRotation < d_ptr->m_minYRotation) + maxRotation = d_ptr->m_minYRotation; + + if (d_ptr->m_maxYRotation != maxRotation) { + d_ptr->m_maxYRotation = maxRotation; + emit maxYRotationChanged(maxRotation); + + if (d_ptr->m_yRotation > d_ptr->m_maxYRotation) + setYRotation(d_ptr->m_yRotation); } } @@ -141,6 +315,7 @@ void Q3DCamera::setViewMatrix(const QMatrix4x4 &viewMatrix) if (d_ptr->m_viewMatrix != viewMatrix) { d_ptr->m_viewMatrix = viewMatrix; setDirty(true); + emit viewMatrixChanged(d_ptr->m_viewMatrix); } } @@ -159,6 +334,7 @@ bool Q3DCamera::isViewMatrixAutoUpdateEnabled() void Q3DCamera::setViewMatrixAutoUpdateEnabled(bool isEnabled) { d_ptr->m_isViewMatrixUpdateActive = isEnabled; + emit viewMatrixAutoUpdateChanged(isEnabled); } /*! @@ -178,99 +354,123 @@ void Q3DCamera::setCameraPreset(QDataVis::CameraPreset preset) { switch (preset) { case QDataVis::CameraPresetFrontLow: { - d_ptr->setRotations(QPointF(0.0f, 0.0f)); + setXRotation(0.0); + setYRotation(0.0); break; } case QDataVis::CameraPresetFront: { - d_ptr->setRotations(QPointF(0.0f, 22.5f)); + setXRotation(0.0); + setYRotation(22.5); break; } case QDataVis::CameraPresetFrontHigh: { - d_ptr->setRotations(QPointF(0.0f, 45.0f)); + setXRotation(0.0); + setYRotation(45.0); break; } case QDataVis::CameraPresetLeftLow: { - d_ptr->setRotations(QPointF(90.0f, 0.0f)); + setXRotation(90.0); + setYRotation(0.0); break; } case QDataVis::CameraPresetLeft: { - d_ptr->setRotations(QPointF(90.0f, 22.5f)); + setXRotation(90.0); + setYRotation(22.5); break; } case QDataVis::CameraPresetLeftHigh: { - d_ptr->setRotations(QPointF(90.0f, 45.0f)); + setXRotation(90.0); + setYRotation(45.0); break; } case QDataVis::CameraPresetRightLow: { - d_ptr->setRotations(QPointF(-90.0f, 0.0f)); + setXRotation(-90.0); + setYRotation(0.0); break; } case QDataVis::CameraPresetRight: { - d_ptr->setRotations(QPointF(-90.0f, 22.5f)); + setXRotation(-90.0); + setYRotation(22.5); break; } case QDataVis::CameraPresetRightHigh: { - d_ptr->setRotations(QPointF(-90.0f, 45.0f)); + setXRotation(-90.0); + setYRotation(45.0); break; } case QDataVis::CameraPresetBehindLow: { - d_ptr->setRotations(QPointF(180.0f, 0.0f)); + setXRotation(180.0); + setYRotation(0.0); break; } case QDataVis::CameraPresetBehind: { - d_ptr->setRotations(QPointF(180.0f, 22.5f)); + setXRotation(180.0); + setYRotation(22.5); break; } case QDataVis::CameraPresetBehindHigh: { - d_ptr->setRotations(QPointF(180.0f, 45.0f)); + setXRotation(180.0); + setYRotation(45.0); break; } case QDataVis::CameraPresetIsometricLeft: { - d_ptr->setRotations(QPointF(45.0f, 22.5f)); + setXRotation(45.0); + setYRotation(22.5); break; } case QDataVis::CameraPresetIsometricLeftHigh: { - d_ptr->setRotations(QPointF(45.0f, 45.0f)); + setXRotation(45.0); + setYRotation(45.0); break; } case QDataVis::CameraPresetIsometricRight: { - d_ptr->setRotations(QPointF(-45.0f, 22.5f)); + setXRotation(-45.0); + setYRotation(22.5); break; } case QDataVis::CameraPresetIsometricRightHigh: { - d_ptr->setRotations(QPointF(-45.0f, 45.0f)); + setXRotation(-45.0); + setYRotation(45.0); break; } case QDataVis::CameraPresetDirectlyAbove: { - d_ptr->setRotations(QPointF(0.0f, 90.0f)); + setXRotation(0.0); + setYRotation(90.0); break; } case QDataVis::CameraPresetDirectlyAboveCW45: { - d_ptr->setRotations(QPointF(-45.0f, 90.0f)); + setXRotation(-45.0); + setYRotation(90.0); break; } case QDataVis::CameraPresetDirectlyAboveCCW45: { - d_ptr->setRotations(QPointF(45.0f, 90.0f)); + setXRotation(45.0); + setYRotation(90.0); break; } case QDataVis::CameraPresetFrontBelow: { - d_ptr->setRotations(QPointF(0.0f, -45.0f)); + setXRotation(0.0); + setYRotation(-45.0); break; } case QDataVis::CameraPresetLeftBelow: { - d_ptr->setRotations(QPointF(90.0f, -45.0f)); + setXRotation(90.0); + setYRotation(-45.0); break; } case QDataVis::CameraPresetRightBelow: { - d_ptr->setRotations(QPointF(-90.0f, -45.0f)); + setXRotation(-90.0); + setYRotation(-45.0); break; } case QDataVis::CameraPresetBehindBelow: { - d_ptr->setRotations(QPointF(180.0f, -45.0f)); + setXRotation(180.0); + setYRotation(-45.0); break; } case QDataVis::CameraPresetDirectlyBelow: { - d_ptr->setRotations(QPointF(0.0f, -90.0f)); + setXRotation(0.0); + setYRotation(-90.0); break; } default: @@ -281,6 +481,7 @@ void Q3DCamera::setCameraPreset(QDataVis::CameraPreset preset) if (d_ptr->m_activePreset != preset) { d_ptr->m_activePreset = preset; setDirty(true); + emit cameraPresetChanged(preset); } } @@ -300,6 +501,7 @@ void Q3DCamera::setZoomLevel(int zoomLevel) if (d_ptr->m_zoomLevel != zoomLevel) { d_ptr->m_zoomLevel = zoomLevel; setDirty(true); + emit zoomLevelChanged(zoomLevel); } } @@ -336,18 +538,71 @@ QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relative zPos + relativePosition.z()); } +/*! + * \property Q3DCamera::wrapXRotation + * + * This property determines the behavior of the minimum and maximum limits in the X-rotation. + * By default the X-rotation wraps from minimum value to maximum and from maximum to minimum. + * + * If set to true the X-rotation of the camera is wrapped from minimum to maximum and from maximum to minimum. + * If set to false the X-rotation of the camera is limited to the sector determined by minimum and maximum values. + */ +bool Q3DCamera::wrapXRotation() const +{ + return d_ptr->m_wrapXRotation; +} + +void Q3DCamera::setWrapXRotation(bool isEnabled) +{ + d_ptr->m_wrapXRotation = isEnabled; +} + +/*! + * \property Q3DCamera::wrapYRotation + * + * This property determines the behavior of the minimum and maximum limits in the Y-rotation. + * By default the Y-rotation is limited between the minimum and maximum values without any wrapping. + * + * If true the Y-rotation of the camera is wrapped from minimum to maximum and from maximum to minimum. + * If false the Y-rotation of the camera is limited to the sector determined by minimum and maximum values. + */ +bool Q3DCamera::wrapYRotation() const +{ + return d_ptr->m_wrapYRotation; +} + +void Q3DCamera::setWrapYRotation(bool isEnabled) +{ + d_ptr->m_wrapYRotation = isEnabled; +} + +/*! + * Utility function that sets the camera rotations and distance.\a horizontal and \a vertical define the camera rotations to be used. + * Optional \a zoom parameter can be given to set the zoom of the camera in range of 10-500%. + */ +void Q3DCamera::setCameraPosition(qreal horizontal, qreal vertical, qreal zoom) +{ + setZoomLevel(qBound(10.0, distance, 500.0)); + setXRotation(horizontal); + setYRotation(vertical); +} Q3DCameraPrivate::Q3DCameraPrivate(Q3DCamera *q) : q_ptr(q), m_isViewMatrixUpdateActive(true), - m_xRotation(0.0f), - m_yRotation(0.0f), + m_xRotation(0.0), + m_yRotation(0.0), + m_minXRotation(-180.0), + m_minYRotation(0.0), + m_maxXRotation(180.0), + m_maxYRotation(90.0), + m_wrapXRotation(true), + m_wrapYRotation(false), m_zoomLevel(100), m_activePreset(QDataVis::CameraPresetNone) { } - Q3DCameraPrivate::~Q3DCameraPrivate() { } @@ -363,11 +618,50 @@ void Q3DCameraPrivate::sync(Q3DCamera &other) } } -void Q3DCameraPrivate::setRotations(const QPointF &rotation) +void Q3DCameraPrivate::setXRotation(const qreal rotation) +{ + if (m_xRotation != rotation) { + m_xRotation = rotation; + q_ptr->setDirty(true); + } +} + +void Q3DCameraPrivate::setYRotation(const qreal rotation) +{ + if (m_yRotation != rotation) { + m_yRotation = rotation; + q_ptr->setDirty(true); + } +} + +void Q3DCameraPrivate::setMinXRotation(const qreal rotation) +{ + if (m_minXRotation != rotation) { + m_minXRotation = rotation; + q_ptr->setDirty(true); + } +} + +void Q3DCameraPrivate::setMinYRotation(const qreal rotation) +{ + if (m_minYRotation != rotation) { + m_minYRotation = rotation; + q_ptr->setDirty(true); + } +} + +void Q3DCameraPrivate::setMaxXRotation(const qreal rotation) +{ + if (m_maxXRotation != rotation) { + m_maxXRotation = rotation; + q_ptr->setDirty(true); + } +} + +void Q3DCameraPrivate::setMaxYRotation(const qreal rotation) { - if (m_xRotation != rotation.x() || m_yRotation != rotation.y()) { - m_xRotation = rotation.x(); - m_yRotation = rotation.y(); + if (m_maxYRotation != rotation) { + m_maxYRotation = rotation; q_ptr->setDirty(true); } } @@ -379,20 +673,8 @@ void Q3DCameraPrivate::updateViewMatrix(qreal zoomAdjustment) if (!m_isViewMatrixUpdateActive) return; - bool showUnder = q_ptr->parentScene()->isUnderSideCameraEnabled(); int zoom = m_zoomLevel * zoomAdjustment; QMatrix4x4 viewMatrix; - GLfloat lowerLimit = 0.0f; - if (showUnder) - lowerLimit = -90.0f; - - // Reset at 360 in x and limit to 0...90 in y - if (qAbs(m_xRotation) >= 360.0f) - m_xRotation = 0.0f; - if (m_yRotation >= 90.0f) - m_yRotation = 90.0f; - else if (m_yRotation <= lowerLimit) - m_yRotation = lowerLimit; // Apply to view matrix viewMatrix.lookAt(q_ptr->position(), m_target, m_up); diff --git a/src/datavisualization/engine/q3dcamera.h b/src/datavisualization/engine/q3dcamera.h index 5780fcda..ee750cec 100644 --- a/src/datavisualization/engine/q3dcamera.h +++ b/src/datavisualization/engine/q3dcamera.h @@ -24,7 +24,6 @@ class QVector3D; class QPoint; -class QPointF; QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -33,40 +32,83 @@ class Q3DCameraPrivate; class QT_DATAVISUALIZATION_EXPORT Q3DCamera : public Q3DObject { Q_OBJECT - Q_PROPERTY(QPointF rotations READ rotations WRITE setRotations) - Q_PROPERTY(QMatrix4x4 viewMatrix READ viewMatrix WRITE setViewMatrix) - Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset) - Q_PROPERTY(int zoomLevel READ zoomLevel WRITE setZoomLevel) - Q_PROPERTY(bool viewMatrixAutoUpdateEnabled READ isViewMatrixAutoUpdateEnabled WRITE setViewMatrixAutoUpdateEnabled) + Q_PROPERTY(qreal xRotation READ xRotation WRITE setXRotation NOTIFY xRotationChanged) + Q_PROPERTY(qreal yRotation READ yRotation WRITE setYRotation NOTIFY yRotationChanged) + Q_PROPERTY(qreal minXRotation READ minXRotation NOTIFY minXRotationChanged) + Q_PROPERTY(qreal minYRotation READ minYRotation NOTIFY minYRotationChanged) + Q_PROPERTY(qreal maxXRotation READ maxXRotation NOTIFY maxXRotationChanged) + Q_PROPERTY(qreal maxYRotation READ maxYRotation NOTIFY maxYRotationChanged) + Q_PROPERTY(int zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged) + Q_PROPERTY(QMatrix4x4 viewMatrix READ viewMatrix WRITE setViewMatrix NOTIFY viewMatrixChanged) + Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset NOTIFY cameraPresetChanged) + Q_PROPERTY(bool viewMatrixAutoUpdateEnabled READ isViewMatrixAutoUpdateEnabled WRITE setViewMatrixAutoUpdateEnabled NOTIFY viewMatrixAutoUpdateChanged) + Q_PROPERTY(bool wrapXRotation READ wrapXRotation WRITE setWrapXRotation NOTIFY wrapXRotationChanged ) + Q_PROPERTY(bool wrapYRotation READ wrapYRotation WRITE setWrapYRotation NOTIFY wrapYRotationChanged ) + Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset) public: Q3DCamera(QObject *parent = 0); virtual ~Q3DCamera(); - void copyValuesFrom(const Q3DCamera &source); - - virtual QPointF rotations() const; - virtual void setRotations(const QPointF &rotation); + qreal xRotation() const; + void setXRotation(qreal rotation); + qreal yRotation() const; + void setYRotation(qreal rotation); - virtual QMatrix4x4 viewMatrix() const; - virtual void setViewMatrix(const QMatrix4x4 &viewMatrix); + qreal minXRotation() const; + qreal maxXRotation() const; - virtual bool isViewMatrixAutoUpdateEnabled(); - virtual void setViewMatrixAutoUpdateEnabled(bool isEnabled); + qreal minYRotation() const; + qreal maxYRotation() const; - virtual QDataVis::CameraPreset cameraPreset(); - virtual void setCameraPreset(QDataVis::CameraPreset preset); + bool wrapXRotation() const; + void setWrapXRotation(bool isEnabled); - virtual int zoomLevel(); - virtual void setZoomLevel(int zoomLevel); + bool wrapYRotation() const; + void setWrapYRotation(bool isEnabled); - virtual void setBaseOrientation(const QVector3D &defaultPosition, - const QVector3D &defaultTarget, - const QVector3D &defaultUp); + void copyValuesFrom(const Q3DCamera &source); - virtual QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition, - qreal fixedRotation, - qreal distanceModifier) const; + QMatrix4x4 viewMatrix() const; + void setViewMatrix(const QMatrix4x4 &viewMatrix); + + bool isViewMatrixAutoUpdateEnabled(); + void setViewMatrixAutoUpdateEnabled(bool isEnabled); + + QDataVis::CameraPreset cameraPreset(); + void setCameraPreset(QDataVis::CameraPreset preset); + + int zoomLevel(); + void setZoomLevel(int zoomLevel); + + void setBaseOrientation(const QVector3D &defaultPosition, + const QVector3D &defaultTarget, + const QVector3D &defaultUp); + + QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition, + qreal fixedRotation, + qreal distanceModifier) const; + void setCameraPosition(qreal horizontal, qreal vertical, qreal distance = 100.0); + +signals: + void xRotationChanged(qreal rotation); + void yRotationChanged(qreal rotation); + void minXRotationChanged(qreal rotation); + void minYRotationChanged(qreal rotation); + void maxXRotationChanged(qreal rotation); + void maxYRotationChanged(qreal rotation); + void zoomLevelChanged(int zoomLevel); + void viewMatrixChanged(QMatrix4x4 viewMatrix); + void cameraPresetChanged(QDataVis::CameraPreset preset); + void viewMatrixAutoUpdateChanged(bool enabled); + void wrapXRotationChanged(bool isEnabled); + void wrapYRotationChanged(bool isEnabled); + +protected: + void setMinXRotation(qreal rotation); + void setMinYRotation(qreal rotation); + void setMaxXRotation(qreal rotation); + void setMaxYRotation(qreal rotation); private: QScopedPointer<Q3DCameraPrivate> d_ptr; diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h index 8c160d8c..e0528dcc 100644 --- a/src/datavisualization/engine/q3dcamera_p.h +++ b/src/datavisualization/engine/q3dcamera_p.h @@ -44,7 +44,12 @@ public: void sync(Q3DCamera &other); - void setRotations(const QPointF &rotation); + void setXRotation(qreal rotation); + void setYRotation(qreal rotation); + void setMinXRotation(qreal rotation); + void setMinYRotation(qreal rotation); + void setMaxXRotation(qreal rotation); + void setMaxYRotation(qreal rotation); void updateViewMatrix(qreal zoomAdjustment); @@ -59,6 +64,12 @@ public: GLfloat m_xRotation; GLfloat m_yRotation; + GLfloat m_minXRotation; + GLfloat m_minYRotation; + GLfloat m_maxXRotation; + GLfloat m_maxYRotation; + bool m_wrapXRotation; + bool m_wrapYRotation; int m_zoomLevel; QDataVis::CameraPreset m_activePreset; diff --git a/src/datavisualization/engine/q3dobject.cpp b/src/datavisualization/engine/q3dobject.cpp index 55583b5b..ae13af7d 100644 --- a/src/datavisualization/engine/q3dobject.cpp +++ b/src/datavisualization/engine/q3dobject.cpp @@ -86,6 +86,7 @@ void Q3DObject::setPosition(const QVector3D &position) if (d_ptr->m_position != position) { d_ptr->m_position = position; setDirty(true); + emit positionChanged(d_ptr->m_position); } } diff --git a/src/datavisualization/engine/q3dobject.h b/src/datavisualization/engine/q3dobject.h index db8ec68b..930bb022 100644 --- a/src/datavisualization/engine/q3dobject.h +++ b/src/datavisualization/engine/q3dobject.h @@ -20,19 +20,19 @@ #define Q3DOBJECT_H #include <QtDataVisualization/qdatavisualizationenums.h> +#include <QtDataVisualization/q3dscene.h> + #include <QObject> #include <QVector3D> QT_DATAVISUALIZATION_BEGIN_NAMESPACE - -class Q3DScene; class Q3DObjectPrivate; class Q3DObject : public QObject { Q_OBJECT Q_PROPERTY(Q3DScene* parentScene READ parentScene) - Q_PROPERTY(QVector3D position READ position WRITE setPosition) + Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged) public: Q3DObject(QObject *parent = 0); @@ -40,10 +40,13 @@ public: void copyValuesFrom(const Q3DObject &source); - virtual Q3DScene *parentScene(); + Q3DScene *parentScene(); + + QVector3D position() const; + void setPosition(const QVector3D &position); - virtual QVector3D position() const; - virtual void setPosition(const QVector3D &position); +signals: + void positionChanged(QVector3D position); protected: void setDirty(bool dirty); diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp index 55e353bf..a5053bf3 100644 --- a/src/datavisualization/engine/q3dscatter.cpp +++ b/src/datavisualization/engine/q3dscatter.cpp @@ -21,9 +21,9 @@ #include "scatter3dcontroller_p.h" #include "q3dvalueaxis.h" #include "qscatterdataproxy.h" +#include "q3dcamera.h" #include <QMouseEvent> - #include <QDebug> QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -189,31 +189,6 @@ void Q3DScatter::setObjectType(QDataVis::MeshStyle style, bool smooth) } /*! - * \property Q3DScatter::cameraPreset - * - * The \a preset position of the camera. The position can be one of \c QDataVis::CameraPreset. - */ -void Q3DScatter::setCameraPreset(QDataVis::CameraPreset preset) -{ - d_ptr->m_shared->setCameraPreset(preset); -} - -QDataVis::CameraPreset Q3DScatter::cameraPreset() const -{ - return d_ptr->m_shared->cameraPreset(); -} - -/*! - * Move camera to a wanted position based on \a horizontal and \a vertical angles. Angles are limited - * to -180...180 in horizontal direction and -90...90 in vertical. \a distance is adjustable - * between 10 and 500, being \c 100 by default. - */ -void Q3DScatter::setCameraPosition(qreal horizontal, qreal vertical, int distance) -{ - d_ptr->m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance)); -} - -/*! * Sets a predefined \a theme from \c QDataVis::Theme. It is preset to \c QDataVis::ThemeQt by * default. Theme affects bar colors, label colors, text color, background color, window color and * grid color. Lighting is also adjusted by themes. @@ -302,6 +277,16 @@ QFont Q3DScatter::font() const } /*! + * \property Q3DScatter::scene + * + * This property contains the read only Q3DScene that can be used to access e.g. camera object. + */ +Q3DScene *Q3DScatter::scene() const +{ + return d_ptr->m_shared->scene(); +} + +/*! * \property Q3DScatter::labelStyle * * Sets label \a style to one of \c QDataVis::LabelStyle. It is preset to diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h index 137ccafb..fdea604e 100644 --- a/src/datavisualization/engine/q3dscatter.h +++ b/src/datavisualization/engine/q3dscatter.h @@ -21,6 +21,7 @@ #include <QtDataVisualization/qdatavisualizationenums.h> #include <QtDataVisualization/q3dwindow.h> +#include <QtDataVisualization/q3dscene.h> #include <QFont> QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -37,12 +38,12 @@ class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality) - Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset) Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName) 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_PROPERTY(Q3DScene* scene READ scene) Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode) Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality) Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle) @@ -54,11 +55,6 @@ public: void setObjectType(QDataVis::MeshStyle style, bool smooth = false); - void setCameraPreset(QDataVis::CameraPreset preset); - QDataVis::CameraPreset cameraPreset() const; - - void setCameraPosition(qreal horizontal, qreal vertical, int distance = 100); - void setTheme(QDataVis::Theme theme); void setObjectColor(const QColor &baseColor, bool uniform = true); @@ -73,6 +69,8 @@ public: void setFont(const QFont &font); QFont font() const; + Q3DScene *scene() const; + void setLabelStyle(QDataVis::LabelStyle style); QDataVis::LabelStyle labelStyle() const; diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp index abf41b19..b607dc4a 100644 --- a/src/datavisualization/engine/q3dscene.cpp +++ b/src/datavisualization/engine/q3dscene.cpp @@ -81,6 +81,7 @@ void Q3DScene::setViewport(const QRect &viewport) d_ptr->m_viewport.setX(0); d_ptr->m_viewport.setY(0); d_ptr->m_changeTracker.viewportChanged = true; + emit viewportChanged(viewport); } } @@ -89,10 +90,12 @@ void Q3DScene::setViewport(const QRect &viewport) */ void Q3DScene::setViewportSize(int width, int height) { - if (d_ptr->m_viewport.width() != width || d_ptr->m_viewport.height() != height) { + if (d_ptr->m_viewport.width() != width + || d_ptr->m_viewport.height() != height) { d_ptr->m_viewport.setWidth(width); d_ptr->m_viewport.setHeight(height); d_ptr->m_changeTracker.viewportChanged = true; + emit viewportChanged(d_ptr->m_viewport); } } @@ -112,6 +115,7 @@ void Q3DScene::setPrimarySubViewport(const QRect &primarySubViewport) if (d_ptr->m_primarySubViewport != primarySubViewport) { d_ptr->m_primarySubViewport = primarySubViewport; d_ptr->m_changeTracker.primarySubViewportChanged = true; + emit primarySubViewportChanged(primarySubViewport); } } @@ -169,6 +173,7 @@ void Q3DScene::setSecondarySubViewport(const QRect &secondarySubViewport) if (d_ptr->m_secondarySubViewport != secondarySubViewport) { d_ptr->m_secondarySubViewport = secondarySubViewport; d_ptr->m_changeTracker.secondarySubViewportChanged = true; + emit secondarySubViewportChanged(secondarySubViewport); } } @@ -188,6 +193,7 @@ void Q3DScene::setSlicingActive(bool isSlicing) if (d_ptr->m_isSlicingActive != isSlicing) { d_ptr->m_isSlicingActive = isSlicing; d_ptr->m_changeTracker.slicingActivatedChanged = true; + emit slicingActiveChanged(isSlicing); } } @@ -213,6 +219,7 @@ void Q3DScene::setActiveCamera(Q3DCamera *camera) if (camera != d_ptr->m_camera) { d_ptr->m_camera = camera; d_ptr->m_changeTracker.cameraChanged = true; + emit activeCameraChanged(camera); } } @@ -238,6 +245,7 @@ void Q3DScene::setActiveLight(Q3DLight *light) if (light != d_ptr->m_light) { d_ptr->m_light = light; d_ptr->m_changeTracker.lightChanged = true; + emit activeLightChanged(light); } } @@ -254,10 +262,12 @@ qreal Q3DScene::devicePixelRatio() const void Q3DScene::setDevicePixelRatio(qreal pixelRatio) { - d_ptr->m_devicePixelRatio = pixelRatio; + if (d_ptr->m_devicePixelRatio != pixelRatio) { + d_ptr->m_devicePixelRatio = pixelRatio; + emit devicePixelRatioChanged(pixelRatio); + } } - /*! * Calculates and sets the light position relative to the currently active camera using the given parameters. * \a relativePosition defines the relative 3D offset to the current camera position. @@ -273,20 +283,6 @@ void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePositio distanceModifier)); } -bool Q3DScene::isUnderSideCameraEnabled() const -{ - return d_ptr->m_isUnderSideCameraEnabled; -} - -void Q3DScene::setUnderSideCameraEnabled(bool isEnabled) -{ - if (d_ptr->m_isUnderSideCameraEnabled != isEnabled) { - d_ptr->m_isUnderSideCameraEnabled = isEnabled; - d_ptr->m_changeTracker.underSideCameraEnabledChanged = true; - } -} - - Q3DScenePrivate::Q3DScenePrivate(Q3DScene *q) : q_ptr(q), m_devicePixelRatio(1.f), @@ -336,11 +332,6 @@ void Q3DScenePrivate::sync(Q3DScenePrivate &other) } m_light->d_ptr->sync(*other.m_light); - if (m_changeTracker.underSideCameraEnabledChanged) { - other.q_ptr->setUnderSideCameraEnabled(q_ptr->isUnderSideCameraEnabled()); - m_changeTracker.underSideCameraEnabledChanged = false; - other.m_changeTracker.underSideCameraEnabledChanged = false; - } if (m_changeTracker.slicingActivatedChanged) { other.q_ptr->setSlicingActive(q_ptr->isSlicingActive()); m_changeTracker.slicingActivatedChanged = false; diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h index 8c4f67f8..66a5aa64 100644 --- a/src/datavisualization/engine/q3dscene.h +++ b/src/datavisualization/engine/q3dscene.h @@ -33,13 +33,13 @@ class Q3DScenePrivate; class QT_DATAVISUALIZATION_EXPORT Q3DScene : public QObject { Q_OBJECT - Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) - Q_PROPERTY(QRect primarySubViewport READ primarySubViewport WRITE setPrimarySubViewport) - Q_PROPERTY(QRect secondarySubViewport READ secondarySubViewport WRITE setSecondarySubViewport) - Q_PROPERTY(bool slicingActive READ isSlicingActive WRITE setSlicingActive) - Q_PROPERTY(Q3DCamera* activeCamera READ activeCamera WRITE setActiveCamera) - Q_PROPERTY(Q3DLight* activeLight READ activeLight WRITE setActiveLight) - Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio) + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport NOTIFY viewportChanged) + Q_PROPERTY(QRect primarySubViewport READ primarySubViewport WRITE setPrimarySubViewport NOTIFY primarySubViewportChanged) + Q_PROPERTY(QRect secondarySubViewport READ secondarySubViewport WRITE setSecondarySubViewport NOTIFY secondarySubViewportChanged) + Q_PROPERTY(bool slicingActive READ isSlicingActive WRITE setSlicingActive NOTIFY slicingActiveChanged) + Q_PROPERTY(Q3DCamera* activeCamera READ activeCamera WRITE setActiveCamera NOTIFY activeCameraChanged) + Q_PROPERTY(Q3DLight* activeLight READ activeLight WRITE setActiveLight NOTIFY activeLightChanged) + Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged) public: Q3DScene(QObject *parent = 0); @@ -73,10 +73,16 @@ public: qreal fixedRotation = 0.0, qreal distanceModifier = 0.0); -private: - bool isUnderSideCameraEnabled() const; - void setUnderSideCameraEnabled(bool isEnabled); +signals: + void viewportChanged(QRect viewport); + void primarySubViewportChanged(QRect subViewport); + void secondarySubViewportChanged(QRect subViewport); + void slicingActiveChanged(bool isSlicingActive); + void activeCameraChanged(const Q3DCamera *camera); + void activeLightChanged(const Q3DLight *light); + void devicePixelRatioChanged(qreal pixelRatio); +private: QScopedPointer<Q3DScenePrivate> d_ptr; Q_DISABLE_COPY(Q3DScene) diff --git a/src/datavisualization/engine/q3dscene_p.h b/src/datavisualization/engine/q3dscene_p.h index 20a74467..b28baaae 100644 --- a/src/datavisualization/engine/q3dscene_p.h +++ b/src/datavisualization/engine/q3dscene_p.h @@ -44,7 +44,6 @@ struct Q3DSceneChangeBitField { bool secondarySubViewportChanged : 1; bool cameraChanged : 1; bool lightChanged : 1; - bool underSideCameraEnabledChanged : 1; bool slicingActivatedChanged : 1; bool devicePixelRatioChanged : 1; @@ -54,7 +53,6 @@ struct Q3DSceneChangeBitField { secondarySubViewportChanged(true), cameraChanged(true), lightChanged(true), - underSideCameraEnabledChanged(true), slicingActivatedChanged(true), devicePixelRatioChanged(true) { diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp index 8e32d5d7..7990f362 100644 --- a/src/datavisualization/engine/q3dsurface.cpp +++ b/src/datavisualization/engine/q3dsurface.cpp @@ -20,6 +20,7 @@ #include "q3dsurface_p.h" #include "q3dvalueaxis.h" #include "qsurfacedataproxy.h" +#include "q3dcamera.h" #include <QMouseEvent> @@ -239,31 +240,6 @@ QDataVis::ShadowQuality Q3DSurface::shadowQuality() const } /*! - * \property Q3DSurface::cameraPreset - * - * The \a preset position of the camera. The position can be one of \c QDataVis::CameraPreset. - */ -void Q3DSurface::setCameraPreset(QDataVis::CameraPreset preset) -{ - d_ptr->m_shared->setCameraPreset(preset); -} - -QDataVis::CameraPreset Q3DSurface::cameraPreset() const -{ - return d_ptr->m_shared->cameraPreset(); -} - -/*! - * Move camera to a wanted position based on \a horizontal and \a vertical angles. Angles are limited - * to -180...180 in horizontal direction and 0...90 in vertical. \a distance is adjustable - * between 10 and 500, being \c 100 by default. - */ -void Q3DSurface::setCameraPosition(qreal horizontal, qreal vertical, int distance) -{ - d_ptr->m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance)); -} - -/*! * \property Q3DSurface::smoothSurfaceEnabled * * Sets surface smoothing to \a enabled. It is preset to \c false by default. @@ -345,6 +321,16 @@ QFont Q3DSurface::font() const } /*! + * \property Q3DSurface::scene + * + * This property contains the read only Q3DScene that can be used to access e.g. camera object. + */ +Q3DScene *Q3DSurface::scene() const +{ + return d_ptr->m_shared->scene(); +} + +/*! * \property Q3DSurface::labelStyle * * Sets label \a style to one of \c QDataVis::LabelStyle. It is preset to diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h index 60847265..1b572a36 100644 --- a/src/datavisualization/engine/q3dsurface.h +++ b/src/datavisualization/engine/q3dsurface.h @@ -21,6 +21,7 @@ #include <QtDataVisualization/qdatavisualizationenums.h> #include <QtDataVisualization/q3dwindow.h> +#include <QtDataVisualization/q3dscene.h> #include <QFont> #include <QLinearGradient> @@ -37,13 +38,13 @@ class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle) Q_PROPERTY(QtDataVisualization::QDataVis::Theme theme READ theme WRITE setTheme) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality) - Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset) Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible) Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible) Q_PROPERTY(bool smoothSurfaceEnabled READ isSmoothSurfaceEnabled WRITE setSmoothSurfaceEnabled) Q_PROPERTY(bool surfaceGridEnabled READ isSurfaceGridEnabled WRITE setSurfaceGridEnabled) Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient) Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(Q3DScene* scene READ scene) Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode) Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality) Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle) @@ -65,11 +66,6 @@ public: void setShadowQuality(QDataVis::ShadowQuality quality); QDataVis::ShadowQuality shadowQuality() const; - void setCameraPreset(QDataVis::CameraPreset preset); - QDataVis::CameraPreset cameraPreset() const; - - void setCameraPosition(qreal horizontal, qreal vertical, int distance = 100); - void setSmoothSurfaceEnabled(bool enabled); bool isSmoothSurfaceEnabled() const; @@ -103,6 +99,8 @@ public: void setFont(const QFont &font); QFont font() const; + Q3DScene *scene() const; + void setLabelStyle(QDataVis::LabelStyle style); QDataVis::LabelStyle labelStyle() const; diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 61610e1a..a482cc42 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -176,7 +176,9 @@ void Scatter3DRenderer::updateScene(Q3DScene *scene) { // TODO: Move these to more suitable place e.g. controller should be controlling the viewports. scene->setPrimarySubViewport(m_mainViewPort); - scene->setUnderSideCameraEnabled(true); + + // TODO: See QTRD-2374 + scene->activeCamera()->setMinYRotation(-90.0f); if (m_hasHeightAdjustmentChanged) { // Set initial m_cachedScene->activeCamera() position. Also update if height adjustment has changed. diff --git a/src/datavisualization/engine/selectionpointer.cpp b/src/datavisualization/engine/selectionpointer.cpp index 8a68d792..d1a4c42a 100644 --- a/src/datavisualization/engine/selectionpointer.cpp +++ b/src/datavisualization/engine/selectionpointer.cpp @@ -166,10 +166,11 @@ void SelectionPointer::render(GLuint defaultFboHandle) modelMatrixLabel.translate(m_position + labelAlign + QVector3D(0.0f, 0.0f, zComp)); // Position the label towards the camera - QPointF camRotations = camera->rotations(); + qreal camRotationsX = camera->xRotation(); + qreal camRotationsY = camera->yRotation(); if (!m_cachedIsSlicingActivated) { - modelMatrixLabel.rotate(-camRotations.x(), 0.0f, 1.0f, 0.0f); - modelMatrixLabel.rotate(-camRotations.y(), 1.0f, 0.0f, 0.0f); + modelMatrixLabel.rotate(-camRotationsX, 0.0f, 1.0f, 0.0f); + modelMatrixLabel.rotate(-camRotationsY, 1.0f, 0.0f, 0.0f); } // Scale label based on text size diff --git a/src/datavisualization/input/q3dinputhandler.cpp b/src/datavisualization/input/q3dinputhandler.cpp index f6e73a7d..5267568c 100644 --- a/src/datavisualization/input/q3dinputhandler.cpp +++ b/src/datavisualization/input/q3dinputhandler.cpp @@ -142,9 +142,8 @@ void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) #else if (QDataVis::InputStateRotating == inputState()) { // Calculate mouse movement since last frame - QPointF rotations = scene()->activeCamera()->rotations(); - float xRotation = rotations.x(); - float yRotation = rotations.y(); + qreal xRotation = scene()->activeCamera()->xRotation(); + qreal yRotation = scene()->activeCamera()->yRotation(); float mouseMoveX = float(inputPosition().x() - mousePos.x()) / (scene()->viewport().width() / rotationSpeed); float mouseMoveY = float(inputPosition().y() - mousePos.y()) @@ -152,7 +151,8 @@ void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) // Apply to rotations xRotation -= mouseMoveX; yRotation -= mouseMoveY; - scene()->activeCamera()->setRotations(QPointF(xRotation, yRotation)); + scene()->activeCamera()->setXRotation(xRotation); + scene()->activeCamera()->setYRotation(yRotation); scene()->activeCamera()->d_ptr->updateViewMatrix(1.0f); setPreviousInputPos(inputPosition()); diff --git a/src/datavisualization/input/qtouch3dinputhandler.cpp b/src/datavisualization/input/qtouch3dinputhandler.cpp index b0eabd34..fd079e88 100644 --- a/src/datavisualization/input/qtouch3dinputhandler.cpp +++ b/src/datavisualization/input/qtouch3dinputhandler.cpp @@ -188,9 +188,8 @@ void QTouch3DInputHandlerPrivate::handleRotation(const QPointF &position) if (QDataVis::InputStateRotating == q_ptr->inputState()) { Q3DScene *scene = q_ptr->scene(); Q3DCamera *camera = scene->activeCamera(); - QPointF rotations = camera->rotations(); - float xRotation = rotations.x(); - float yRotation = rotations.y(); + float xRotation = camera->xRotation(); + float yRotation = camera->yRotation(); QPointF inputPos = q_ptr->inputPosition(); float mouseMoveX = float(inputPos.x() - position.x()) / (scene->viewport().width() / rotationSpeed); @@ -198,7 +197,8 @@ void QTouch3DInputHandlerPrivate::handleRotation(const QPointF &position) / (scene->viewport().height() / rotationSpeed); xRotation -= mouseMoveX; yRotation -= mouseMoveY; - camera->setRotations(QPointF(xRotation, yRotation)); + camera->setXRotation(xRotation); + camera->setYRotation(yRotation); camera->d_ptr->updateViewMatrix(1.0f); q_ptr->setPreviousInputPos(inputPos.toPoint()); diff --git a/src/datavisualization/utils/utils.cpp b/src/datavisualization/utils/utils.cpp index 629f525f..da7e94f5 100644 --- a/src/datavisualization/utils/utils.cpp +++ b/src/datavisualization/utils/utils.cpp @@ -239,4 +239,25 @@ QString Utils::defaultLabelFormat() return defaultFormat; } +qreal Utils::wrapValue(qreal value, qreal min, qreal max) +{ + if (value > max) { + value = min + (value - max); + + // In case single wrap fails, jump to opposite end. + if (value > max) + value = min; + } + + if (value < min) { + value = max + (value - min); + + // In case single wrap fails, jump to opposite end. + if (value < min) + value = max; + } + + return value; +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/utils/utils_p.h b/src/datavisualization/utils/utils_p.h index 6ebd16de..e74b590d 100644 --- a/src/datavisualization/utils/utils_p.h +++ b/src/datavisualization/utils/utils_p.h @@ -68,6 +68,8 @@ public: static QString formatLabel(const QByteArray &format, ParamType paramType, qreal value); static QString defaultLabelFormat(); + static qreal wrapValue(qreal value, qreal min, qreal max); + private: static ParamType mapFormatCharToParamType(const QChar &formatChar); }; diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp index cbee6376..e853ff9c 100644 --- a/src/datavisualizationqml2/abstractdeclarative.cpp +++ b/src/datavisualizationqml2/abstractdeclarative.cpp @@ -31,19 +31,9 @@ AbstractDeclarative::~AbstractDeclarative() { } -void AbstractDeclarative::setCameraPosition(qreal horizontal, qreal vertical, int distance) +Q3DScene* AbstractDeclarative::scene() const { - m_controller->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance)); -} - -void AbstractDeclarative::setCameraPreset(QDataVis::CameraPreset preset) -{ - m_controller->setCameraPreset(preset); -} - -QDataVis::CameraPreset AbstractDeclarative::cameraPreset() const -{ - return m_controller->cameraPreset(); + return m_controller->scene(); } void AbstractDeclarative::setTheme(QDataVis::Theme theme) @@ -133,6 +123,20 @@ void AbstractDeclarative::setSharedController(Abstract3DController *controller) m_controller = controller; QObject::connect(m_controller, &Abstract3DController::shadowQualityChanged, this, &AbstractDeclarative::handleShadowQualityUpdate); + emit sceneChanged(m_controller->scene()); + QObject::connect(m_controller, &Abstract3DController::activeInputHandlerChanged, this, + &AbstractDeclarative::handleInputHandlerUpdate); + emit inputHandlerChanged(m_controller->activeInputHandler()); +} + +QAbstract3DInputHandler* AbstractDeclarative::inputHandler() const +{ + return m_controller->activeInputHandler(); +} + +void AbstractDeclarative::setInputHandler(QAbstract3DInputHandler *inputHandler) +{ + m_controller->setActiveInputHandler(inputHandler); } void AbstractDeclarative::mouseDoubleClickEvent(QMouseEvent *event) @@ -177,4 +181,9 @@ void AbstractDeclarative::handleShadowQualityUpdate(QDataVis::ShadowQuality qual emit shadowQualityChanged(quality); } +void AbstractDeclarative::handleInputHandlerUpdate(QAbstract3DInputHandler *inputHandler) +{ + emit inputHandlerChanged(inputHandler); +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h index 30789126..41d4a4da 100644 --- a/src/datavisualizationqml2/abstractdeclarative_p.h +++ b/src/datavisualizationqml2/abstractdeclarative_p.h @@ -31,6 +31,7 @@ #include "datavisualizationglobal_p.h" #include "abstract3dcontroller_p.h" +#include "qabstract3dinputhandler.h" #include <QAbstractItemModel> #include <QQuickItem> @@ -44,26 +45,27 @@ class AbstractDeclarative : public QQuickItem Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality) - Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset) + Q_PROPERTY(Q3DScene* scene READ scene NOTIFY sceneChanged) + Q_PROPERTY(QAbstract3DInputHandler* inputHandler READ inputHandler WRITE setInputHandler NOTIFY inputHandlerChanged) Q_PROPERTY(QtDataVisualization::QDataVis::Theme theme READ theme WRITE setTheme) 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(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat) Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode) Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality) Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle) Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset) Q_ENUMS(QtDataVisualization::QDataVis::Theme) - Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat) public: explicit AbstractDeclarative(QQuickItem *parent = 0); virtual ~AbstractDeclarative(); - Q_INVOKABLE void setCameraPosition(qreal horizontal, qreal vertical, int distance); + virtual Q3DScene *scene() const; - virtual void setCameraPreset(QDataVis::CameraPreset preset); - virtual QDataVis::CameraPreset cameraPreset() const; + virtual QAbstract3DInputHandler *inputHandler() const; + virtual void setInputHandler(QAbstract3DInputHandler *inputHandler); virtual void setTheme(QDataVis::Theme theme); virtual QDataVis::Theme theme() const; @@ -101,10 +103,12 @@ protected: // Used to detect when shadow quality changes autonomously due to e.g. resizing. virtual void handleShadowQualityUpdate(QDataVis::ShadowQuality quality); - + virtual void handleInputHandlerUpdate(QAbstract3DInputHandler *inputHandler); signals: // Signals shadow quality changes. void shadowQualityChanged(QDataVis::ShadowQuality quality); + void sceneChanged(Q3DScene *scene); + void inputHandlerChanged(QAbstract3DInputHandler *inputHandler); private: Abstract3DController *m_controller; diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp index 10fc7f4c..b98f72ac 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp @@ -41,6 +41,8 @@ void Datavis3Dqml2Plugin::registerTypes(const char *uri) QLatin1String("Trying to create uncreatable: SurfaceDataProxy.")); qmlRegisterUncreatableType<AbstractDeclarative>(uri, 1, 0, "AbstractGraph3D", QLatin1String("Trying to create uncreatable: AbstractGraph3D.")); + qmlRegisterUncreatableType<Q3DScene>(uri, 1, 0, "Scene3D", + QLatin1String("Trying to create uncreatable: Scene3D.")); qmlRegisterType<QItemModelBarDataMapping>(uri, 1, 0, "BarDataMapping"); qmlRegisterType<QItemModelScatterDataMapping>(uri, 1, 0, "ScatterDataMapping"); @@ -53,6 +55,8 @@ void Datavis3Dqml2Plugin::registerTypes(const char *uri) qmlRegisterType<Q3DValueAxis>(uri, 1, 0, "ValueAxis3D"); qmlRegisterType<Q3DCategoryAxis>(uri, 1, 0, "CategoryAxis3D"); + qmlRegisterType<Q3DCamera>(uri, 1, 0, "Camera3D"); + qmlRegisterType<QItemModelBarDataProxy>(uri, 1, 0, "ItemModelBarDataProxy"); qmlRegisterType<QItemModelScatterDataProxy>(uri, 1, 0, "ItemModelScatterDataProxy"); qmlRegisterType<QItemModelSurfaceDataProxy>(uri, 1, 0, "ItemModelSurfaceDataProxy"); @@ -60,7 +64,6 @@ void Datavis3Dqml2Plugin::registerTypes(const char *uri) qmlRegisterType<ColorGradientStop>(uri, 1, 0, "ColorGradientStop"); qmlRegisterType<ColorGradient>(uri, 1, 0, "ColorGradient"); - } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.h b/src/datavisualizationqml2/datavisualizationqml2_plugin.h index 66b5cb61..c0d7c4b8 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.h +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.h @@ -32,6 +32,9 @@ #include "qheightmapsurfacedataproxy.h" #include "q3dvalueaxis.h" #include "q3dcategoryaxis.h" +#include "q3dobject.h" +#include "q3dcamera.h" +#include "q3dscene.h" #include <QQmlExtensionPlugin> @@ -53,6 +56,9 @@ QML_DECLARE_TYPE(Q3DAbstractAxis) QML_DECLARE_TYPE(Q3DCategoryAxis) QML_DECLARE_TYPE(Q3DValueAxis) +QML_DECLARE_TYPE(Q3DScene) +QML_DECLARE_TYPE(Q3DCamera) + QML_DECLARE_TYPE(QAbstractDataProxy) QML_DECLARE_TYPE(QBarDataProxy) QML_DECLARE_TYPE(QItemModelBarDataProxy) diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp index c1599b18..ad27d83c 100644 --- a/tests/barstest/chart.cpp +++ b/tests/barstest/chart.cpp @@ -20,6 +20,8 @@ #include <QtDataVisualization/q3dcategoryaxis.h> #include <QtDataVisualization/q3dvalueaxis.h> #include <QtDataVisualization/qbardataproxy.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <QTime> QT_DATAVISUALIZATION_USE_NAMESPACE @@ -445,7 +447,7 @@ void GraphModifier::changePresetCamera() { static int preset = QDataVis::CameraPresetFrontLow; - m_chart->setCameraPreset((QDataVis::CameraPreset)preset); + m_chart->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset); if (++preset > QDataVis::CameraPresetDirectlyBelow) preset = QDataVis::CameraPresetFrontLow; @@ -529,13 +531,13 @@ void GraphModifier::setGridEnabled(int enabled) void GraphModifier::rotateX(int rotation) { m_xRotation = rotation; - m_chart->setCameraPosition(m_xRotation, m_yRotation); + m_chart->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); } void GraphModifier::rotateY(int rotation) { m_yRotation = rotation; - m_chart->setCameraPosition(m_xRotation, m_yRotation); + m_chart->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); } void GraphModifier::setSpecsRatio(int barwidth) diff --git a/tests/qmlcamera/main.cpp b/tests/qmlcamera/main.cpp new file mode 100644 index 00000000..90d81eab --- /dev/null +++ b/tests/qmlcamera/main.cpp @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include <QtGui/QGuiApplication> +#include "qtquick2applicationviewer.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QtQuick2ApplicationViewer viewer; +#ifdef Q_OS_ANDROID + viewer.addImportPath(QString::fromLatin1("assets:/qml")); + viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(), + QString::fromLatin1("lib"))); +#else + viewer.addImportPath(QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), + QString::fromLatin1("qml"))); +#endif + viewer.setMainQmlFile(QStringLiteral("qml/qmlcamera/main.qml")); + viewer.setResizeMode(QQuickView::SizeRootObjectToView); + viewer.showExpanded(); + + return app.exec(); +} diff --git a/tests/qmlcamera/qml/qmlcamera/Axes.qml b/tests/qmlcamera/qml/qmlcamera/Axes.qml new file mode 100644 index 00000000..b0ba3eb2 --- /dev/null +++ b/tests/qmlcamera/qml/qmlcamera/Axes.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +import QtQuick 2.1 +import com.digia.QtDataVisualization 1.0 + +Item { + property alias column: columnAxis + property alias expenses: expensesAxis + property alias income: incomeAxis + + // For row labels we can use row labels from data proxy, so default axis + // suffices for rows. + + // Custom labels for columns, since the data contains abbreviated month names. + CategoryAxis3D { + id: columnAxis + categoryLabels: ["January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"] + } + ValueAxis3D { + id: incomeAxis + min: 0 + max: 35 + labelFormat: "%.2f M\u20AC" + title: "Monthly income" + } + ValueAxis3D { + id: expensesAxis + min: 0 + max: 35 + labelFormat: "-%.2f M\u20AC" + title: "Monthly expenses" + } +} diff --git a/tests/qmlcamera/qml/qmlcamera/ControlSurface.qml b/tests/qmlcamera/qml/qmlcamera/ControlSurface.qml new file mode 100644 index 00000000..c655e016 --- /dev/null +++ b/tests/qmlcamera/qml/qmlcamera/ControlSurface.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: controlRect + color: "#000000" + property real xValue : 0 + property real yValue : 0 + property real minXValue : 0 + property real minYValue : 0 + property real maxXValue : 0 + property real maxYValue : 0 + + property real halfWidth: width / 2.0; + property real halfHeight: height / 2.0; + + Rectangle { + id: pointer + color: "#FFFFFF" + width: 5 + height: 5 + } + + MouseArea { + id: inputArea + anchors.fill: parent + onPositionChanged: { + pointer.x = Math.min(Math.max(0, mouse.x), controlRect.width - pointer.width ); + pointer.y = Math.min(Math.max(0, mouse.y), controlRect.height - pointer.height); + var mixX = (mouse.x / controlRect.width); + var mixY = (mouse.y / controlRect.width); + controlRect.xValue = minXValue*(1-mixX) + maxXValue*mixX; + controlRect.yValue = minYValue*(1-mixY) + maxYValue*mixY; + } + } +} diff --git a/tests/qmlcamera/qml/qmlcamera/Data.qml b/tests/qmlcamera/qml/qmlcamera/Data.qml new file mode 100644 index 00000000..fff568cc --- /dev/null +++ b/tests/qmlcamera/qml/qmlcamera/Data.qml @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +import QtQuick 2.1 +import com.digia.QtDataVisualization 1.0 + +Item { + property alias mapping: valueMapping + property alias model: dataModel + property alias proxy: modelProxy + + BarDataMapping { + id: valueMapping + rowRole: "year" + columnRole: "month" + valueRole: "expenses" + } + + ItemModelBarDataProxy { + id: modelProxy + activeMapping: valueMapping + itemModel: dataModel + } + + ListModel { + id: dataModel + ListElement{ year: "2006"; month: "Jan"; expenses: "4"; income: "5" } + ListElement{ year: "2006"; month: "Feb"; expenses: "5"; income: "6" } + ListElement{ year: "2006"; month: "Mar"; expenses: "7"; income: "4" } + ListElement{ year: "2006"; month: "Apr"; expenses: "3"; income: "2" } + ListElement{ year: "2006"; month: "May"; expenses: "4"; income: "1" } + ListElement{ year: "2006"; month: "Jun"; expenses: "2"; income: "2" } + ListElement{ year: "2006"; month: "Jul"; expenses: "1"; income: "3" } + ListElement{ year: "2006"; month: "Aug"; expenses: "5"; income: "1" } + ListElement{ year: "2006"; month: "Sep"; expenses: "2"; income: "3" } + ListElement{ year: "2006"; month: "Oct"; expenses: "5"; income: "2" } + ListElement{ year: "2006"; month: "Nov"; expenses: "8"; income: "5" } + ListElement{ year: "2006"; month: "Dec"; expenses: "3"; income: "3" } + + ListElement{ year: "2007"; month: "Jan"; expenses: "3"; income: "1" } + ListElement{ year: "2007"; month: "Feb"; expenses: "4"; income: "2" } + ListElement{ year: "2007"; month: "Mar"; expenses: "12"; income: "4" } + ListElement{ year: "2007"; month: "Apr"; expenses: "13"; income: "6" } + ListElement{ year: "2007"; month: "May"; expenses: "14"; income: "11" } + ListElement{ year: "2007"; month: "Jun"; expenses: "7"; income: "7" } + ListElement{ year: "2007"; month: "Jul"; expenses: "6"; income: "4" } + ListElement{ year: "2007"; month: "Aug"; expenses: "4"; income: "15" } + ListElement{ year: "2007"; month: "Sep"; expenses: "2"; income: "18" } + ListElement{ year: "2007"; month: "Oct"; expenses: "29"; income: "25" } + ListElement{ year: "2007"; month: "Nov"; expenses: "23"; income: "29" } + ListElement{ year: "2007"; month: "Dec"; expenses: "5"; income: "9" } + + ListElement{ year: "2008"; month: "Jan"; expenses: "3"; income: "8" } + ListElement{ year: "2008"; month: "Feb"; expenses: "8"; income: "14" } + ListElement{ year: "2008"; month: "Mar"; expenses: "10"; income: "20" } + ListElement{ year: "2008"; month: "Apr"; expenses: "12"; income: "24" } + ListElement{ year: "2008"; month: "May"; expenses: "10"; income: "19" } + ListElement{ year: "2008"; month: "Jun"; expenses: "5"; income: "8" } + ListElement{ year: "2008"; month: "Jul"; expenses: "1"; income: "4" } + ListElement{ year: "2008"; month: "Aug"; expenses: "7"; income: "12" } + ListElement{ year: "2008"; month: "Sep"; expenses: "4"; income: "16" } + ListElement{ year: "2008"; month: "Oct"; expenses: "22"; income: "33" } + ListElement{ year: "2008"; month: "Nov"; expenses: "16"; income: "25" } + ListElement{ year: "2008"; month: "Dec"; expenses: "2"; income: "7" } + + ListElement{ year: "2009"; month: "Jan"; expenses: "4"; income: "5" } + ListElement{ year: "2009"; month: "Feb"; expenses: "4"; income: "7" } + ListElement{ year: "2009"; month: "Mar"; expenses: "11"; income: "14" } + ListElement{ year: "2009"; month: "Apr"; expenses: "16"; income: "22" } + ListElement{ year: "2009"; month: "May"; expenses: "3"; income: "5" } + ListElement{ year: "2009"; month: "Jun"; expenses: "4"; income: "8" } + ListElement{ year: "2009"; month: "Jul"; expenses: "7"; income: "9" } + ListElement{ year: "2009"; month: "Aug"; expenses: "9"; income: "13" } + ListElement{ year: "2009"; month: "Sep"; expenses: "1"; income: "6" } + ListElement{ year: "2009"; month: "Oct"; expenses: "14"; income: "25" } + ListElement{ year: "2009"; month: "Nov"; expenses: "19"; income: "29" } + ListElement{ year: "2009"; month: "Dec"; expenses: "5"; income: "7" } + + ListElement{ year: "2010"; month: "Jan"; expenses: "14"; income: "22" } + ListElement{ year: "2010"; month: "Feb"; expenses: "5"; income: "7" } + ListElement{ year: "2010"; month: "Mar"; expenses: "1"; income: "9" } + ListElement{ year: "2010"; month: "Apr"; expenses: "1"; income: "12" } + ListElement{ year: "2010"; month: "May"; expenses: "5"; income: "9" } + ListElement{ year: "2010"; month: "Jun"; expenses: "5"; income: "8" } + ListElement{ year: "2010"; month: "Jul"; expenses: "3"; income: "7" } + ListElement{ year: "2010"; month: "Aug"; expenses: "1"; income: "5" } + ListElement{ year: "2010"; month: "Sep"; expenses: "2"; income: "4" } + ListElement{ year: "2010"; month: "Oct"; expenses: "10"; income: "13" } + ListElement{ year: "2010"; month: "Nov"; expenses: "12"; income: "17" } + ListElement{ year: "2010"; month: "Dec"; expenses: "6"; income: "9" } + + ListElement{ year: "2011"; month: "Jan"; expenses: "2"; income: "6" } + ListElement{ year: "2011"; month: "Feb"; expenses: "4"; income: "8" } + ListElement{ year: "2011"; month: "Mar"; expenses: "7"; income: "12" } + ListElement{ year: "2011"; month: "Apr"; expenses: "9"; income: "15" } + ListElement{ year: "2011"; month: "May"; expenses: "7"; income: "19" } + ListElement{ year: "2011"; month: "Jun"; expenses: "9"; income: "18" } + ListElement{ year: "2011"; month: "Jul"; expenses: "13"; income: "17" } + ListElement{ year: "2011"; month: "Aug"; expenses: "5"; income: "9" } + ListElement{ year: "2011"; month: "Sep"; expenses: "3"; income: "8" } + ListElement{ year: "2011"; month: "Oct"; expenses: "13"; income: "15" } + ListElement{ year: "2011"; month: "Nov"; expenses: "8"; income: "17" } + ListElement{ year: "2011"; month: "Dec"; expenses: "7"; income: "10" } + + ListElement{ year: "2012"; month: "Jan"; expenses: "12"; income: "16" } + ListElement{ year: "2012"; month: "Feb"; expenses: "24"; income: "28" } + ListElement{ year: "2012"; month: "Mar"; expenses: "27"; income: "22" } + ListElement{ year: "2012"; month: "Apr"; expenses: "29"; income: "25" } + ListElement{ year: "2012"; month: "May"; expenses: "27"; income: "29" } + ListElement{ year: "2012"; month: "Jun"; expenses: "19"; income: "18" } + ListElement{ year: "2012"; month: "Jul"; expenses: "13"; income: "17" } + ListElement{ year: "2012"; month: "Aug"; expenses: "15"; income: "19" } + ListElement{ year: "2012"; month: "Sep"; expenses: "3"; income: "8" } + ListElement{ year: "2012"; month: "Oct"; expenses: "3"; income: "6" } + ListElement{ year: "2012"; month: "Nov"; expenses: "4"; income: "8" } + ListElement{ year: "2012"; month: "Dec"; expenses: "5"; income: "9" } + } +} diff --git a/tests/qmlcamera/qml/qmlcamera/main.qml b/tests/qmlcamera/qml/qmlcamera/main.qml new file mode 100644 index 00000000..0518c1c8 --- /dev/null +++ b/tests/qmlcamera/qml/qmlcamera/main.qml @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.0 +import com.digia.QtDataVisualization 1.0 +import "." + +Item { + id: mainview + width: 1280 + height: 1024 + visible: true + + Data { + id: chartData + } + + Axes { + id: chartAxes + } + + Item { + id: dataView + width: parent.width - camControlArea.width + height: parent.height + anchors.right: parent.right; + + Bars3D { + id: testChart + width: dataView.width + height: dataView.height + shadowQuality: Bars3D.ShadowQualityMedium + selectionMode: Bars3D.SelectionModeItem + font.pointSize: 35 + theme: Bars3D.ThemeRetro + labelStyle: Bars3D.LabelStyleFromTheme + dataProxy: chartData.proxy + barThickness: 0.5 + barSpacing: Qt.size(0.5, 0.5) + barSpacingRelative: false + + columnAxis: chartAxes.column + valueAxis: chartAxes.expenses + itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel" + + onSelectedBarPosChanged: { + // Set camControlArea current row to selected bar + var rowRole = chartData.proxy.rowLabels[position.x]; + var colRole = chartData.proxy.columnLabels[position.y]; + } + + // Bind UI controls to the camera + scene.activeCamera.wrapXRotation: false + scene.activeCamera.xRotation: camControlArea.xValue + scene.activeCamera.yRotation: camControlArea.yValue + scene.activeCamera.zoomLevel: zoomSlider.value + inputHandler: null + } + } + + ControlSurface { + id: camControlArea + x: 0 + y: 0 + width: 298 + height: 298 + minXValue: testChart.scene.activeCamera.minXRotation + minYValue: testChart.scene.activeCamera.minYRotation + maxXValue: testChart.scene.activeCamera.maxYRotation + maxYValue: testChart.scene.activeCamera.maxYRotation + } + + Slider { + id: zoomSlider + width: camControlArea.width + anchors.top: camControlArea.bottom + value: 100 + minimumValue: 10 + maximumValue: 300 + } + + Button { + id: mappingToggle + anchors.bottom: parent.bottom + width: camControlArea.width + text: "Show Income" + onClicked: { + if (chartData.mapping.valueRole === "expenses") { + chartData.mapping.valueRole = "income" + text = "Show Expenses" + testChart.valueAxis = chartAxes.income + } else { + chartData.mapping.valueRole = "expenses" + text = "Show Income" + testChart.valueAxis = chartAxes.expenses + } + } + } + + Button { + id: shadowToggle + anchors.bottom: mappingToggle.top + width: camControlArea.width + text: "Hide Shadows" + onClicked: { + if (testChart.shadowQuality == Bars3D.ShadowQualityNone) { + testChart.shadowQuality = Bars3D.ShadowQualityMedium; + text = "Hide Shadows" + } else { + testChart.shadowQuality = Bars3D.ShadowQualityNone; + text = "Show Shadows" + } + } + } + + Button { + id: dataToggle + anchors.bottom: shadowToggle.top + width: camControlArea.width + text: "Show 2010 - 2012" + onClicked: { + if (testChart.rowAxis.max !== 6) { + text = "Show 2010 - 2012" + chartData.mapping.autoRowCategories = true + } else { + text = "Show all years" + // Explicitly defining row categories, since we do not want to show data for + // all years in the model, just for the selected ones. + chartData.mapping.autoRowCategories = false + chartData.mapping.rowCategories = ["2010", "2011", "2012"] + } + } + } +} diff --git a/tests/qmlcamera/qmlcamera.desktop b/tests/qmlcamera/qmlcamera.desktop new file mode 100644 index 00000000..10a0a2e7 --- /dev/null +++ b/tests/qmlcamera/qmlcamera.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Type=Application +Terminal=false +Name=qmlcamera +Exec=/opt/qmlcamera/bin/qmlcamera +Icon=qmlcamera64 +X-Window-Icon= +X-HildonDesk-ShowInToolbar=true +X-Osso-Type=application/x-executable diff --git a/tests/qmlcamera/qmlcamera.pro b/tests/qmlcamera/qmlcamera.pro new file mode 100644 index 00000000..bc3a6953 --- /dev/null +++ b/tests/qmlcamera/qmlcamera.pro @@ -0,0 +1,31 @@ +# Add more folders to ship with the application, here +folder_01.source = qml/qmlcamera +folder_01.target = qml +DEPLOYMENTFOLDERS = folder_01 + +# Additional import path used to resolve QML modules in Creator's code model +QML_IMPORT_PATH = + +# If your application uses the Qt Mobility libraries, uncomment the following +# lines and add the respective components to the MOBILITY variable. +# CONFIG += mobility +# MOBILITY += + +# The .cpp file which was generated for your project. Feel free to hack it. +SOURCES += main.cpp + +# Installation path +# target.path = + +# Please do not modify the following two lines. Required for deployment. +include(qtquick2applicationviewer/qtquick2applicationviewer.pri) +qtcAddDeployment() + +RESOURCES += \ + qmlcamera.qrc + +OTHER_FILES += \ + qml/qmlcamera/Data.qml \ + qml/qmlcamera/Axes.qml \ + qml/qmlcamera/main.qml \ + qml/qmlcamera/ControlSurface.qml diff --git a/tests/qmlcamera/qmlcamera.qrc b/tests/qmlcamera/qmlcamera.qrc new file mode 100644 index 00000000..d9b993c7 --- /dev/null +++ b/tests/qmlcamera/qmlcamera.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/qml"> + <file alias="main.qml">qml/qmlcamera/main.qml</file> + <file alias="Data.qml">qml/qmlcamera/Data.qml</file> + <file alias="Axes.qml">qml/qmlcamera/Axes.qml</file> + </qresource> +</RCC> diff --git a/tests/qmlcamera/qmlcamera64.png b/tests/qmlcamera/qmlcamera64.png Binary files differnew file mode 100644 index 00000000..707d5c4e --- /dev/null +++ b/tests/qmlcamera/qmlcamera64.png diff --git a/tests/qmlcamera/qmlcamera80.png b/tests/qmlcamera/qmlcamera80.png Binary files differnew file mode 100644 index 00000000..6ad8096c --- /dev/null +++ b/tests/qmlcamera/qmlcamera80.png diff --git a/tests/qmlcamera/qmlcamera_harmattan.desktop b/tests/qmlcamera/qmlcamera_harmattan.desktop new file mode 100644 index 00000000..8e9e9857 --- /dev/null +++ b/tests/qmlcamera/qmlcamera_harmattan.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Type=Application +Terminal=false +Name=qmlcamera +Exec=/usr/bin/single-instance /opt/qmlcamera/bin/qmlcamera +Icon=/usr/share/icons/hicolor/80x80/apps/qmlcamera80.png +X-Window-Icon= +X-HildonDesk-ShowInToolbar=true +X-Osso-Type=application/x-executable diff --git a/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.cpp new file mode 100644 index 00000000..10709d7a --- /dev/null +++ b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.cpp @@ -0,0 +1,81 @@ +// checksum 0x4f6f version 0x90005 +/* + This file was generated by the Qt Quick 2 Application wizard of Qt Creator. + QtQuick2ApplicationViewer is a convenience class containing mobile device specific + code such as screen orientation handling. Also QML paths and debugging are + handled here. + It is recommended not to modify this file, since newer versions of Qt Creator + may offer an updated version of it. +*/ + +#include "qtquick2applicationviewer.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> +#include <QtQml/QQmlEngine> + +class QtQuick2ApplicationViewerPrivate +{ + QString mainQmlFile; + friend class QtQuick2ApplicationViewer; + static QString adjustPath(const QString &path); +}; + +QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path) +{ +#if defined(Q_OS_MAC) + if (!QDir::isAbsolutePath(path)) + return QString::fromLatin1("%1/../Resources/%2") + .arg(QCoreApplication::applicationDirPath(), path); +#elif defined(Q_OS_BLACKBERRY) + if (!QDir::isAbsolutePath(path)) + return QString::fromLatin1("app/native/%1").arg(path); +#elif !defined(Q_OS_ANDROID) + QString pathInInstallDir = + QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path); + if (QFileInfo(pathInInstallDir).exists()) + return pathInInstallDir; + pathInInstallDir = + QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), path); + if (QFileInfo(pathInInstallDir).exists()) + return pathInInstallDir; +#endif + return path; +} + +QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent) + : QQuickView(parent) + , d(new QtQuick2ApplicationViewerPrivate()) +{ + connect(engine(), SIGNAL(quit()), SLOT(close())); + setResizeMode(QQuickView::SizeRootObjectToView); +} + +QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer() +{ + delete d; +} + +void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file) +{ + d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file); +#ifdef Q_OS_ANDROID + setSource(QUrl(QLatin1String("assets:/")+d->mainQmlFile)); +#else + setSource(QUrl::fromLocalFile(d->mainQmlFile)); +#endif +} + +void QtQuick2ApplicationViewer::addImportPath(const QString &path) +{ + engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path)); +} + +void QtQuick2ApplicationViewer::showExpanded() +{ +#if defined(Q_WS_SIMULATOR) || defined(Q_OS_QNX) + showFullScreen(); +#else + show(); +#endif +} diff --git a/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.h b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.h new file mode 100644 index 00000000..cf66f140 --- /dev/null +++ b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.h @@ -0,0 +1,33 @@ +// checksum 0xfde6 version 0x90005 +/* + This file was generated by the Qt Quick 2 Application wizard of Qt Creator. + QtQuick2ApplicationViewer is a convenience class containing mobile device specific + code such as screen orientation handling. Also QML paths and debugging are + handled here. + It is recommended not to modify this file, since newer versions of Qt Creator + may offer an updated version of it. +*/ + +#ifndef QTQUICK2APPLICATIONVIEWER_H +#define QTQUICK2APPLICATIONVIEWER_H + +#include <QtQuick/QQuickView> + +class QtQuick2ApplicationViewer : public QQuickView +{ + Q_OBJECT + +public: + explicit QtQuick2ApplicationViewer(QWindow *parent = 0); + virtual ~QtQuick2ApplicationViewer(); + + void setMainQmlFile(const QString &file); + void addImportPath(const QString &path); + + void showExpanded(); + +private: + class QtQuick2ApplicationViewerPrivate *d; +}; + +#endif // QTQUICK2APPLICATIONVIEWER_H diff --git a/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.pri b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.pri new file mode 100644 index 00000000..e5f7990f --- /dev/null +++ b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.pri @@ -0,0 +1,180 @@ +# checksum 0x7b0d version 0x90005 +# This file was generated by the Qt Quick 2 Application wizard of Qt Creator. +# The code below adds the QtQuick2ApplicationViewer to the project and handles +# the activation of QML debugging. +# It is recommended not to modify this file, since newer versions of Qt Creator +# may offer an updated version of it. + +QT += qml quick + +SOURCES += $$PWD/qtquick2applicationviewer.cpp +HEADERS += $$PWD/qtquick2applicationviewer.h +INCLUDEPATH += $$PWD +# This file was generated by an application wizard of Qt Creator. +# The code below handles deployment to Android and Maemo, aswell as copying +# of the application data to shadow build directories on desktop. +# It is recommended not to modify this file, since newer versions of Qt Creator +# may offer an updated version of it. + +defineTest(qtcAddDeployment) { +for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + greaterThan(QT_MAJOR_VERSION, 4) { + itemsources = $${item}.files + } else { + itemsources = $${item}.sources + } + $$itemsources = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath= $$eval($${deploymentfolder}.target) + export($$itemsources) + export($$itempath) + DEPLOYMENT += $$item +} + +MAINPROFILEPWD = $$PWD + +android-no-sdk { + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + target.path = /data/user/qt + + export(target.path) + INSTALLS += target +} else:android { + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = /assets/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + + export(target.path) + INSTALLS += target +} else:win32 { + copyCommand = + for(deploymentfolder, DEPLOYMENTFOLDERS) { + source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) + source = $$replace(source, /, \\) + sourcePathSegments = $$split(source, \\) + target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments) + target = $$replace(target, /, \\) + target ~= s,\\\\\\.?\\\\,\\, + !isEqual(source,$$target) { + !isEmpty(copyCommand):copyCommand += && + isEqual(QMAKE_DIR_SEP, \\) { + copyCommand += $(COPY_DIR) \"$$source\" \"$$target\" + } else { + source = $$replace(source, \\\\, /) + target = $$OUT_PWD/$$eval($${deploymentfolder}.target) + target = $$replace(target, \\\\, /) + copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\" + } + } + } + !isEmpty(copyCommand) { + copyCommand = @echo Copying application data... && $$copyCommand + copydeploymentfolders.commands = $$copyCommand + first.depends = $(first) copydeploymentfolders + export(first.depends) + export(copydeploymentfolders.commands) + QMAKE_EXTRA_TARGETS += first copydeploymentfolders + } +} else:unix { + maemo5 { + desktopfile.files = $${TARGET}.desktop + desktopfile.path = /usr/share/applications/hildon + icon.files = $${TARGET}64.png + icon.path = /usr/share/icons/hicolor/64x64/apps + } else:!isEmpty(MEEGO_VERSION_MAJOR) { + desktopfile.files = $${TARGET}_harmattan.desktop + desktopfile.path = /usr/share/applications + icon.files = $${TARGET}80.png + icon.path = /usr/share/icons/hicolor/80x80/apps + } else { # Assumed to be a Desktop Unix + copyCommand = + for(deploymentfolder, DEPLOYMENTFOLDERS) { + source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) + source = $$replace(source, \\\\, /) + macx { + target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target) + } else { + target = $$OUT_PWD/$$eval($${deploymentfolder}.target) + } + target = $$replace(target, \\\\, /) + sourcePathSegments = $$split(source, /) + targetFullPath = $$target/$$last(sourcePathSegments) + targetFullPath ~= s,/\\.?/,/, + !isEqual(source,$$targetFullPath) { + !isEmpty(copyCommand):copyCommand += && + copyCommand += $(MKDIR) \"$$target\" + copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\" + } + } + !isEmpty(copyCommand) { + copyCommand = @echo Copying application data... && $$copyCommand + copydeploymentfolders.commands = $$copyCommand + first.depends = $(first) copydeploymentfolders + export(first.depends) + export(copydeploymentfolders.commands) + QMAKE_EXTRA_TARGETS += first copydeploymentfolders + } + } + !isEmpty(target.path) { + installPrefix = $${target.path} + } else { + installPrefix = /opt/$${TARGET} + } + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + !isEmpty(desktopfile.path) { + export(icon.files) + export(icon.path) + export(desktopfile.files) + export(desktopfile.path) + INSTALLS += icon desktopfile + } + + isEmpty(target.path) { + target.path = $${installPrefix}/bin + export(target.path) + } + INSTALLS += target +} + +export (ICON) +export (INSTALLS) +export (DEPLOYMENT) +export (LIBS) +export (QMAKE_EXTRA_TARGETS) +} diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp index a10f0065..f23ee99d 100644 --- a/tests/scattertest/scatterchart.cpp +++ b/tests/scattertest/scatterchart.cpp @@ -19,6 +19,8 @@ #include "scatterchart.h" #include <QtDataVisualization/qscatterdataproxy.h> #include <QtDataVisualization/q3dvalueaxis.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <qmath.h> using namespace QtDataVisualization; @@ -37,7 +39,7 @@ ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter) m_chart->setObjectType(QDataVis::MeshStyleSpheres, true); m_chart->setTheme(QDataVis::ThemeStoneMoss); m_chart->setShadowQuality(QDataVis::ShadowQualityHigh); - m_chart->setCameraPreset(QDataVis::CameraPresetFront); + m_chart->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront); m_chart->setAxisX(new Q3DValueAxis); m_chart->setAxisY(new Q3DValueAxis); m_chart->setAxisZ(new Q3DValueAxis); @@ -117,7 +119,7 @@ void ScatterDataModifier::changePresetCamera() { static int preset = QDataVis::CameraPresetFrontLow; - m_chart->setCameraPreset((QDataVis::CameraPreset)preset); + m_chart->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset); if (++preset > QDataVis::CameraPresetDirectlyAboveCCW45) preset = QDataVis::CameraPresetFrontLow; diff --git a/tests/spectrum/spectrumapp/main.cpp b/tests/spectrum/spectrumapp/main.cpp index d0282ca0..3d2e2bf1 100644 --- a/tests/spectrum/spectrumapp/main.cpp +++ b/tests/spectrum/spectrumapp/main.cpp @@ -23,6 +23,8 @@ #include <QtDataVisualization/qbardataproxy.h> #include <QtDataVisualization/q3dvalueaxis.h> #include <QtDataVisualization/q3dcategoryaxis.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> #include <QGuiApplication> #include <QAudio> @@ -92,7 +94,7 @@ MainApp::MainApp(Q3DBars *window) // Set bar type, flat bars m_chart->setBarType(QDataVis::MeshStyleBars, false); // Adjust camera position - m_chart->setCameraPosition(10.0f, 7.5f, 75); + m_chart->scene()->activeCamera()->setCameraPosition(10.0f, 7.5f, 75); #endif // Set color scheme m_chart->setBarColor(QColor(Qt::red), false); diff --git a/tests/tests.pro b/tests/tests.pro index a9462378..30223e61 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -10,6 +10,7 @@ TEMPLATE = subdirs SUBDIRS += barstest \ scattertest \ kinectsurface \ - surfacetest + surfacetest \ + qmlcamera qtHaveModule(multimedia):!android: SUBDIRS += spectrum |