OSDN Git Service

10b05a2c4d7c517a1fb0e5bc814e29147ca77edb
[qt-creator-jp/qt-creator-jp.git] / share / qtcreator / qml / qmljsdebugger / editor / zoomtool.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "zoomtool.h"
35 #include "../qdeclarativeviewobserver_p.h"
36
37 #include <QtGui/QMouseEvent>
38 #include <QtGui/QWheelEvent>
39 #include <QtGui/QKeyEvent>
40 #include <QtGui/QMenu>
41 #include <QtGui/QAction>
42
43 #include <QtCore/QRectF>
44 #include <QtCore/QDebug>
45
46 namespace QmlJSDebugger {
47
48 ZoomTool::ZoomTool(QDeclarativeViewObserver *view) :
49     AbstractLiveEditTool(view),
50     m_rubberbandManipulator(),
51     m_smoothZoomMultiplier(0.05f),
52     m_currentScale(1.0f)
53 {
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));
59
60
61     LiveLayerItem *layerItem = QDeclarativeViewObserverPrivate::get(view)->manipulatorLayer;
62     QGraphicsObject *layerObject = reinterpret_cast<QGraphicsObject *>(layerItem);
63     m_rubberbandManipulator = new LiveRubberBandSelectionManipulator(layerObject, view);
64
65
66     connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100()));
67     connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn()));
68     connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut()));
69 }
70
71 ZoomTool::~ZoomTool()
72 {
73     delete m_rubberbandManipulator;
74 }
75
76 void ZoomTool::mousePressEvent(QMouseEvent *event)
77 {
78     m_mousePos = event->pos();
79
80     QPointF scenePos = view()->mapToScene(event->pos());
81
82     if (event->buttons() & Qt::RightButton) {
83         QMenu contextMenu;
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;
92     }
93 }
94
95 void ZoomTool::mouseMoveEvent(QMouseEvent *event)
96 {
97     m_mousePos = event->pos();
98
99     QPointF scenePos = view()->mapToScene(event->pos());
100
101     if (event->buttons() & Qt::LeftButton
102             && (QPointF(scenePos - m_dragBeginPos).manhattanLength()
103                 > Constants::DragStartDistance / 3)
104             && !m_dragStarted)
105     {
106         m_dragStarted = true;
107         m_rubberbandManipulator->begin(m_dragBeginPos);
108         return;
109     }
110
111     if (m_dragStarted)
112         m_rubberbandManipulator->update(scenePos);
113
114 }
115
116 void ZoomTool::mouseReleaseEvent(QMouseEvent *event)
117 {
118     m_mousePos = event->pos();
119     QPointF scenePos = view()->mapToScene(event->pos());
120
121     if (m_dragStarted) {
122         m_rubberbandManipulator->end();
123
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());
128
129         QPointF scenePosTopLeft = QPoint(x1, y1);
130         QPointF scenePosBottomRight = QPoint(x2, y2);
131
132         QRectF sceneArea(scenePosTopLeft, scenePosBottomRight);
133
134         m_currentScale = qMin(view()->rect().width() / sceneArea.width(),
135                               view()->rect().height() / sceneArea.height());
136
137
138         QTransform transform;
139         transform.scale(m_currentScale, m_currentScale);
140
141         view()->setTransform(transform);
142         view()->setSceneRect(sceneArea);
143     } else {
144         Qt::KeyboardModifier modifierKey = Qt::ControlModifier;
145 #ifdef Q_WS_MAC
146         modifierKey = Qt::AltModifier;
147 #endif
148         if (event->modifiers() & modifierKey) {
149             zoomOut();
150         } else {
151             zoomIn();
152         }
153     }
154 }
155
156 void ZoomTool::zoomIn()
157 {
158     m_currentScale = nextZoomScale(ZoomIn);
159     scaleView(view()->mapToScene(m_mousePos));
160 }
161
162 void ZoomTool::zoomOut()
163 {
164     m_currentScale = nextZoomScale(ZoomOut);
165     scaleView(view()->mapToScene(m_mousePos));
166 }
167
168 void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event)
169 {
170     m_mousePos = event->pos();
171 }
172
173
174 void ZoomTool::hoverMoveEvent(QMouseEvent *event)
175 {
176     m_mousePos = event->pos();
177 }
178
179
180 void ZoomTool::keyPressEvent(QKeyEvent * /*event*/)
181 {
182 }
183
184 void ZoomTool::wheelEvent(QWheelEvent *event)
185 {
186     if (event->orientation() != Qt::Vertical)
187         return;
188
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);
193
194         scaleView(view()->mapToScene(m_mousePos));
195
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);
201         }
202         scaleView(view()->mapToScene(m_mousePos));
203     }
204 }
205
206 void ZoomTool::keyReleaseEvent(QKeyEvent *event)
207 {
208     switch(event->key()) {
209     case Qt::Key_Plus:
210         zoomIn();
211         break;
212     case Qt::Key_Minus:
213         zoomOut();
214         break;
215     case Qt::Key_1:
216     case Qt::Key_2:
217     case Qt::Key_3:
218     case Qt::Key_4:
219     case Qt::Key_5:
220     case Qt::Key_6:
221     case Qt::Key_7:
222     case Qt::Key_8:
223     case Qt::Key_9:
224     {
225         m_currentScale = ((event->key() - Qt::Key_0) * 1.0f);
226         scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center())
227         break;
228     }
229
230     default:
231         break;
232     }
233
234 }
235
236 void ZoomTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
237 {
238 }
239
240 void ZoomTool::clear()
241 {
242     view()->setCursor(Qt::ArrowCursor);
243 }
244
245 void ZoomTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
246 {
247 }
248
249 void ZoomTool::scaleView(const QPointF &centerPos)
250 {
251
252     QTransform transform;
253     transform.scale(m_currentScale, m_currentScale);
254     view()->setTransform(transform);
255
256     QPointF adjustedCenterPos = centerPos;
257     QSize rectSize(view()->rect().width() / m_currentScale,
258                    view()->rect().height() / m_currentScale);
259
260     QRectF sceneRect;
261     if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) {
262         adjustedCenterPos.rx() = rectSize.width() / 2;
263         adjustedCenterPos.ry() = rectSize.height() / 2;
264     }
265
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,
271                           rectSize.width(),
272                           rectSize.height());
273     } else {
274         sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2,
275                           adjustedCenterPos.y() - rectSize.height() / 2,
276                           rectSize.width(),
277                           rectSize.height());
278     }
279
280     view()->setSceneRect(sceneRect);
281 }
282
283 void ZoomTool::zoomTo100()
284 {
285     m_currentScale = 1.0f;
286     scaleView(view()->mapToScene(view()->rect().center()));
287 }
288
289 qreal ZoomTool::nextZoomScale(ZoomDirection direction) const
290 {
291     static QList<qreal> zoomScales =
292             QList<qreal>()
293             << 0.125f
294             << 1.0f / 6.0f
295             << 0.25f
296             << 1.0f / 3.0f
297             << 0.5f
298             << 2.0f / 3.0f
299             << 1.0f
300             << 2.0f
301             << 3.0f
302             << 4.0f
303             << 5.0f
304             << 6.0f
305             << 7.0f
306             << 8.0f
307             << 12.0f
308             << 16.0f
309             << 32.0f
310             << 48.0f;
311
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];
316         }
317     } else {
318         for (int i = zoomScales.length() - 1; i >= 0; --i) {
319             if (zoomScales[i] < m_currentScale || i == 0)
320                 return zoomScales[i];
321         }
322     }
323
324     return 1.0f;
325 }
326
327 } // namespace QmlJSDebugger