1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "highlight.h"
5
6#include <QtCore/QTimer>
7#include <QtGui/QPainter>
8#include <QtGui/QStaticText>
9#include <QtQuick/QQuickWindow>
10
11QT_BEGIN_NAMESPACE
12
13namespace QmlJSDebugger {
14
15Highlight::Highlight(QQuickItem *parent) : QQuickPaintedItem(parent)
16{
17 initRenderDetails();
18}
19
20Highlight::Highlight(QQuickItem *item, QQuickItem *parent)
21 : QQuickPaintedItem(parent)
22{
23 initRenderDetails();
24 setItem(item);
25}
26
27void Highlight::initRenderDetails()
28{
29 setRenderTarget(QQuickPaintedItem::FramebufferObject);
30 setPerformanceHint(hint: QQuickPaintedItem::FastFBOResizing, enabled: true);
31}
32
33void Highlight::setItem(QQuickItem *item)
34{
35 if (m_item)
36 m_item->disconnect(receiver: this);
37
38 if (item) {
39 connect(sender: item, signal: &QQuickItem::xChanged, context: this, slot: &Highlight::adjust);
40 connect(sender: item, signal: &QQuickItem::yChanged, context: this, slot: &Highlight::adjust);
41 connect(sender: item, signal: &QQuickItem::widthChanged, context: this, slot: &Highlight::adjust);
42 connect(sender: item, signal: &QQuickItem::heightChanged, context: this, slot: &Highlight::adjust);
43 connect(sender: item, signal: &QQuickItem::rotationChanged, context: this, slot: &Highlight::adjust);
44 connect(sender: item, signal: &QQuickItem::transformOriginChanged, context: this, slot: &Highlight::adjust);
45 }
46 QQuickWindow *view = item->window();
47 QQuickItem * contentItem = view->contentItem();
48 if (contentItem) {
49 connect(sender: contentItem, signal: &QQuickItem::xChanged, context: this, slot: &Highlight::adjust);
50 connect(sender: contentItem, signal: &QQuickItem::yChanged, context: this, slot: &Highlight::adjust);
51 connect(sender: contentItem, signal: &QQuickItem::widthChanged, context: this, slot: &Highlight::adjust);
52 connect(sender: contentItem, signal: &QQuickItem::heightChanged, context: this, slot: &Highlight::adjust);
53 connect(sender: contentItem, signal: &QQuickItem::rotationChanged, context: this, slot: &Highlight::adjust);
54 connect(sender: contentItem, signal: &QQuickItem::transformOriginChanged, context: this, slot: &Highlight::adjust);
55 }
56 m_item = item;
57 setContentsSize(view->size());
58 adjust();
59}
60
61void Highlight::adjust()
62{
63 if (!m_item)
64 return;
65
66 bool success = false;
67 m_transform = m_item->itemTransform(nullptr, &success);
68 if (!success)
69 m_transform = QTransform();
70
71 setSize(QSizeF(m_item->width(), m_item->height()));
72 qreal scaleFactor = 1;
73 QPointF originOffset = QPointF(0,0);
74 QQuickWindow *view = m_item->window();
75 if (view->contentItem()) {
76 scaleFactor = view->contentItem()->scale();
77 originOffset -= view->contentItem()->position();
78 }
79 // The scale transform for the overlay needs to be cancelled
80 // as the Item's transform which will be applied to the painter
81 // takes care of it.
82 parentItem()->setScale(1/scaleFactor);
83 setPosition(originOffset);
84 update();
85}
86
87
88void HoverHighlight::paint(QPainter *painter)
89{
90 if (!item())
91 return;
92
93 painter->save();
94 painter->setTransform(transform: transform());
95 painter->setPen(QColor(108, 141, 221));
96 painter->drawRect(r: QRect(0, 0, item()->width() - 1, item()->height() - 1));
97 painter->restore();
98}
99
100
101SelectionHighlight::SelectionHighlight(const QString &name, QQuickItem *item, QQuickItem *parent)
102 : Highlight(item, parent),
103 m_name(name),
104 m_nameDisplayActive(false)
105{
106}
107
108void SelectionHighlight::paint(QPainter *painter)
109{
110 if (!item())
111 return;
112 painter->save();
113 painter->fillRect(QRectF(0,0,contentsSize().width(), contentsSize().height()),
114 color: QColor(0,0,0,127));
115 painter->setTransform(transform: transform());
116 // Setting the composition mode such that the transparency will
117 // be erased as per the selected item.
118 painter->setCompositionMode(QPainter::CompositionMode_Clear);
119 painter->fillRect(x: 0, y: 0, w: item()->width(), h: item()->height(), c: Qt::black);
120 painter->restore();
121
122 // Use the painter with the original transform and not with the
123 // item's transform for display of name.
124 if (!m_nameDisplayActive)
125 return;
126
127 // Paint the text in gray background if display name is active..
128 QRect textRect = painter->boundingRect(rect: QRect(10, contentsSize().height() - 10 ,
129 contentsSize().width() - 20, contentsSize().height()),
130 flags: Qt::AlignCenter | Qt::ElideRight, text: m_name);
131
132 qreal xPosition = m_displayPoint.x();
133 if (xPosition + textRect.width() > contentsSize().width())
134 xPosition = contentsSize().width() - textRect.width();
135 if (xPosition < 0) {
136 xPosition = 0;
137 textRect.setWidth(contentsSize().width());
138 }
139 qreal yPosition = m_displayPoint.y() - textRect.height() - 20;
140 if (yPosition < 50 )
141 yPosition = 50;
142
143 painter->fillRect(r: QRectF(xPosition - 5, yPosition - 5,
144 textRect.width() + 10, textRect.height() + 10), c: Qt::gray);
145 painter->drawRect(rect: QRectF(xPosition - 5, yPosition - 5,
146 textRect.width() + 10, textRect.height() + 10));
147
148 painter->drawStaticText(x: xPosition, y: yPosition, staticText: QStaticText(m_name));
149}
150
151void SelectionHighlight::showName(const QPointF &displayPoint)
152{
153 m_displayPoint = displayPoint;
154 m_nameDisplayActive = true;
155 QTimer::singleShot(interval: 1500, receiver: this, slot: &SelectionHighlight::disableNameDisplay);
156 update();
157}
158
159void SelectionHighlight::disableNameDisplay()
160{
161 m_nameDisplayActive = false;
162 update();
163}
164
165} // namespace QmlJSDebugger
166
167QT_END_NAMESPACE
168
169#include "moc_highlight.cpp"
170

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