1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** 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 {
58 ZoomTool::ZoomTool(QDeclarativeViewInspector *view) :
59 AbstractLiveEditTool(view),
60 m_rubberbandManipulator(),
61 m_smoothZoomMultiplier(0.05f),
64 m_zoomTo100Action = new QAction(tr("Zoom to &100%"), this);
65 m_zoomInAction = new QAction(tr("Zoom In"), this);
66 m_zoomOutAction = new QAction(tr("Zoom Out"), this);
67 m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Plus));
68 m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus));
71 LiveLayerItem *layerItem = QDeclarativeViewInspectorPrivate::get(view)->manipulatorLayer;
72 QGraphicsObject *layerObject = reinterpret_cast<QGraphicsObject *>(layerItem);
73 m_rubberbandManipulator = new LiveRubberBandSelectionManipulator(layerObject, view);
76 connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100()));
77 connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn()));
78 connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut()));
83 delete m_rubberbandManipulator;
86 void ZoomTool::mousePressEvent(QMouseEvent *event)
88 m_mousePos = event->pos();
90 QPointF scenePos = view()->mapToScene(event->pos());
92 if (event->buttons() & Qt::RightButton) {
94 contextMenu.addAction(m_zoomTo100Action);
95 contextMenu.addSeparator();
96 contextMenu.addAction(m_zoomInAction);
97 contextMenu.addAction(m_zoomOutAction);
98 contextMenu.exec(event->globalPos());
99 } else if (event->buttons() & Qt::LeftButton) {
100 m_dragBeginPos = scenePos;
101 m_dragStarted = false;
105 void ZoomTool::mouseMoveEvent(QMouseEvent *event)
107 m_mousePos = event->pos();
109 QPointF scenePos = view()->mapToScene(event->pos());
111 if (event->buttons() & Qt::LeftButton
112 && (QPointF(scenePos - m_dragBeginPos).manhattanLength()
113 > Constants::DragStartDistance / 3)
116 m_dragStarted = true;
117 m_rubberbandManipulator->begin(m_dragBeginPos);
122 m_rubberbandManipulator->update(scenePos);
126 void ZoomTool::mouseReleaseEvent(QMouseEvent *event)
128 m_mousePos = event->pos();
129 QPointF scenePos = view()->mapToScene(event->pos());
132 m_rubberbandManipulator->end();
134 int x1 = qMin(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
135 int x2 = qMax(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
136 int y1 = qMin(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
137 int y2 = qMax(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
139 QPointF scenePosTopLeft = QPoint(x1, y1);
140 QPointF scenePosBottomRight = QPoint(x2, y2);
142 QRectF sceneArea(scenePosTopLeft, scenePosBottomRight);
144 m_currentScale = qMin(view()->rect().width() / sceneArea.width(),
145 view()->rect().height() / sceneArea.height());
148 QTransform transform;
149 transform.scale(m_currentScale, m_currentScale);
151 view()->setTransform(transform);
152 view()->setSceneRect(sceneArea);
154 Qt::KeyboardModifier modifierKey = Qt::ControlModifier;
156 modifierKey = Qt::AltModifier;
158 if (event->modifiers() & modifierKey) {
166 void ZoomTool::zoomIn()
168 m_currentScale = nextZoomScale(ZoomIn);
169 scaleView(view()->mapToScene(m_mousePos));
172 void ZoomTool::zoomOut()
174 m_currentScale = nextZoomScale(ZoomOut);
175 scaleView(view()->mapToScene(m_mousePos));
178 void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event)
180 m_mousePos = event->pos();
184 void ZoomTool::hoverMoveEvent(QMouseEvent *event)
186 m_mousePos = event->pos();
190 void ZoomTool::keyPressEvent(QKeyEvent * /*event*/)
194 void ZoomTool::wheelEvent(QWheelEvent *event)
196 if (event->orientation() != Qt::Vertical)
199 Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier;
200 if (event->modifiers() & smoothZoomModifier) {
201 int numDegrees = event->delta() / 8;
202 m_currentScale += m_smoothZoomMultiplier * (numDegrees / 15.0f);
204 scaleView(view()->mapToScene(m_mousePos));
206 } else if (!event->modifiers()) {
207 if (event->delta() > 0) {
208 m_currentScale = nextZoomScale(ZoomIn);
209 } else if (event->delta() < 0) {
210 m_currentScale = nextZoomScale(ZoomOut);
212 scaleView(view()->mapToScene(m_mousePos));
216 void ZoomTool::keyReleaseEvent(QKeyEvent *event)
218 switch (event->key()) {
235 m_currentScale = ((event->key() - Qt::Key_0) * 1.0f);
236 scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center())
246 void ZoomTool::clear()
248 view()->setCursor(Qt::ArrowCursor);
251 void ZoomTool::scaleView(const QPointF ¢erPos)
254 QTransform transform;
255 transform.scale(m_currentScale, m_currentScale);
256 view()->setTransform(transform);
258 QPointF adjustedCenterPos = centerPos;
259 QSize rectSize(view()->rect().width() / m_currentScale,
260 view()->rect().height() / m_currentScale);
263 if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) {
264 adjustedCenterPos.rx() = rectSize.width() / 2;
265 adjustedCenterPos.ry() = rectSize.height() / 2;
268 if (m_currentScale < 1.0f) {
269 adjustedCenterPos.rx() = rectSize.width() / 2;
270 adjustedCenterPos.ry() = rectSize.height() / 2;
271 sceneRect.setRect(view()->rect().width() / 2 -rectSize.width() / 2,
272 view()->rect().height() / 2 -rectSize.height() / 2,
276 sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2,
277 adjustedCenterPos.y() - rectSize.height() / 2,
282 view()->setSceneRect(sceneRect);
285 void ZoomTool::zoomTo100()
287 m_currentScale = 1.0f;
288 scaleView(view()->mapToScene(view()->rect().center()));
291 qreal ZoomTool::nextZoomScale(ZoomDirection direction) const
293 static QList<qreal> zoomScales =
314 if (direction == ZoomIn) {
315 for (int i = 0; i < zoomScales.length(); ++i) {
316 if (zoomScales[i] > m_currentScale || i == zoomScales.length() - 1)
317 return zoomScales[i];
320 for (int i = zoomScales.length() - 1; i >= 0; --i) {
321 if (zoomScales[i] < m_currentScale || i == 0)
322 return zoomScales[i];
329 } // namespace QtQuick1
330 } // namespace QmlJSDebugger