aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp')
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp336
1 files changed, 336 insertions, 0 deletions
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp
new file mode 100644
index 0000000000..b70cda5ba4
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "zoomtool_p.h"
+
+#include "../qdeclarativeviewobserver_p_p.h"
+
+#include <QtGui/QMouseEvent>
+#include <QtGui/QWheelEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+
+#include <QtCore/QRectF>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+ZoomTool::ZoomTool(QDeclarativeViewObserver *view) :
+ AbstractLiveEditTool(view),
+ m_rubberbandManipulator(),
+ m_smoothZoomMultiplier(0.05f),
+ m_currentScale(1.0f)
+{
+ m_zoomTo100Action = new QAction(tr("Zoom to &100%"), this);
+ m_zoomInAction = new QAction(tr("Zoom In"), this);
+ m_zoomOutAction = new QAction(tr("Zoom Out"), this);
+ m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Plus));
+ m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus));
+
+
+ LiveLayerItem *layerItem = QDeclarativeViewObserverPrivate::get(view)->manipulatorLayer;
+ QGraphicsObject *layerObject = reinterpret_cast<QGraphicsObject *>(layerItem);
+ m_rubberbandManipulator = new LiveRubberBandSelectionManipulator(layerObject, view);
+
+
+ connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100()));
+ connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn()));
+ connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut()));
+}
+
+ZoomTool::~ZoomTool()
+{
+ delete m_rubberbandManipulator;
+}
+
+void ZoomTool::mousePressEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+
+ QPointF scenePos = view()->mapToScene(event->pos());
+
+ if (event->buttons() & Qt::RightButton) {
+ QMenu contextMenu;
+ contextMenu.addAction(m_zoomTo100Action);
+ contextMenu.addSeparator();
+ contextMenu.addAction(m_zoomInAction);
+ contextMenu.addAction(m_zoomOutAction);
+ contextMenu.exec(event->globalPos());
+ } else if (event->buttons() & Qt::LeftButton) {
+ m_dragBeginPos = scenePos;
+ m_dragStarted = false;
+ }
+}
+
+void ZoomTool::mouseMoveEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+
+ QPointF scenePos = view()->mapToScene(event->pos());
+
+ if (event->buttons() & Qt::LeftButton
+ && (QPointF(scenePos - m_dragBeginPos).manhattanLength()
+ > Constants::DragStartDistance / 3)
+ && !m_dragStarted)
+ {
+ m_dragStarted = true;
+ m_rubberbandManipulator->begin(m_dragBeginPos);
+ return;
+ }
+
+ if (m_dragStarted)
+ m_rubberbandManipulator->update(scenePos);
+
+}
+
+void ZoomTool::mouseReleaseEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+ QPointF scenePos = view()->mapToScene(event->pos());
+
+ if (m_dragStarted) {
+ m_rubberbandManipulator->end();
+
+ int x1 = qMin(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
+ int x2 = qMax(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
+ int y1 = qMin(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
+ int y2 = qMax(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
+
+ QPointF scenePosTopLeft = QPoint(x1, y1);
+ QPointF scenePosBottomRight = QPoint(x2, y2);
+
+ QRectF sceneArea(scenePosTopLeft, scenePosBottomRight);
+
+ m_currentScale = qMin(view()->rect().width() / sceneArea.width(),
+ view()->rect().height() / sceneArea.height());
+
+
+ QTransform transform;
+ transform.scale(m_currentScale, m_currentScale);
+
+ view()->setTransform(transform);
+ view()->setSceneRect(sceneArea);
+ } else {
+ Qt::KeyboardModifier modifierKey = Qt::ControlModifier;
+#ifdef Q_WS_MAC
+ modifierKey = Qt::AltModifier;
+#endif
+ if (event->modifiers() & modifierKey) {
+ zoomOut();
+ } else {
+ zoomIn();
+ }
+ }
+}
+
+void ZoomTool::zoomIn()
+{
+ m_currentScale = nextZoomScale(ZoomIn);
+ scaleView(view()->mapToScene(m_mousePos));
+}
+
+void ZoomTool::zoomOut()
+{
+ m_currentScale = nextZoomScale(ZoomOut);
+ scaleView(view()->mapToScene(m_mousePos));
+}
+
+void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+}
+
+
+void ZoomTool::hoverMoveEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+}
+
+
+void ZoomTool::keyPressEvent(QKeyEvent * /*event*/)
+{
+}
+
+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;
+ m_currentScale += m_smoothZoomMultiplier * (numDegrees / 15.0f);
+
+ scaleView(view()->mapToScene(m_mousePos));
+
+ } else if (!event->modifiers()) {
+ if (event->delta() > 0) {
+ m_currentScale = nextZoomScale(ZoomIn);
+ } else if (event->delta() < 0) {
+ m_currentScale = nextZoomScale(ZoomOut);
+ }
+ scaleView(view()->mapToScene(m_mousePos));
+ }
+}
+
+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:
+ {
+ m_currentScale = ((event->key() - Qt::Key_0) * 1.0f);
+ scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center())
+ break;
+ }
+
+ default:
+ break;
+ }
+
+}
+
+void ZoomTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
+{
+}
+
+void ZoomTool::clear()
+{
+ view()->setCursor(Qt::ArrowCursor);
+}
+
+void ZoomTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
+{
+}
+
+void ZoomTool::scaleView(const QPointF &centerPos)
+{
+
+ QTransform transform;
+ transform.scale(m_currentScale, m_currentScale);
+ view()->setTransform(transform);
+
+ QPointF adjustedCenterPos = centerPos;
+ QSize rectSize(view()->rect().width() / m_currentScale,
+ view()->rect().height() / m_currentScale);
+
+ QRectF sceneRect;
+ if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) {
+ adjustedCenterPos.rx() = rectSize.width() / 2;
+ adjustedCenterPos.ry() = rectSize.height() / 2;
+ }
+
+ if (m_currentScale < 1.0f) {
+ adjustedCenterPos.rx() = rectSize.width() / 2;
+ adjustedCenterPos.ry() = rectSize.height() / 2;
+ sceneRect.setRect(view()->rect().width() / 2 -rectSize.width() / 2,
+ view()->rect().height() / 2 -rectSize.height() / 2,
+ rectSize.width(),
+ rectSize.height());
+ } else {
+ sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2,
+ adjustedCenterPos.y() - rectSize.height() / 2,
+ rectSize.width(),
+ rectSize.height());
+ }
+
+ view()->setSceneRect(sceneRect);
+}
+
+void ZoomTool::zoomTo100()
+{
+ m_currentScale = 1.0f;
+ scaleView(view()->mapToScene(view()->rect().center()));
+}
+
+qreal ZoomTool::nextZoomScale(ZoomDirection direction) const
+{
+ static QList<qreal> zoomScales =
+ QList<qreal>()
+ << 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 || i == zoomScales.length() - 1)
+ return zoomScales[i];
+ }
+ } else {
+ for (int i = zoomScales.length() - 1; i >= 0; --i) {
+ if (zoomScales[i] < m_currentScale || i == 0)
+ return zoomScales[i];
+ }
+ }
+
+ return 1.0f;
+}
+
+QT_END_NAMESPACE