1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
35 #include "../qdeclarativeviewobserver_p.h"
37 #include <QtGui/QMouseEvent>
38 #include <QtGui/QWheelEvent>
39 #include <QtGui/QKeyEvent>
40 #include <QtGui/QMenu>
41 #include <QtGui/QAction>
43 #include <QtCore/QRectF>
44 #include <QtCore/QDebug>
46 namespace QmlJSDebugger {
48 ZoomTool::ZoomTool(QDeclarativeViewObserver *view) :
49 AbstractLiveEditTool(view),
50 m_rubberbandManipulator(),
51 m_smoothZoomMultiplier(0.05f),
54 m_zoomTo100Action = new QAction(tr("Zoom to &100%"), this);
55 m_zoomInAction = new QAction(tr("Zoom In"), this);
56 m_zoomOutAction = new QAction(tr("Zoom Out"), this);
57 m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Plus));
58 m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus));
61 LiveLayerItem *layerItem = QDeclarativeViewObserverPrivate::get(view)->manipulatorLayer;
62 QGraphicsObject *layerObject = reinterpret_cast<QGraphicsObject *>(layerItem);
63 m_rubberbandManipulator = new LiveRubberBandSelectionManipulator(layerObject, view);
66 connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100()));
67 connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn()));
68 connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut()));
73 delete m_rubberbandManipulator;
76 void ZoomTool::mousePressEvent(QMouseEvent *event)
78 m_mousePos = event->pos();
80 QPointF scenePos = view()->mapToScene(event->pos());
82 if (event->buttons() & Qt::RightButton) {
84 contextMenu.addAction(m_zoomTo100Action);
85 contextMenu.addSeparator();
86 contextMenu.addAction(m_zoomInAction);
87 contextMenu.addAction(m_zoomOutAction);
88 contextMenu.exec(event->globalPos());
89 } else if (event->buttons() & Qt::LeftButton) {
90 m_dragBeginPos = scenePos;
91 m_dragStarted = false;
95 void ZoomTool::mouseMoveEvent(QMouseEvent *event)
97 m_mousePos = event->pos();
99 QPointF scenePos = view()->mapToScene(event->pos());
101 if (event->buttons() & Qt::LeftButton
102 && (QPointF(scenePos - m_dragBeginPos).manhattanLength()
103 > Constants::DragStartDistance / 3)
106 m_dragStarted = true;
107 m_rubberbandManipulator->begin(m_dragBeginPos);
112 m_rubberbandManipulator->update(scenePos);
116 void ZoomTool::mouseReleaseEvent(QMouseEvent *event)
118 m_mousePos = event->pos();
119 QPointF scenePos = view()->mapToScene(event->pos());
122 m_rubberbandManipulator->end();
124 int x1 = qMin(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
125 int x2 = qMax(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
126 int y1 = qMin(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
127 int y2 = qMax(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
129 QPointF scenePosTopLeft = QPoint(x1, y1);
130 QPointF scenePosBottomRight = QPoint(x2, y2);
132 QRectF sceneArea(scenePosTopLeft, scenePosBottomRight);
134 m_currentScale = qMin(view()->rect().width() / sceneArea.width(),
135 view()->rect().height() / sceneArea.height());
138 QTransform transform;
139 transform.scale(m_currentScale, m_currentScale);
141 view()->setTransform(transform);
142 view()->setSceneRect(sceneArea);
144 Qt::KeyboardModifier modifierKey = Qt::ControlModifier;
146 modifierKey = Qt::AltModifier;
148 if (event->modifiers() & modifierKey) {
156 void ZoomTool::zoomIn()
158 m_currentScale = nextZoomScale(ZoomIn);
159 scaleView(view()->mapToScene(m_mousePos));
162 void ZoomTool::zoomOut()
164 m_currentScale = nextZoomScale(ZoomOut);
165 scaleView(view()->mapToScene(m_mousePos));
168 void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event)
170 m_mousePos = event->pos();
174 void ZoomTool::hoverMoveEvent(QMouseEvent *event)
176 m_mousePos = event->pos();
180 void ZoomTool::keyPressEvent(QKeyEvent * /*event*/)
184 void ZoomTool::wheelEvent(QWheelEvent *event)
186 if (event->orientation() != Qt::Vertical)
189 Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier;
190 if (event->modifiers() & smoothZoomModifier) {
191 int numDegrees = event->delta() / 8;
192 m_currentScale += m_smoothZoomMultiplier * (numDegrees / 15.0f);
194 scaleView(view()->mapToScene(m_mousePos));
196 } else if (!event->modifiers()) {
197 if (event->delta() > 0) {
198 m_currentScale = nextZoomScale(ZoomIn);
199 } else if (event->delta() < 0) {
200 m_currentScale = nextZoomScale(ZoomOut);
202 scaleView(view()->mapToScene(m_mousePos));
206 void ZoomTool::keyReleaseEvent(QKeyEvent *event)
208 switch(event->key()) {
225 m_currentScale = ((event->key() - Qt::Key_0) * 1.0f);
226 scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center())
236 void ZoomTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
240 void ZoomTool::clear()
242 view()->setCursor(Qt::ArrowCursor);
245 void ZoomTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
249 void ZoomTool::scaleView(const QPointF ¢erPos)
252 QTransform transform;
253 transform.scale(m_currentScale, m_currentScale);
254 view()->setTransform(transform);
256 QPointF adjustedCenterPos = centerPos;
257 QSize rectSize(view()->rect().width() / m_currentScale,
258 view()->rect().height() / m_currentScale);
261 if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) {
262 adjustedCenterPos.rx() = rectSize.width() / 2;
263 adjustedCenterPos.ry() = rectSize.height() / 2;
266 if (m_currentScale < 1.0f) {
267 adjustedCenterPos.rx() = rectSize.width() / 2;
268 adjustedCenterPos.ry() = rectSize.height() / 2;
269 sceneRect.setRect(view()->rect().width() / 2 -rectSize.width() / 2,
270 view()->rect().height() / 2 -rectSize.height() / 2,
274 sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2,
275 adjustedCenterPos.y() - rectSize.height() / 2,
280 view()->setSceneRect(sceneRect);
283 void ZoomTool::zoomTo100()
285 m_currentScale = 1.0f;
286 scaleView(view()->mapToScene(view()->rect().center()));
289 qreal ZoomTool::nextZoomScale(ZoomDirection direction) const
291 static QList<qreal> zoomScales =
312 if (direction == ZoomIn) {
313 for (int i = 0; i < zoomScales.length(); ++i) {
314 if (zoomScales[i] > m_currentScale || i == zoomScales.length() - 1)
315 return zoomScales[i];
318 for (int i = zoomScales.length() - 1; i >= 0; --i) {
319 if (zoomScales[i] < m_currentScale || i == 0)
320 return zoomScales[i];
327 } // namespace QmlJSDebugger