From: Simjees Abraham Date: Mon, 19 Mar 2012 10:33:05 +0000 (+0100) Subject: Initial checkin for ZoomTool implementation X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=a11a9e926b1b0eaff4842f354b6d0acebe70717f;p=konrad%2Fqtdeclarative.git Initial checkin for ZoomTool implementation Change-Id: I0f2c8906a48b0c1d45fb980a349a8ffb135130b5 Reviewed-by: Kai Koehne --- diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro b/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro index 2d4de57..33bda11 100644 --- a/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro +++ b/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro @@ -15,7 +15,8 @@ SOURCES += \ selectiontool.cpp \ qquickviewinspector.cpp \ ../shared/abstracttool.cpp \ - ../shared/abstractviewinspector.cpp + ../shared/abstractviewinspector.cpp \ + zoomtool.cpp HEADERS += \ qtquick2plugin.h \ @@ -25,7 +26,8 @@ HEADERS += \ ../shared/abstracttool.h \ ../shared/abstractviewinspector.h \ ../shared/qqmlinspectorprotocol.h \ - ../shared/qmlinspectorconstants.h + ../shared/qmlinspectorconstants.h \ + zoomtool.h OTHER_FILES += qtquick2plugin.json diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp index 200c66e..0a73540 100644 --- a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp +++ b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp @@ -44,6 +44,7 @@ #include "qqmlinspectorprotocol.h" #include "highlight.h" #include "selectiontool.h" +#include "zoomtool.h" #include @@ -120,6 +121,7 @@ QQuickViewInspector::QQuickViewInspector(QQuickView *view, QObject *parent) : m_view(view), m_overlay(new QQuickItem), m_selectionTool(new SelectionTool(this)), + m_zoomTool(0), m_designMode(true) { // Try to make sure the overlay is always on top @@ -176,7 +178,9 @@ void QQuickViewInspector::changeTool(InspectorProtocol::Tool tool) emit selectToolActivated(); break; case InspectorProtocol::ZoomTool: - // TODO + if (!m_zoomTool) + m_zoomTool = new ZoomTool(this, m_view); + setCurrentTool(m_zoomTool); emit zoomToolActivated(); break; } diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h index fbc3c17..e8fdf35 100644 --- a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h +++ b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h @@ -57,6 +57,7 @@ namespace QtQuick2 { class SelectionTool; class SelectionHighlight; +class ZoomTool; class QQuickViewInspector : public AbstractViewInspector { @@ -99,6 +100,7 @@ private: QQuickItem *m_overlay; SelectionTool *m_selectionTool; + ZoomTool *m_zoomTool; QList > m_selectedItems; QHash m_highlightItems; diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.cpp b/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.cpp new file mode 100644 index 0000000..171f1a5 --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.cpp @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "zoomtool.h" +#include "qquickviewinspector.h" + +#include +#include +#include +#include +#include + +#include +#include + +namespace QmlJSDebugger { +namespace QtQuick2 { + +ZoomTool::ZoomTool(QQuickViewInspector *inspector, QQuickView *view) : + AbstractTool(inspector), + m_dragStarted(false), + m_pinchStarted(false), + m_currentScale(1.0f), + m_smoothScaleFactor(0.05f), + m_minScale(0.125f), + m_maxScale(48.0f), + m_tapScaleCounter(0) +{ + m_rootItem = view->rootItem(); + m_originalSmooth = m_rootItem->smooth(); + if (!m_originalSmooth) + m_rootItem->setSmooth(true); + m_originalPosition = m_rootItem->pos(); + m_originalScale = m_rootItem->scale(); +} + +ZoomTool::~ZoomTool() +{ + // restoring the original states. + m_rootItem->setScale(m_originalScale); + m_rootItem->setPos(m_originalPosition); + if (!m_originalSmooth) + m_rootItem->setSmooth(m_originalSmooth); +} + +void ZoomTool::mousePressEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); + if (event->buttons() & Qt::LeftButton) { + m_dragStartPosition = event->posF(); + m_dragStarted = false; + } +} + +void ZoomTool::mouseMoveEvent(QMouseEvent *event) +{ + if (m_pinchStarted) + return; + + m_mousePosition = event->posF(); + if (!m_dragStarted + && event->buttons() & Qt::LeftButton + && ((m_dragStartPosition - event->posF()).manhattanLength() + > Constants::DragStartDistance)) { + m_dragStarted = true; + } + if (m_dragStarted) { + m_adjustedOrigin += event->posF() - m_dragStartPosition; + m_dragStartPosition = event->posF(); + m_rootItem->setPos(m_adjustedOrigin); + } +} + +void ZoomTool::hoverMoveEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); +} + +void ZoomTool::wheelEvent(QWheelEvent *event) +{ + if (event->orientation() != Qt::Vertical) + return; + + Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier; + if (event->modifiers() & smoothZoomModifier) { + int numDegrees = event->delta() / 8; + qreal newScale = m_currentScale + m_smoothScaleFactor * (numDegrees / 15.0f); + scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); + } else if (!event->modifiers()) { + if (event->delta() > 0) { + zoomIn(); + } else if (event->delta() < 0) { + zoomOut(); + } + } +} + +void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); + zoomTo100(); +} + +void ZoomTool::keyReleaseEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Plus: + zoomIn(); + break; + case Qt::Key_Minus: + zoomOut(); + break; + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_8: + case Qt::Key_9: { + qreal newScale = ((event->key() - Qt::Key_0) * 1.0f); + scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); + break; + } + default: + break; + } +} + +void ZoomTool::touchEvent(QTouchEvent *event) +{ + QList touchPoints = event->touchPoints(); + + switch (event->type()) { + case QEvent::TouchBegin: + // fall through.. + case QEvent::TouchUpdate: { + if ((touchPoints.count() == 2) + && (!(event->touchPointStates() & Qt::TouchPointReleased))) { + // determine scale factor + const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first(); + const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last(); + + qreal touchScaleFactor = + QLineF(touchPoint0.pos(), touchPoint1.pos()).length() + / QLineF(touchPoint0.lastPos(), touchPoint1.lastPos()).length(); + + QPointF oldcenter = (touchPoint0.lastPos() + touchPoint1.lastPos()) / 2; + QPointF newcenter = (touchPoint0.pos() + touchPoint1.pos()) / 2; + + m_pinchStarted = true; + m_tapScaleCounter = 0; + scaleView(touchScaleFactor, newcenter, oldcenter); + } + break; + } + case QEvent::TouchEnd: { + if (m_pinchStarted) { + m_pinchStarted = false; + } else if ((touchPoints.count() == 1) + &&(!m_dragStarted)) { + ++m_tapScaleCounter; + qreal factor = 1.0f + (1.0f / (m_tapScaleCounter + 1)); + scaleView(factor, touchPoints.first().pos(), + touchPoints.first().pos()); + } + break; + } + default: + break; + } +} + +void ZoomTool::scaleView(const qreal &factor, const QPointF &newcenter, const QPointF &oldcenter) +{ + if (((m_currentScale * factor) > m_maxScale) + || ((m_currentScale * factor) < m_minScale)) { + return; + } + //New position = new center + scalefactor * (oldposition - oldcenter) + m_adjustedOrigin = newcenter + (factor * (m_adjustedOrigin - oldcenter)); + m_currentScale *= factor; + + m_rootItem->setScale(m_currentScale); + m_rootItem->setPos(m_adjustedOrigin); +} + +void ZoomTool::zoomIn() +{ + qreal newScale = nextZoomScale(ZoomIn); + scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); +} + +void ZoomTool::zoomOut() +{ + qreal newScale = nextZoomScale(ZoomOut); + scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); +} + +void ZoomTool::zoomTo100() +{ + m_currentScale = 1.0; + m_adjustedOrigin = QPointF(0, 0); + m_tapScaleCounter = 0; + + m_rootItem->setPos(m_adjustedOrigin); + m_rootItem->setScale(m_currentScale); +} + +qreal ZoomTool::nextZoomScale(ZoomDirection direction) +{ + static QList zoomScales = + QList() + << 0.125f + << 1.0f / 6.0f + << 0.25f + << 1.0f / 3.0f + << 0.5f + << 2.0f / 3.0f + << 1.0f + << 2.0f + << 3.0f + << 4.0f + << 5.0f + << 6.0f + << 7.0f + << 8.0f + << 12.0f + << 16.0f + << 32.0f + << 48.0f; + + if (direction == ZoomIn) { + for (int i = 0; i < zoomScales.length(); ++i) { + if (zoomScales[i] > m_currentScale) + return zoomScales[i]; + } + return zoomScales.last(); + } else { + for (int i = zoomScales.length() - 1; i >= 0; --i) { + if (zoomScales[i] < m_currentScale) + return zoomScales[i]; + } + return zoomScales.first(); + } + + return 1.0f; +} + +} // namespace QtQuick2 +} // namespace QmlJSDebugger diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.h b/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.h new file mode 100644 index 0000000..02ed8e0 --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ZOOMTOOL_H +#define ZOOMTOOL_H + +#include "abstracttool.h" + +#include + +QT_FORWARD_DECLARE_CLASS(QQuickView) +QT_FORWARD_DECLARE_CLASS(QQuickItem) + +namespace QmlJSDebugger { +namespace QtQuick2 { + +class QQuickViewInspector; + +class ZoomTool : public AbstractTool +{ + Q_OBJECT + +public: + enum ZoomDirection { + ZoomIn, + ZoomOut + }; + + explicit ZoomTool(QQuickViewInspector *inspector, QQuickView *view); + virtual ~ZoomTool(); + void leaveEvent(QEvent *) {} + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *) {} + void mouseDoubleClickEvent(QMouseEvent *event); + + void hoverMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + + void keyPressEvent(QKeyEvent *) {} + void keyReleaseEvent(QKeyEvent *event); + + void touchEvent(QTouchEvent *event); + +private: + qreal nextZoomScale(ZoomDirection direction); + void scaleView(const qreal &factor, const QPointF &newcenter, const QPointF &oldcenter); + void zoomTo100(); + void zoomIn(); + void zoomOut(); + +private: + bool m_originalSmooth; + bool m_dragStarted; + bool m_pinchStarted; + QQuickItem *m_rootItem; + QPointF m_adjustedOrigin; + QPointF m_dragStartPosition; + QPointF m_mousePosition; + QPointF m_originalPosition; + qreal m_currentScale; + qreal m_smoothScaleFactor; + qreal m_minScale; + qreal m_maxScale; + qreal m_tapScaleCounter; + qreal m_originalScale; +}; + +} // namespace QtQuick2 +} // namespace QmlJSDebugger + +#endif // ZOOMTOOL_H diff --git a/src/plugins/qmltooling/shared/abstracttool.h b/src/plugins/qmltooling/shared/abstracttool.h index 3581706..7e5ba65 100644 --- a/src/plugins/qmltooling/shared/abstracttool.h +++ b/src/plugins/qmltooling/shared/abstracttool.h @@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE class QMouseEvent; class QKeyEvent; class QWheelEvent; +class QTouchEvent; QT_END_NAMESPACE namespace QmlJSDebugger { @@ -76,6 +77,8 @@ public: virtual void keyPressEvent(QKeyEvent *event) = 0; virtual void keyReleaseEvent(QKeyEvent *keyEvent) = 0; + virtual void touchEvent(QTouchEvent *) {} + private: AbstractViewInspector *m_inspector; }; diff --git a/src/plugins/qmltooling/shared/abstractviewinspector.cpp b/src/plugins/qmltooling/shared/abstractviewinspector.cpp index 33e47d2..135da1b 100644 --- a/src/plugins/qmltooling/shared/abstractviewinspector.cpp +++ b/src/plugins/qmltooling/shared/abstractviewinspector.cpp @@ -50,6 +50,7 @@ #include #include +#include namespace QmlJSDebugger { @@ -220,6 +221,12 @@ bool AbstractViewInspector::eventFilter(QObject *obj, QEvent *event) if (wheelEvent(static_cast(event))) return true; break; + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + if (touchEvent(static_cast(event))) + return true; + break; default: break; } @@ -300,6 +307,12 @@ bool AbstractViewInspector::wheelEvent(QWheelEvent *event) return true; } +bool AbstractViewInspector::touchEvent(QTouchEvent *event) +{ + m_currentTool->touchEvent(event); + return true; +} + void AbstractViewInspector::handleMessage(const QByteArray &message) { QDataStream ds(message); diff --git a/src/plugins/qmltooling/shared/abstractviewinspector.h b/src/plugins/qmltooling/shared/abstractviewinspector.h index 0dacc92..04ca029 100644 --- a/src/plugins/qmltooling/shared/abstractviewinspector.h +++ b/src/plugins/qmltooling/shared/abstractviewinspector.h @@ -56,6 +56,8 @@ class QQmlInspectorService; class QKeyEvent; class QMouseEvent; class QWheelEvent; +class QTouchEvent; + QT_END_NAMESPACE namespace QmlJSDebugger { @@ -128,6 +130,7 @@ protected: virtual bool keyReleaseEvent(QKeyEvent *keyEvent); virtual bool mouseDoubleClickEvent(QMouseEvent *event); virtual bool wheelEvent(QWheelEvent *event); + virtual bool touchEvent(QTouchEvent *event); private slots: void sendColorChanged(const QColor &color);