1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include "qdeclarativeviewinspector_p.h"
46 #include <QtGui/QMouseEvent>
47 #include <QtGui/QWheelEvent>
48 #include <QtGui/QKeyEvent>
49 #include <QtWidgets/QMenu>
50 #include <QtWidgets/QAction>
52 #include <QtCore/QRectF>
53 #include <QtCore/QDebug>
55 namespace QmlJSDebugger {
57 ZoomTool::ZoomTool(QDeclarativeViewInspector *view) :
58 AbstractLiveEditTool(view),
59 m_rubberbandManipulator(),
60 m_smoothZoomMultiplier(0.05f),
63 m_zoomTo100Action = new QAction(tr("Zoom to &100%"), this);
64 m_zoomInAction = new QAction(tr("Zoom In"), this);
65 m_zoomOutAction = new QAction(tr("Zoom Out"), this);
66 m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Plus));
67 m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus));
70 LiveLayerItem *layerItem = QDeclarativeViewInspectorPrivate::get(view)->manipulatorLayer;
71 QGraphicsObject *layerObject = reinterpret_cast<QGraphicsObject *>(layerItem);
72 m_rubberbandManipulator = new LiveRubberBandSelectionManipulator(layerObject, view);
75 connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100()));
76 connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn()));
77 connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut()));
82 delete m_rubberbandManipulator;
85 void ZoomTool::mousePressEvent(QMouseEvent *event)
87 m_mousePos = event->pos();
89 QPointF scenePos = view()->mapToScene(event->pos());
91 if (event->buttons() & Qt::RightButton) {
93 contextMenu.addAction(m_zoomTo100Action);
94 contextMenu.addSeparator();
95 contextMenu.addAction(m_zoomInAction);
96 contextMenu.addAction(m_zoomOutAction);
97 contextMenu.exec(event->globalPos());
98 } else if (event->buttons() & Qt::LeftButton) {
99 m_dragBeginPos = scenePos;
100 m_dragStarted = false;
104 void ZoomTool::mouseMoveEvent(QMouseEvent *event)
106 m_mousePos = event->pos();
108 QPointF scenePos = view()->mapToScene(event->pos());
110 if (event->buttons() & Qt::LeftButton
111 && (QPointF(scenePos - m_dragBeginPos).manhattanLength()
112 > Constants::DragStartDistance / 3)
115 m_dragStarted = true;
116 m_rubberbandManipulator->begin(m_dragBeginPos);
121 m_rubberbandManipulator->update(scenePos);
125 void ZoomTool::mouseReleaseEvent(QMouseEvent *event)
127 m_mousePos = event->pos();
128 QPointF scenePos = view()->mapToScene(event->pos());
131 m_rubberbandManipulator->end();
133 int x1 = qMin(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
134 int x2 = qMax(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
135 int y1 = qMin(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
136 int y2 = qMax(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
138 QPointF scenePosTopLeft = QPoint(x1, y1);
139 QPointF scenePosBottomRight = QPoint(x2, y2);
141 QRectF sceneArea(scenePosTopLeft, scenePosBottomRight);
143 m_currentScale = qMin(view()->rect().width() / sceneArea.width(),
144 view()->rect().height() / sceneArea.height());
147 QTransform transform;
148 transform.scale(m_currentScale, m_currentScale);
150 view()->setTransform(transform);
151 view()->setSceneRect(sceneArea);
153 Qt::KeyboardModifier modifierKey = Qt::ControlModifier;
155 modifierKey = Qt::AltModifier;
157 if (event->modifiers() & modifierKey) {
165 void ZoomTool::zoomIn()
167 m_currentScale = nextZoomScale(ZoomIn);
168 scaleView(view()->mapToScene(m_mousePos));
171 void ZoomTool::zoomOut()
173 m_currentScale = nextZoomScale(ZoomOut);
174 scaleView(view()->mapToScene(m_mousePos));
177 void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event)
179 m_mousePos = event->pos();
183 void ZoomTool::hoverMoveEvent(QMouseEvent *event)
185 m_mousePos = event->pos();
189 void ZoomTool::keyPressEvent(QKeyEvent * /*event*/)
193 void ZoomTool::wheelEvent(QWheelEvent *event)
195 if (event->orientation() != Qt::Vertical)
198 Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier;
199 if (event->modifiers() & smoothZoomModifier) {
200 int numDegrees = event->delta() / 8;
201 m_currentScale += m_smoothZoomMultiplier * (numDegrees / 15.0f);
203 scaleView(view()->mapToScene(m_mousePos));
205 } else if (!event->modifiers()) {
206 if (event->delta() > 0) {
207 m_currentScale = nextZoomScale(ZoomIn);
208 } else if (event->delta() < 0) {
209 m_currentScale = nextZoomScale(ZoomOut);
211 scaleView(view()->mapToScene(m_mousePos));
215 void ZoomTool::keyReleaseEvent(QKeyEvent *event)
217 switch (event->key()) {
234 m_currentScale = ((event->key() - Qt::Key_0) * 1.0f);
235 scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center())
245 void ZoomTool::clear()
247 view()->setCursor(Qt::ArrowCursor);
250 void ZoomTool::scaleView(const QPointF ¢erPos)
253 QTransform transform;
254 transform.scale(m_currentScale, m_currentScale);
255 view()->setTransform(transform);
257 QPointF adjustedCenterPos = centerPos;
258 QSize rectSize(view()->rect().width() / m_currentScale,
259 view()->rect().height() / m_currentScale);
262 if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) {
263 adjustedCenterPos.rx() = rectSize.width() / 2;
264 adjustedCenterPos.ry() = rectSize.height() / 2;
267 if (m_currentScale < 1.0f) {
268 adjustedCenterPos.rx() = rectSize.width() / 2;
269 adjustedCenterPos.ry() = rectSize.height() / 2;
270 sceneRect.setRect(view()->rect().width() / 2 -rectSize.width() / 2,
271 view()->rect().height() / 2 -rectSize.height() / 2,
275 sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2,
276 adjustedCenterPos.y() - rectSize.height() / 2,
281 view()->setSceneRect(sceneRect);
284 void ZoomTool::zoomTo100()
286 m_currentScale = 1.0f;
287 scaleView(view()->mapToScene(view()->rect().center()));
290 qreal ZoomTool::nextZoomScale(ZoomDirection direction) const
292 static QList<qreal> zoomScales =
313 if (direction == ZoomIn) {
314 for (int i = 0; i < zoomScales.length(); ++i) {
315 if (zoomScales[i] > m_currentScale || i == zoomScales.length() - 1)
316 return zoomScales[i];
319 for (int i = zoomScales.length() - 1; i >= 0; --i) {
320 if (zoomScales[i] < m_currentScale || i == 0)
321 return zoomScales[i];
328 } // namespace QmlJSDebugger