OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / share / qtcreator / qml / qmljsdebugger / editor / subcomponenteditortool.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 "subcomponenteditortool.h"
35 #include "../qdeclarativeviewobserver_p.h"
36 #include "subcomponentmasklayeritem.h"
37 #include "layeritem.h"
38
39 #include <QGraphicsItem>
40 #include <QGraphicsObject>
41 #include <QTimer>
42 #include <QMouseEvent>
43 #include <QKeyEvent>
44
45 #include <QDebug>
46
47
48 namespace QmlJSDebugger {
49
50 const qreal MaxOpacity = 0.5f;
51
52 SubcomponentEditorTool::SubcomponentEditorTool(QDeclarativeViewObserver *view)
53     : AbstractFormEditorTool(view),
54       m_animIncrement(0.05f),
55       m_animTimer(new QTimer(this))
56 {
57     QDeclarativeViewObserverPrivate *observerPrivate =
58             QDeclarativeViewObserverPrivate::get(view);
59     m_mask = new SubcomponentMaskLayerItem(view, observerPrivate->manipulatorLayer);
60     connect(m_animTimer, SIGNAL(timeout()), SLOT(animate()));
61     m_animTimer->setInterval(20);
62 }
63
64 SubcomponentEditorTool::~SubcomponentEditorTool()
65 {
66
67 }
68
69 void SubcomponentEditorTool::mousePressEvent(QMouseEvent * /*event*/)
70 {
71
72 }
73
74 void SubcomponentEditorTool::mouseMoveEvent(QMouseEvent * /*event*/)
75 {
76
77 }
78
79 bool SubcomponentEditorTool::containsCursor(const QPoint &mousePos) const
80 {
81     if (!m_currentContext.size())
82         return false;
83
84     QPointF scenePos = view()->mapToScene(mousePos);
85     QRectF itemRect = m_currentContext.top()->boundingRect()
86             | m_currentContext.top()->childrenBoundingRect();
87     QRectF polyRect = m_currentContext.top()->mapToScene(itemRect).boundingRect();
88
89     return polyRect.contains(scenePos);
90 }
91
92 void SubcomponentEditorTool::mouseReleaseEvent(QMouseEvent * /*event*/)
93 {
94
95 }
96
97 void SubcomponentEditorTool::mouseDoubleClickEvent(QMouseEvent *event)
98 {
99     if (event->buttons() & Qt::LeftButton
100             && !containsCursor(event->pos())
101             && m_currentContext.size() > 1)
102     {
103         aboutToPopContext();
104     }
105 }
106
107 void SubcomponentEditorTool::hoverMoveEvent(QMouseEvent *event)
108 {
109     if (!containsCursor(event->pos()) && m_currentContext.size() > 1) {
110         QDeclarativeViewObserverPrivate::get(observer())->clearHighlight();
111     }
112 }
113
114 void SubcomponentEditorTool::wheelEvent(QWheelEvent * /*event*/)
115 {
116
117 }
118
119 void SubcomponentEditorTool::keyPressEvent(QKeyEvent * /*event*/)
120 {
121
122 }
123
124 void SubcomponentEditorTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
125 {
126
127 }
128
129 void SubcomponentEditorTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
130 {
131
132 }
133
134 void SubcomponentEditorTool::animate()
135 {
136     if (m_animIncrement > 0) {
137         if (m_mask->opacity() + m_animIncrement < MaxOpacity) {
138             m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
139         } else {
140             m_animTimer->stop();
141             m_mask->setOpacity(MaxOpacity);
142         }
143     } else {
144         if (m_mask->opacity() + m_animIncrement > 0) {
145             m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
146         } else {
147             m_animTimer->stop();
148             m_mask->setOpacity(0);
149             popContext();
150             emit contextPathChanged(m_path);
151         }
152     }
153
154 }
155
156 void SubcomponentEditorTool::clear()
157 {
158     m_currentContext.clear();
159     m_mask->setCurrentItem(0);
160     m_animTimer->stop();
161     m_mask->hide();
162     m_path.clear();
163
164     emit contextPathChanged(m_path);
165     emit cleared();
166 }
167
168 void SubcomponentEditorTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
169 {
170
171 }
172
173 void SubcomponentEditorTool::setCurrentItem(QGraphicsItem* contextItem)
174 {
175     if (!contextItem)
176         return;
177
178     QGraphicsObject *gfxObject = contextItem->toGraphicsObject();
179     if (!gfxObject)
180         return;
181
182     //QString parentClassName = gfxObject->metaObject()->className();
183     //if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+")))
184
185     bool containsSelectableItems = false;
186     foreach(QGraphicsItem *item, gfxObject->childItems()) {
187         if (item->type() == Constants::EditorItemType
188                 || item->type() == Constants::ResizeHandleItemType)
189         {
190             continue;
191         }
192         containsSelectableItems = true;
193         break;
194     }
195
196     if (containsSelectableItems) {
197         m_mask->setCurrentItem(gfxObject);
198         m_mask->setOpacity(0);
199         m_mask->show();
200         m_animIncrement = 0.05f;
201         m_animTimer->start();
202
203         QDeclarativeViewObserverPrivate::get(observer())->clearHighlight();
204         observer()->setSelectedItems(QList<QGraphicsItem*>());
205
206         pushContext(gfxObject);
207     }
208 }
209
210 QGraphicsItem *SubcomponentEditorTool::firstChildOfContext(QGraphicsItem *item) const
211 {
212     if (!item)
213         return 0;
214
215     if (isDirectChildOfContext(item))
216         return item;
217
218     QGraphicsItem *parent = item->parentItem();
219     while (parent) {
220         if (isDirectChildOfContext(parent))
221             return parent;
222         parent = parent->parentItem();
223     }
224
225     return 0;
226 }
227
228 bool SubcomponentEditorTool::isChildOfContext(QGraphicsItem *item) const
229 {
230     return (firstChildOfContext(item) != 0);
231 }
232
233 bool SubcomponentEditorTool::isDirectChildOfContext(QGraphicsItem *item) const
234 {
235     return (item->parentItem() == m_currentContext.top());
236 }
237
238 bool SubcomponentEditorTool::itemIsChildOfQmlSubComponent(QGraphicsItem *item) const
239 {
240     if (item->parentItem() && item->parentItem() != m_currentContext.top()) {
241         QGraphicsObject *parent = item->parentItem()->toGraphicsObject();
242         QString parentClassName = parent->metaObject()->className();
243
244         if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+"))) {
245             return true;
246         } else {
247             return itemIsChildOfQmlSubComponent(parent);
248         }
249     }
250
251     return false;
252 }
253
254 void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem)
255 {
256     connect(contextItem, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*)));
257     connect(contextItem, SIGNAL(xChanged()), this, SLOT(resizeMask()));
258     connect(contextItem, SIGNAL(yChanged()), this, SLOT(resizeMask()));
259     connect(contextItem, SIGNAL(widthChanged()), this, SLOT(resizeMask()));
260     connect(contextItem, SIGNAL(heightChanged()), this, SLOT(resizeMask()));
261     connect(contextItem, SIGNAL(rotationChanged()), this, SLOT(resizeMask()));
262
263     m_currentContext.push(contextItem);
264     QString title = titleForItem(contextItem);
265     emit contextPushed(title);
266
267     m_path << title;
268     emit contextPathChanged(m_path);
269 }
270
271 void SubcomponentEditorTool::aboutToPopContext()
272 {
273     if (m_currentContext.size() > 2) {
274         popContext();
275         emit contextPathChanged(m_path);
276     } else {
277         m_animIncrement = -0.05f;
278         m_animTimer->start();
279     }
280 }
281
282 QGraphicsObject *SubcomponentEditorTool::popContext()
283 {
284     QGraphicsObject *popped = m_currentContext.pop();
285     m_path.removeLast();
286
287     emit contextPopped();
288
289     disconnect(popped, SIGNAL(xChanged()), this, SLOT(resizeMask()));
290     disconnect(popped, SIGNAL(yChanged()), this, SLOT(resizeMask()));
291     disconnect(popped, SIGNAL(scaleChanged()), this, SLOT(resizeMask()));
292     disconnect(popped, SIGNAL(widthChanged()), this, SLOT(resizeMask()));
293     disconnect(popped, SIGNAL(heightChanged()), this, SLOT(resizeMask()));
294
295     if (m_currentContext.size() > 1) {
296         QGraphicsObject *item = m_currentContext.top();
297         m_mask->setCurrentItem(item);
298         m_mask->setOpacity(MaxOpacity);
299         m_mask->setVisible(true);
300     } else {
301         m_mask->setVisible(false);
302     }
303
304     return popped;
305 }
306
307 void SubcomponentEditorTool::resizeMask()
308 {
309     QGraphicsObject *item = m_currentContext.top();
310     m_mask->setCurrentItem(item);
311 }
312
313 QGraphicsObject *SubcomponentEditorTool::currentRootItem() const
314 {
315     return m_currentContext.top();
316 }
317
318 void SubcomponentEditorTool::contextDestroyed(QObject *contextToDestroy)
319 {
320     disconnect(contextToDestroy, SIGNAL(destroyed(QObject*)),
321                this, SLOT(contextDestroyed(QObject*)));
322
323     // pop out the whole context - it might not be safe anymore.
324     while (m_currentContext.size() > 1) {
325         m_currentContext.pop();
326         m_path.removeLast();
327         emit contextPopped();
328     }
329     m_mask->setVisible(false);
330
331     emit contextPathChanged(m_path);
332 }
333
334 QGraphicsObject *SubcomponentEditorTool::setContext(int contextIndex)
335 {
336     Q_ASSERT(contextIndex >= 0);
337
338     // sometimes we have to delete the context while user was still clicking around,
339     // so just bail out.
340     if (contextIndex >= m_currentContext.size() -1)
341         return 0;
342
343     while (m_currentContext.size() - 1 > contextIndex) {
344         popContext();
345     }
346     emit contextPathChanged(m_path);
347
348     return m_currentContext.top();
349 }
350
351 int SubcomponentEditorTool::contextIndex() const
352 {
353     return m_currentContext.size() - 1;
354 }
355
356 } // namespace QmlJSDebugger