KDDockWidgets API Documentation 2.0
Loading...
Searching...
No Matches
qtwidgets/views/ClassicIndicatorsWindow.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2019 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6
7 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8
9 Contact KDAB at <info@kdab.com> for commercial licensing options.
10*/
11
13#include "kddockwidgets/core/indicators/ClassicDropIndicatorOverlay.h"
14#include "kddockwidgets/core/Group.h"
15#include "kddockwidgets/ViewFactory.h"
16#include "kddockwidgets/Config.h"
17#include "View.h"
18#include "core/Utils_p.h"
19
20
21#include <QPainter>
22
23#include <utility>
24
25#ifdef QT_X11EXTRAS_LIB
26#include <QtX11Extras/QX11Info>
27#endif
28
29#define INDICATOR_WIDTH 40
30#define OUTTER_INDICATOR_MARGIN 10
31
32using namespace KDDockWidgets;
33using namespace KDDockWidgets::Core;
34using namespace KDDockWidgets::QtWidgets;
35
36namespace KDDockWidgets {
37
39{
40 if (qEnvironmentVariableIsSet("KDDW_NO_TRANSLUCENCY")
42 return false;
43
44#ifdef QT_X11EXTRAS_LIB
45 if (isXCB())
46 return QX11Info::isCompositingManagerRunning();
47#endif
48
49 // macOS and Windows are fine
50 return true;
51}
52
53class Indicator : public QWidget
54{
56public:
57 typedef QList<Indicator *> List;
58 explicit Indicator(IndicatorWindow *parent, DropLocation location);
59 void paintEvent(QPaintEvent *) override;
60
61 void setHovered(bool hovered);
62 QString iconName(bool active) const;
63 QString iconFileName(bool active) const;
64
65 QImage m_image;
66 QImage m_imageActive;
67 bool m_hovered = false;
68 const DropLocation m_dropLocation;
69};
70
71static QString iconName(DropLocation loc, bool active)
72{
73 QString suffix = active ? QStringLiteral("_active") : QString();
74
75 QString name;
76 switch (loc) {
78 name = QStringLiteral("center");
79 break;
81 name = QStringLiteral("inner_left");
82 break;
84 name = QStringLiteral("inner_right");
85 break;
87 name = QStringLiteral("inner_bottom");
88 break;
90 name = QStringLiteral("inner_top");
91 break;
93 name = QStringLiteral("outter_left");
94 break;
96 name = QStringLiteral("outter_bottom");
97 break;
99 name = QStringLiteral("outter_right");
100 break;
102 name = QStringLiteral("outter_top");
103 break;
109 return QString();
110 }
111
112 return name + suffix;
113}
114}
115
116void Indicator::paintEvent(QPaintEvent *)
117{
118 QPainter p(this);
119 if (m_hovered)
120 p.drawImage(rect(), m_imageActive, rect());
121 else
122 p.drawImage(rect(), m_image, rect());
123}
124
125void Indicator::setHovered(bool hovered)
126{
127 if (hovered != m_hovered) {
128 m_hovered = hovered;
129 update();
130 }
131}
132
133QString Indicator::iconName(bool active) const
134{
135 return KDDockWidgets::iconName(m_dropLocation, active);
136}
137
138QString Indicator::iconFileName(bool active) const
139{
140 const QString name = iconName(active);
142
144 ? QStringLiteral("%1/%2.png").arg(path, name)
145 : QStringLiteral("%1/opaque/%2.png").arg(path, name);
146}
147
149{
150 // On Wayland it can't be a top-level, as we have no way of positioning it
151
152 return isWayland() ? QtCommon::View_qt::asQWidget(classicIndicators_->view()) : nullptr;
153}
154
159
162 , classicIndicators(classicIndicators_)
163 , m_center(new Indicator(this, DropLocation_Center)) // Each indicator is not a top-level. Otherwise
164 // there's noticeable delay.
165 , m_left(new Indicator(this, DropLocation_Left))
166 , m_right(new Indicator(this, DropLocation_Right))
167 , m_bottom(new Indicator(this, DropLocation_Bottom))
168 , m_top(new Indicator(this, DropLocation_Top))
169 , m_outterLeft(new Indicator(this, DropLocation_OutterLeft))
170 , m_outterRight(new Indicator(this, DropLocation_OutterRight))
171 , m_outterBottom(new Indicator(this, DropLocation_OutterBottom))
172 , m_outterTop(new Indicator(this, DropLocation_OutterTop))
173{
175
177 // Ensure the overlay window is on top
179 }
180
182
183 m_indicators << m_center << m_left << m_right << m_top << m_bottom << m_outterBottom
184 << m_outterTop << m_outterLeft << m_outterRight;
185}
186
187Indicator *IndicatorWindow::indicatorForLocation(DropLocation loc) const
188{
189 switch (loc) {
191 return m_center;
193 return m_left;
195 return m_right;
197 return m_bottom;
198 case DropLocation_Top:
199 return m_top;
201 return m_outterLeft;
203 return m_outterBottom;
205 return m_outterRight;
207 return m_outterTop;
213 return nullptr;
214 }
215
216 return nullptr;
217}
218
219void IndicatorWindow::updateMask()
220{
221 QRegion region;
222
224 for (Indicator *indicator : std::as_const(m_indicators)) {
225 if (indicator->isVisible())
226 region = region.united(QRegion(indicator->geometry(), QRegion::Rectangle));
227 }
228 }
229
230 setMask(region);
231}
232
233void IndicatorWindow::resizeEvent(QResizeEvent *ev)
234{
237}
238
240{
241 for (Indicator *indicator : { m_left, m_right, m_bottom, m_top, m_outterTop, m_outterLeft,
242 m_outterRight, m_outterBottom, m_center })
243 indicator->setVisible(classicIndicators->dropIndicatorVisible(indicator->m_dropLocation));
244
245 updateMask();
246}
247
249{
250 Indicator *indicator = indicatorForLocation(loc);
251 return indicator->mapToGlobal(indicator->rect().center());
252}
253
255{
257
258 for (Indicator *indicator : std::as_const(m_indicators)) {
259 if (indicator->isVisible()) {
260 const bool hovered = indicator->rect().contains(indicator->mapFromGlobal(globalPos));
261 indicator->setHovered(hovered);
262 if (hovered)
263 loc = indicator->m_dropLocation;
264 }
265 }
266
267 return loc;
268}
269
271{
272 QRect r = rect();
273 const int indicatorWidth = m_outterBottom->width();
274 const int halfIndicatorWidth = m_outterBottom->width() / 2;
275
276 m_outterLeft->move(r.x() + OUTTER_INDICATOR_MARGIN, r.center().y() - halfIndicatorWidth);
277 m_outterBottom->move(r.center().x() - halfIndicatorWidth,
278 r.y() + height() - indicatorWidth - OUTTER_INDICATOR_MARGIN);
279 m_outterTop->move(r.center().x() - halfIndicatorWidth, r.y() + OUTTER_INDICATOR_MARGIN);
280 m_outterRight->move(r.x() + width() - indicatorWidth - OUTTER_INDICATOR_MARGIN,
281 r.center().y() - halfIndicatorWidth);
282 Core::Group *hoveredGroup = classicIndicators->hoveredGroup();
283 if (hoveredGroup) {
284 QRect hoveredRect = hoveredGroup->view()->geometry();
285 m_center->move(r.topLeft() + hoveredRect.center()
286 - QPoint(halfIndicatorWidth, halfIndicatorWidth));
287 m_top->move(m_center->pos() - QPoint(0, indicatorWidth + OUTTER_INDICATOR_MARGIN));
288 m_right->move(m_center->pos() + QPoint(indicatorWidth + OUTTER_INDICATOR_MARGIN, 0));
289 m_bottom->move(m_center->pos() + QPoint(0, indicatorWidth + OUTTER_INDICATOR_MARGIN));
290 m_left->move(m_center->pos() - QPoint(indicatorWidth + OUTTER_INDICATOR_MARGIN, 0));
291 }
292}
293
298
303
305{
307}
308
310{
312}
313
318
320{
321 return QWidget::isWindow();
322}
323
324Indicator::Indicator(IndicatorWindow *parent,
325 DropLocation location)
326 : QWidget(parent)
327 , m_dropLocation(location)
328{
329 m_image = QImage(iconFileName(/*active=*/false)).scaled(INDICATOR_WIDTH, INDICATOR_WIDTH);
330 m_imageActive = QImage(iconFileName(/*active=*/true)).scaled(INDICATOR_WIDTH, INDICATOR_WIDTH);
331 setFixedSize(m_image.size());
332 setVisible(true);
333}
334
335#include "ClassicIndicatorsWindow.moc"
Core::ViewFactory * viewFactory() const
getter for the framework view factory
Definition Config.cpp:182
@ InternalFlag_DisableTranslucency
Definition Config.h:167
static Config & self()
returns the singleton Config instance
Definition Config.cpp:88
@ Flag_KeepAboveIfNotUtilityWindow
Definition Config.h:119
View * view() const
Returns the view associated with this controller, if any.
virtual bool dropIndicatorVisible(DropLocation) const
Returns whether the specified drop indicator should be visible.
virtual QString classicIndicatorsPath() const
The path to a folder containing the classic_indicator png files.
virtual Rect geometry() const =0
IndicatorWindow(Core::ClassicDropIndicatorOverlay *classicIndicators)
Class to abstract QAction, so code still works with QtQuick and Flutter.
DropLocation
Enum describing the different drop indicator types.
static QString iconName(DropLocation loc, bool active)
Definition utils.h:161
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
Q_OBJECTQ_OBJECT
void setObjectName(const QString &name)
QObject * parent() const const
int x() const const
int y() const const
QPoint center() const const
QPoint topLeft() const const
int x() const const
int y() const const
QRegion united(const QRegion &r) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
WA_TranslucentBackground
typedef WindowFlags
static Qt::WindowFlags flagsForIndicatorWindow()
static QWidget * parentForIndicatorWindow(ClassicDropIndicatorOverlay *classicIndicators_)
bool isWindow() const const
void raise()
void resize(int w, int h)
virtual void resizeEvent(QResizeEvent *event)
void setAttribute(Qt::WidgetAttribute attribute, bool on)
void setFixedSize(const QSize &s)
void setGeometry(int x, int y, int w, int h)
void setMask(const QBitmap &bitmap)
void setWindowFlag(Qt::WindowType flag, bool on)
virtual void setVisible(bool visible)

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated by doxygen 1.9.8