1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** 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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "inspecttool.h"
41#include "highlight.h"
42#include "qquickwindowinspector.h"
43#include "globalinspector.h"
44
45#include <QtCore/QLineF>
46
47#include <QtGui/QMouseEvent>
48#include <QtGui/QTouchEvent>
49#include <QtGui/QKeyEvent>
50#include <QtGui/QGuiApplication>
51#include <QtGui/QStyleHints>
52
53#include <QtQuick/QQuickView>
54#include <QtQuick/QQuickItem>
55
56QT_BEGIN_NAMESPACE
57
58namespace QmlJSDebugger {
59
60InspectTool::InspectTool(QQuickWindowInspector *inspector, QQuickWindow *view) :
61 QObject(inspector),
62 m_contentItem(view->contentItem()),
63 m_touchTimestamp(0),
64 m_hoverHighlight(new HoverHighlight(inspector->overlay())),
65 m_lastItem(nullptr),
66 m_lastClickedItem(nullptr)
67{
68 //Timer to display selected item's name
69 m_nameDisplayTimer.setSingleShot(true);
70 m_nameDisplayTimer.setInterval(QGuiApplication::styleHints()->mouseDoubleClickInterval());
71 connect(&m_nameDisplayTimer, &QTimer::timeout, this, &InspectTool::showItemName);
72}
73
74void InspectTool::enterEvent(QEvent *)
75{
76 m_hoverHighlight->setVisible(true);
77}
78
79void InspectTool::leaveEvent(QEvent *)
80{
81 m_hoverHighlight->setVisible(false);
82}
83
84void InspectTool::mousePressEvent(QMouseEvent *event)
85{
86 m_mousePosition = event->localPos();
87 if (event->button() == Qt::LeftButton) {
88 selectItem();
89 m_hoverHighlight->setVisible(false);
90 }
91}
92
93void InspectTool::mouseDoubleClickEvent(QMouseEvent *event)
94{
95 m_mousePosition = event->localPos();
96 if (event->button() == Qt::LeftButton) {
97 selectNextItem();
98 m_hoverHighlight->setVisible(false);
99 }
100}
101
102void InspectTool::mouseMoveEvent(QMouseEvent *event)
103{
104 hoverMoveEvent(event);
105}
106
107void InspectTool::hoverMoveEvent(QMouseEvent *event)
108{
109 m_mousePosition = event->localPos();
110 QQuickItem *item = inspector()->topVisibleItemAt(event->pos());
111 if (!item || item == m_lastClickedItem) {
112 m_hoverHighlight->setVisible(false);
113 } else {
114 m_hoverHighlight->setItem(item);
115 m_hoverHighlight->setVisible(true);
116 }
117}
118
119void InspectTool::touchEvent(QTouchEvent *event)
120{
121 QList<QTouchEvent::TouchPoint> touchPoints = event->touchPoints();
122
123 switch (event->type()) {
124 case QEvent::TouchBegin:
125 if (touchPoints.count() == 1 && (event->touchPointStates() & Qt::TouchPointPressed)) {
126 m_mousePosition = touchPoints.first().pos();
127 m_tapEvent = true;
128 } else {
129 m_tapEvent = false;
130 }
131 break;
132 case QEvent::TouchUpdate: {
133 if (touchPoints.count() > 1)
134 m_tapEvent = false;
135 else if ((touchPoints.count() == 1) && (event->touchPointStates() & Qt::TouchPointMoved))
136 m_mousePosition = touchPoints.first().pos();
137 break;
138 }
139 case QEvent::TouchEnd: {
140 if (touchPoints.count() == 1 && m_tapEvent) {
141 m_tapEvent = false;
142 bool doubleTap = event->timestamp() - m_touchTimestamp
143 < static_cast<ulong>(QGuiApplication::styleHints()->mouseDoubleClickInterval());
144 if (doubleTap) {
145 m_nameDisplayTimer.stop();
146 selectNextItem();
147 } else {
148 selectItem();
149 }
150 m_touchTimestamp = event->timestamp();
151 }
152 break;
153 }
154 default:
155 break;
156 }
157}
158
159void InspectTool::selectNextItem()
160{
161 if (m_lastClickedItem != inspector()->topVisibleItemAt(m_mousePosition))
162 return;
163 QList<QQuickItem*> items = inspector()->itemsAt(m_mousePosition);
164 for (int i = 0; i < items.count(); i++) {
165 if (m_lastItem == items[i]) {
166 if (i + 1 < items.count())
167 m_lastItem = items[i+1];
168 else
169 m_lastItem = items[0];
170 globalInspector()->setSelectedItems(QList<QQuickItem*>() << m_lastItem);
171 showItemName();
172 break;
173 }
174 }
175}
176
177void InspectTool::selectItem()
178{
179 if (!inspector()->topVisibleItemAt(m_mousePosition))
180 return;
181 m_lastClickedItem = inspector()->topVisibleItemAt(m_mousePosition);
182 m_lastItem = m_lastClickedItem;
183 globalInspector()->setSelectedItems(QList<QQuickItem*>() << m_lastClickedItem);
184 if (m_lastClickedItem == inspector()->topVisibleItemAt(m_mousePosition)) {
185 m_nameDisplayTimer.start();
186 } else {
187 showItemName();
188 }
189}
190
191void InspectTool::showItemName()
192{
193 globalInspector()->showSelectedItemName(m_lastItem, m_mousePosition);
194}
195
196QQuickWindowInspector *InspectTool::inspector() const
197{
198 return static_cast<QQuickWindowInspector *>(parent());
199}
200
201GlobalInspector *InspectTool::globalInspector() const
202{
203 return static_cast<GlobalInspector *>(parent()->parent());
204}
205
206} // namespace QmlJSDebugger
207
208QT_END_NAMESPACE
209
210#include "moc_inspecttool.cpp"
211