From 1b311517f8889e6faa8a1ae51af582c1cd07e739 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 4 Jul 2014 12:14:13 +0300 Subject: Exposed default input handlers to QML Also added properties to control rotation, zoom, and selection individually. Also added missing documentation about surface texture. Task-number: QTRD-3202 Change-Id: I981edb7f336aea499440559f4a2098711200206d Reviewed-by: Mika Salmela --- src/datavisualization/data/qsurface3dseries.cpp | 13 +- .../engine/abstract3dcontroller.cpp | 13 +- src/datavisualization/input/q3dinputhandler.cpp | 184 ++++++++++++++++----- src/datavisualization/input/q3dinputhandler.h | 15 ++ src/datavisualization/input/q3dinputhandler_p.h | 8 +- .../input/qtouch3dinputhandler.cpp | 122 +++++++++----- 6 files changed, 264 insertions(+), 91 deletions(-) (limited to 'src/datavisualization') diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp index bcfc4042..7d4dacfe 100644 --- a/src/datavisualization/data/qsurface3dseries.cpp +++ b/src/datavisualization/data/qsurface3dseries.cpp @@ -140,6 +140,14 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * Clearing all flags is not allowed. */ +/*! + * \qmlproperty string Surface3DSeries::textureFile + * + * Holds the texture file name for the surface texture. To clear the texture, set empty + * file name. + */ + + /*! * \enum QSurface3DSeries::DrawFlag * @@ -300,6 +308,8 @@ QSurface3DSeries::DrawFlags QSurface3DSeries::drawMode() const } /*! + * \property QSurface3DSeries::texture + * * Set the \a texture as a QImage for the surface. To clear the texture, set empty * QImage as texture. */ @@ -318,7 +328,8 @@ QImage QSurface3DSeries::texture() const return dptrc()->m_texture; } -/*! \property QSurface3DSeries::textureFile +/*! + * \property QSurface3DSeries::textureFile * * Holds the texture file name for the surface texture. To clear the texture, set empty * file name. diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 1b497490..52ab853d 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -75,10 +75,6 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen inputHandler = new QTouch3DInputHandler(); inputHandler->d_ptr->m_isDefaultHandler = true; setActiveInputHandler(inputHandler); - connect(inputHandler, &QAbstract3DInputHandler::inputViewChanged, this, - &Abstract3DController::handleInputViewChanged); - connect(inputHandler, &QAbstract3DInputHandler::positionChanged, this, - &Abstract3DController::handleInputPositionChanged); connect(m_scene->d_ptr.data(), &Q3DScenePrivate::needRender, this, &Abstract3DController::emitNeedRender); } @@ -783,8 +779,9 @@ void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputH m_inputHandlers.removeAll(m_activeInputHandler); delete m_activeInputHandler; } else { - // Disconnect the old input handler from the scene + // Disconnect the old input handler m_activeInputHandler->setScene(0); + QObject::disconnect(m_activeInputHandler, 0, this, 0); } } @@ -796,6 +793,12 @@ void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputH if (m_activeInputHandler) m_activeInputHandler->setScene(m_scene); + // Connect the input handler + QObject::connect(m_activeInputHandler, &QAbstract3DInputHandler::inputViewChanged, this, + &Abstract3DController::handleInputViewChanged); + QObject::connect(m_activeInputHandler, &QAbstract3DInputHandler::positionChanged, this, + &Abstract3DController::handleInputPositionChanged); + // Notify change of input handler emit activeInputHandlerChanged(m_activeInputHandler); } diff --git a/src/datavisualization/input/q3dinputhandler.cpp b/src/datavisualization/input/q3dinputhandler.cpp index f0044096..e6f3de24 100644 --- a/src/datavisualization/input/q3dinputhandler.cpp +++ b/src/datavisualization/input/q3dinputhandler.cpp @@ -61,6 +61,43 @@ const float rotationSpeed = 100.0f; * \li Closes the secondary view. * \note Secondary view is available only for Q3DBars and Q3DSurface graphs. * \endtable + * + * Rotation, zoom, and selection can each be individually disabled using + * corresponding properties of this class. + */ + +/*! + * \qmltype InputHandler3D + * \inqmlmodule QtDataVisualization + * \since QtDataVisualization 1.2 + * \ingroup datavisualization_qml + * \instantiates Q3DInputHandler + * \brief Basic wheel mouse based input handler. + * + * InputHandler3D is the basic input handler for wheel mouse type of input devices. + * + * See Q3DInputHandler documentation for more details. + */ + +/*! + * \qmlproperty bool InputHandler3D::rotationEnabled + * \since QtDataVisualization 1.2 + * + * This property specifies if this input handler allows graph rotation. + */ + +/*! + * \qmlproperty bool InputHandler3D::zoomEnabled + * \since QtDataVisualization 1.2 + * + * This property specifies if this input handler allows graph zooming. + */ + +/*! + * \qmlproperty bool InputHandler3D::selectionEnabled + * \since QtDataVisualization 1.2 + * + * This property specifies if this input handler allows selection from the graph. */ /*! @@ -92,29 +129,35 @@ void Q3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos Q_UNUSED(mousePos); #else if (Qt::LeftButton == event->button()) { - if (scene()->isSlicingActive()) { - if (scene()->isPointInPrimarySubView(mousePos)) + if (isSelectionEnabled()) { + if (scene()->isSlicingActive()) { + if (scene()->isPointInPrimarySubView(mousePos)) + setInputView(InputViewOnPrimary); + else if (scene()->isPointInSecondarySubView(mousePos)) + setInputView(InputViewOnSecondary); + else + setInputView(InputViewNone); + } else { + // update mouse positions to prevent jumping when releasing or repressing a button + setInputPosition(mousePos); + scene()->setSelectionQueryPosition(mousePos); setInputView(InputViewOnPrimary); - else if (scene()->isPointInSecondarySubView(mousePos)) - setInputView(InputViewOnSecondary); - else - setInputView(InputViewNone); - } else { - // update mouse positions to prevent jumping when releasing or repressing a button - setInputPosition(mousePos); - scene()->setSelectionQueryPosition(mousePos); - setInputView(InputViewOnPrimary); - d_ptr->m_inputState = QAbstract3DInputHandlerPrivate::InputStateSelecting; + d_ptr->m_inputState = QAbstract3DInputHandlerPrivate::InputStateSelecting; + } } } else if (Qt::MiddleButton == event->button()) { - // reset rotations - setInputPosition(QPoint(0, 0)); + if (isRotationEnabled()) { + // reset rotations + setInputPosition(QPoint(0, 0)); + } } else if (Qt::RightButton == event->button()) { - // disable rotating when in slice view - if (!scene()->isSlicingActive()) - d_ptr->m_inputState = QAbstract3DInputHandlerPrivate::InputStateRotating; - // update mouse positions to prevent jumping when releasing or repressing a button - setInputPosition(mousePos); + if (isRotationEnabled()) { + // disable rotating when in slice view + if (!scene()->isSlicingActive()) + d_ptr->m_inputState = QAbstract3DInputHandlerPrivate::InputStateRotating; + // update mouse positions to prevent jumping when releasing or repressing a button + setInputPosition(mousePos); + } } #endif } @@ -148,7 +191,8 @@ void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) #if defined(Q_OS_IOS) Q_UNUSED(mousePos); #else - if (QAbstract3DInputHandlerPrivate::InputStateRotating == d_ptr->m_inputState) { + if (QAbstract3DInputHandlerPrivate::InputStateRotating == d_ptr->m_inputState + && isRotationEnabled()) { // Calculate mouse movement since last frame float xRotation = scene()->activeCamera()->xRotation(); float yRotation = scene()->activeCamera()->yRotation(); @@ -174,29 +218,91 @@ void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) */ void Q3DInputHandler::wheelEvent(QWheelEvent *event) { - // disable zooming if in slice view - if (scene()->isSlicingActive()) - return; - - // Adjust zoom level based on what zoom range we're in. - int zoomLevel = scene()->activeCamera()->zoomLevel(); - if (zoomLevel > oneToOneZoomLevel) - zoomLevel += event->angleDelta().y() / nearZoomRangeDivider; - else if (zoomLevel > halfSizeZoomLevel) - zoomLevel += event->angleDelta().y() / midZoomRangeDivider; - else - zoomLevel += event->angleDelta().y() / farZoomRangeDivider; - if (zoomLevel > maxZoomLevel) - zoomLevel = maxZoomLevel; - else if (zoomLevel < minZoomLevel) - zoomLevel = minZoomLevel; - - scene()->activeCamera()->setZoomLevel(zoomLevel); + if (isZoomEnabled()) { + // disable zooming if in slice view + if (scene()->isSlicingActive()) + return; + + // Adjust zoom level based on what zoom range we're in. + int zoomLevel = scene()->activeCamera()->zoomLevel(); + if (zoomLevel > oneToOneZoomLevel) + zoomLevel += event->angleDelta().y() / nearZoomRangeDivider; + else if (zoomLevel > halfSizeZoomLevel) + zoomLevel += event->angleDelta().y() / midZoomRangeDivider; + else + zoomLevel += event->angleDelta().y() / farZoomRangeDivider; + if (zoomLevel > maxZoomLevel) + zoomLevel = maxZoomLevel; + else if (zoomLevel < minZoomLevel) + zoomLevel = minZoomLevel; + + scene()->activeCamera()->setZoomLevel(zoomLevel); + } +} + +/*! + * \property Q3DInputHandler::rotationEnabled + * \since QtDataVisualization 1.2 + * + * This property specifies if this input handler allows graph rotation. + */ +void Q3DInputHandler::setRotationEnabled(bool enable) +{ + if (d_ptr->m_rotationEnabled != enable) { + d_ptr->m_rotationEnabled = enable; + emit rotationEnabledChanged(enable); + } +} + +bool Q3DInputHandler::isRotationEnabled() const +{ + return d_ptr->m_rotationEnabled; +} + +/*! + * \property Q3DInputHandler::zoomEnabled + * \since QtDataVisualization 1.2 + * + * This property specifies if this input handler allows graph zooming. + */ +void Q3DInputHandler::setZoomEnabled(bool enable) +{ + if (d_ptr->m_zoomEnabled != enable) { + d_ptr->m_zoomEnabled = enable; + emit zoomEnabledChanged(enable); + } +} + +bool Q3DInputHandler::isZoomEnabled() const +{ + return d_ptr->m_zoomEnabled; +} + +/*! + * \property Q3DInputHandler::selectionEnabled + * \since QtDataVisualization 1.2 + * + * This property specifies if this input handler allows selection from the graph. + */ +void Q3DInputHandler::setSelectionEnabled(bool enable) +{ + if (d_ptr->m_selectionEnabled != enable) { + d_ptr->m_selectionEnabled = enable; + emit selectionEnabledChanged(enable); + } +} + +bool Q3DInputHandler::isSelectionEnabled() const +{ + return d_ptr->m_selectionEnabled; } Q3DInputHandlerPrivate::Q3DInputHandlerPrivate(Q3DInputHandler *q) : q_ptr(q), - m_inputState(QAbstract3DInputHandlerPrivate::InputStateNone) + m_inputState(QAbstract3DInputHandlerPrivate::InputStateNone), + m_rotationEnabled(true), + m_zoomEnabled(true), + m_selectionEnabled(true) { } diff --git a/src/datavisualization/input/q3dinputhandler.h b/src/datavisualization/input/q3dinputhandler.h index 118bd829..9afeb945 100644 --- a/src/datavisualization/input/q3dinputhandler.h +++ b/src/datavisualization/input/q3dinputhandler.h @@ -28,17 +28,32 @@ class Q3DInputHandlerPrivate; class QT_DATAVISUALIZATION_EXPORT Q3DInputHandler : public QAbstract3DInputHandler { Q_OBJECT + Q_PROPERTY(bool rotationEnabled READ isRotationEnabled WRITE setRotationEnabled NOTIFY rotationEnabledChanged) + Q_PROPERTY(bool zoomEnabled READ isZoomEnabled WRITE setZoomEnabled NOTIFY zoomEnabledChanged) + Q_PROPERTY(bool selectionEnabled READ isSelectionEnabled WRITE setSelectionEnabled NOTIFY selectionEnabledChanged) public: explicit Q3DInputHandler(QObject *parent = 0); virtual ~Q3DInputHandler(); + void setRotationEnabled(bool enable); + bool isRotationEnabled() const; + void setZoomEnabled(bool enable); + bool isZoomEnabled() const; + void setSelectionEnabled(bool enable); + bool isSelectionEnabled() const; + // Input event listeners virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos); virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); virtual void wheelEvent(QWheelEvent *event); +signals: + void rotationEnabledChanged(bool enable); + void zoomEnabledChanged(bool enable); + void selectionEnabledChanged(bool enable); + private: Q_DISABLE_COPY(Q3DInputHandler) diff --git a/src/datavisualization/input/q3dinputhandler_p.h b/src/datavisualization/input/q3dinputhandler_p.h index a9b27307..a3ed8c9c 100644 --- a/src/datavisualization/input/q3dinputhandler_p.h +++ b/src/datavisualization/input/q3dinputhandler_p.h @@ -40,9 +40,15 @@ public: Q3DInputHandlerPrivate(Q3DInputHandler *q); ~Q3DInputHandlerPrivate(); -public: +protected: Q3DInputHandler *q_ptr; QAbstract3DInputHandlerPrivate::InputState m_inputState; + + bool m_rotationEnabled; + bool m_zoomEnabled; + bool m_selectionEnabled; + + friend class Q3DInputHandler; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/input/qtouch3dinputhandler.cpp b/src/datavisualization/input/qtouch3dinputhandler.cpp index 30f31d4a..5d62922b 100644 --- a/src/datavisualization/input/qtouch3dinputhandler.cpp +++ b/src/datavisualization/input/qtouch3dinputhandler.cpp @@ -66,6 +66,22 @@ const int maxZoomLevel = 500; * \li Closes the secondary view. * \note Secondary view is available only for Q3DBars and Q3DSurface graphs. * \endtable + * + * Rotation, zoom, and selection can each be individually disabled using + * corresponding Q3DInputHandler properties. + */ + +/*! + * \qmltype TouchInputHandler3D + * \inqmlmodule QtDataVisualization + * \since QtDataVisualization 1.2 + * \ingroup datavisualization_qml + * \instantiates QTouch3DInputHandler + * \brief Basic touch display based input handler. + * + * TouchInputHandler3D is the basic input handler for touch screen devices. + * + * See QTouch3DInputHandler documentation for more details. */ /*! @@ -104,29 +120,38 @@ void QTouch3DInputHandler::touchEvent(QTouchEvent *event) // Flush input state d_ptr->m_inputState = QAbstract3DInputHandlerPrivate::InputStateNone; if (scene()->isSlicingActive()) { - if (scene()->isPointInPrimarySubView(pointerPos.toPoint())) - setInputView(InputViewOnPrimary); - else if (scene()->isPointInSecondarySubView(pointerPos.toPoint())) - setInputView(InputViewOnSecondary); - else - setInputView(InputViewNone); + if (isSelectionEnabled()) { + if (scene()->isPointInPrimarySubView(pointerPos.toPoint())) + setInputView(InputViewOnPrimary); + else if (scene()->isPointInSecondarySubView(pointerPos.toPoint())) + setInputView(InputViewOnSecondary); + else + setInputView(InputViewNone); + } } else { // Handle possible tap-and-hold selection - d_ptr->m_startHoldPos = pointerPos; - d_ptr->m_touchHoldPos = d_ptr->m_startHoldPos; - d_ptr->m_holdTimer->start(); - setInputView(InputViewOnPrimary); + if (isSelectionEnabled()) { + d_ptr->m_startHoldPos = pointerPos; + d_ptr->m_touchHoldPos = d_ptr->m_startHoldPos; + d_ptr->m_holdTimer->start(); + setInputView(InputViewOnPrimary); + } // Start rotating - d_ptr->m_inputState = QAbstract3DInputHandlerPrivate::InputStateRotating; - setInputPosition(pointerPos.toPoint()); + if (isRotationEnabled()) { + d_ptr->m_inputState = QAbstract3DInputHandlerPrivate::InputStateRotating; + setInputPosition(pointerPos.toPoint()); + setInputView(InputViewOnPrimary); + } } } else if (event->type() == QEvent::TouchEnd) { setInputView(InputViewNone); d_ptr->m_holdTimer->stop(); // Handle possible selection if (!scene()->isSlicingActive() - && QAbstract3DInputHandlerPrivate::InputStatePinching != d_ptr->m_inputState) + && QAbstract3DInputHandlerPrivate::InputStatePinching + != d_ptr->m_inputState) { d_ptr->handleSelection(pointerPos); + } } else if (event->type() == QEvent::TouchUpdate) { if (!scene()->isSlicingActive()) { d_ptr->m_touchHoldPos = pointerPos; @@ -158,52 +183,59 @@ QTouch3DInputHandlerPrivate::~QTouch3DInputHandlerPrivate() void QTouch3DInputHandlerPrivate::handlePinchZoom(float distance) { - int newDistance = distance; - int prevDist = q_ptr->prevDistance(); - if (prevDist > 0 && qAbs(prevDist - newDistance) < maxPinchJitter) - return; - m_inputState = QAbstract3DInputHandlerPrivate::InputStatePinching; - Q3DCamera *camera = q_ptr->scene()->activeCamera(); - int zoomLevel = camera->zoomLevel(); - float zoomRate = qSqrt(qSqrt(zoomLevel)); - if (newDistance > prevDist) - zoomLevel += zoomRate; - else - zoomLevel -= zoomRate; - if (zoomLevel > maxZoomLevel) - zoomLevel = maxZoomLevel; - else if (zoomLevel < minZoomLevel) - zoomLevel = minZoomLevel; - camera->setZoomLevel(zoomLevel); - q_ptr->setPrevDistance(newDistance); + if (q_ptr->isZoomEnabled()) { + int newDistance = distance; + int prevDist = q_ptr->prevDistance(); + if (prevDist > 0 && qAbs(prevDist - newDistance) < maxPinchJitter) + return; + m_inputState = QAbstract3DInputHandlerPrivate::InputStatePinching; + Q3DCamera *camera = q_ptr->scene()->activeCamera(); + int zoomLevel = camera->zoomLevel(); + float zoomRate = qSqrt(qSqrt(zoomLevel)); + if (newDistance > prevDist) + zoomLevel += zoomRate; + else + zoomLevel -= zoomRate; + if (zoomLevel > maxZoomLevel) + zoomLevel = maxZoomLevel; + else if (zoomLevel < minZoomLevel) + zoomLevel = minZoomLevel; + camera->setZoomLevel(zoomLevel); + q_ptr->setPrevDistance(newDistance); + } } void QTouch3DInputHandlerPrivate::handleTapAndHold() { - QPointF distance = m_startHoldPos - m_touchHoldPos; - if (distance.manhattanLength() < maxTapAndHoldJitter) { - q_ptr->setInputPosition(m_touchHoldPos.toPoint()); - q_ptr->scene()->setSelectionQueryPosition(m_touchHoldPos.toPoint()); - m_inputState = QAbstract3DInputHandlerPrivate::InputStateSelecting; + if (q_ptr->isSelectionEnabled()) { + QPointF distance = m_startHoldPos - m_touchHoldPos; + if (distance.manhattanLength() < maxTapAndHoldJitter) { + q_ptr->setInputPosition(m_touchHoldPos.toPoint()); + q_ptr->scene()->setSelectionQueryPosition(m_touchHoldPos.toPoint()); + m_inputState = QAbstract3DInputHandlerPrivate::InputStateSelecting; + } } } void QTouch3DInputHandlerPrivate::handleSelection(const QPointF &position) { - QPointF distance = m_startHoldPos - position; - if (distance.manhattanLength() < maxSelectionJitter) { - m_inputState = QAbstract3DInputHandlerPrivate::InputStateSelecting; - q_ptr->scene()->setSelectionQueryPosition(position.toPoint()); - } else { - m_inputState = QAbstract3DInputHandlerPrivate::InputStateNone; - q_ptr->setInputView(QAbstract3DInputHandler::InputViewNone); + if (q_ptr->isSelectionEnabled()) { + QPointF distance = m_startHoldPos - position; + if (distance.manhattanLength() < maxSelectionJitter) { + m_inputState = QAbstract3DInputHandlerPrivate::InputStateSelecting; + q_ptr->scene()->setSelectionQueryPosition(position.toPoint()); + } else { + m_inputState = QAbstract3DInputHandlerPrivate::InputStateNone; + q_ptr->setInputView(QAbstract3DInputHandler::InputViewNone); + } + q_ptr->setPreviousInputPos(position.toPoint()); } - q_ptr->setPreviousInputPos(position.toPoint()); } void QTouch3DInputHandlerPrivate::handleRotation(const QPointF &position) { - if (QAbstract3DInputHandlerPrivate::InputStateRotating == m_inputState) { + if (q_ptr->isRotationEnabled() + && QAbstract3DInputHandlerPrivate::InputStateRotating == m_inputState) { Q3DScene *scene = q_ptr->scene(); Q3DCamera *camera = scene->activeCamera(); float xRotation = camera->xRotation(); -- cgit v1.2.3