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 "highlight.h"
41
42#include <QtCore/QTimer>
43#include <QtGui/QPainter>
44#include <QtGui/QStaticText>
45#include <QtQuick/QQuickWindow>
46
47QT_BEGIN_NAMESPACE
48
49namespace QmlJSDebugger {
50
51Highlight::Highlight(QQuickItem *parent) : QQuickPaintedItem(parent)
52{
53 initRenderDetails();
54}
55
56Highlight::Highlight(QQuickItem *item, QQuickItem *parent)
57 : QQuickPaintedItem(parent)
58{
59 initRenderDetails();
60 setItem(item);
61}
62
63void Highlight::initRenderDetails()
64{
65 setRenderTarget(QQuickPaintedItem::FramebufferObject);
66 setPerformanceHint(hint: QQuickPaintedItem::FastFBOResizing, enabled: true);
67}
68
69void Highlight::setItem(QQuickItem *item)
70{
71 if (m_item)
72 m_item->disconnect(receiver: this);
73
74 if (item) {
75 connect(sender: item, signal: &QQuickItem::xChanged, receiver: this, slot: &Highlight::adjust);
76 connect(sender: item, signal: &QQuickItem::yChanged, receiver: this, slot: &Highlight::adjust);
77 connect(sender: item, signal: &QQuickItem::widthChanged, receiver: this, slot: &Highlight::adjust);
78 connect(sender: item, signal: &QQuickItem::heightChanged, receiver: this, slot: &Highlight::adjust);
79 connect(sender: item, signal: &QQuickItem::rotationChanged, receiver: this, slot: &Highlight::adjust);
80 connect(sender: item, signal: &QQuickItem::transformOriginChanged, receiver: this, slot: &Highlight::adjust);
81 }
82 QQuickWindow *view = item->window();
83 QQuickItem * contentItem = view->contentItem();
84 if (contentItem) {
85 connect(sender: contentItem, signal: &QQuickItem::xChanged, receiver: this, slot: &Highlight::adjust);
86 connect(sender: contentItem, signal: &QQuickItem::yChanged, receiver: this, slot: &Highlight::adjust);
87 connect(sender: contentItem, signal: &QQuickItem::widthChanged, receiver: this, slot: &Highlight::adjust);
88 connect(sender: contentItem, signal: &QQuickItem::heightChanged, receiver: this, slot: &Highlight::adjust);
89 connect(sender: contentItem, signal: &QQuickItem::rotationChanged, receiver: this, slot: &Highlight::adjust);
90 connect(sender: contentItem, signal: &QQuickItem::transformOriginChanged, receiver: this, slot: &Highlight::adjust);
91 }
92 m_item = item;
93 setContentsSize(view->size());
94 adjust();
95}
96
97void Highlight::adjust()
98{
99 if (!m_item)
100 return;
101
102 bool success = false;
103 m_transform = m_item->itemTransform(nullptr, &success);
104 if (!success)
105 m_transform = QTransform();
106
107 setSize(QSizeF(m_item->width(), m_item->height()));
108 qreal scaleFactor = 1;
109 QPointF originOffset = QPointF(0,0);
110 QQuickWindow *view = m_item->window();
111 if (view->contentItem()) {
112 scaleFactor = view->contentItem()->scale();
113 originOffset -= view->contentItem()->position();
114 }
115 // The scale transform for the overlay needs to be cancelled
116 // as the Item's transform which will be applied to the painter
117 // takes care of it.
118 parentItem()->setScale(1/scaleFactor);
119 setPosition(originOffset);
120 update();
121}
122
123
124void HoverHighlight::paint(QPainter *painter)
125{
126 if (!item())
127 return;
128
129 painter->save();
130 painter->setTransform(transform: transform());
131 painter->setPen(QColor(108, 141, 221));
132 painter->drawRect(r: QRect(0, 0, item()->width() - 1, item()->height() - 1));
133 painter->restore();
134}
135
136
137SelectionHighlight::SelectionHighlight(const QString &name, QQuickItem *item, QQuickItem *parent)
138 : Highlight(item, parent),
139 m_name(name),
140 m_nameDisplayActive(false)
141{
142}
143
144void SelectionHighlight::paint(QPainter *painter)
145{
146 if (!item())
147 return;
148 painter->save();
149 painter->fillRect(QRectF(0,0,contentsSize().width(), contentsSize().height()),
150 color: QColor(0,0,0,127));
151 painter->setTransform(transform: transform());
152 // Setting the composition mode such that the transparency will
153 // be erased as per the selected item.
154 painter->setCompositionMode(QPainter::CompositionMode_Clear);
155 painter->fillRect(x: 0, y: 0, w: item()->width(), h: item()->height(), c: Qt::black);
156 painter->restore();
157
158 // Use the painter with the original transform and not with the
159 // item's transform for display of name.
160 if (!m_nameDisplayActive)
161 return;
162
163 // Paint the text in gray background if display name is active..
164 QRect textRect = painter->boundingRect(rect: QRect(10, contentsSize().height() - 10 ,
165 contentsSize().width() - 20, contentsSize().height()),
166 flags: Qt::AlignCenter | Qt::ElideRight, text: m_name);
167
168 qreal xPosition = m_displayPoint.x();
169 if (xPosition + textRect.width() > contentsSize().width())
170 xPosition = contentsSize().width() - textRect.width();
171 if (xPosition < 0) {
172 xPosition = 0;
173 textRect.setWidth(contentsSize().width());
174 }
175 qreal yPosition = m_displayPoint.y() - textRect.height() - 20;
176 if (yPosition < 50 )
177 yPosition = 50;
178
179 painter->fillRect(r: QRectF(xPosition - 5, yPosition - 5,
180 textRect.width() + 10, textRect.height() + 10), c: Qt::gray);
181 painter->drawRect(rect: QRectF(xPosition - 5, yPosition - 5,
182 textRect.width() + 10, textRect.height() + 10));
183
184 painter->drawStaticText(x: xPosition, y: yPosition, staticText: QStaticText(m_name));
185}
186
187void SelectionHighlight::showName(const QPointF &displayPoint)
188{
189 m_displayPoint = displayPoint;
190 m_nameDisplayActive = true;
191 QTimer::singleShot(interval: 1500, receiver: this, slot: &SelectionHighlight::disableNameDisplay);
192 update();
193}
194
195void SelectionHighlight::disableNameDisplay()
196{
197 m_nameDisplayActive = false;
198 update();
199}
200
201} // namespace QmlJSDebugger
202
203QT_END_NAMESPACE
204
205#include "moc_highlight.cpp"
206

source code of qtdeclarative/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp