KDDockWidgets API Documentation 2.0
Loading...
Searching...
No Matches
qtwidgets/views/TitleBar.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
12#include "TitleBar.h"
13
14#include "core/TitleBar.h"
15#include "core/FloatingWindow.h"
16#include "core/Window_p.h"
17#include "core/Utils_p.h"
18#include "core/View_p.h"
19#include "core/Logging_p.h"
20#include "core/TitleBar_p.h"
21#include "core/DockRegistry_p.h"
22
24
25#include <QPainter>
26#include <QStyle>
27#include <QStyleOptionDockWidget>
28#include <QHBoxLayout>
29#include <QLabel>
30
31using namespace KDDockWidgets;
32using namespace KDDockWidgets::QtWidgets;
33
37
39{
40 QPainter p(this);
42 opt.initFrom(this);
43
44 if (isEnabled() && underMouse()) {
45 if (isDown()) {
46 opt.state |= QStyle::State_Sunken;
47 } else {
48 opt.state |= QStyle::State_Raised;
49 }
51 }
52
53 opt.subControls = QStyle::SC_None;
54 opt.features = QStyleOptionToolButton::None;
55 opt.icon = icon();
56
57 // The first icon size is for scaling 1x, and is what QStyle expects. QStyle will pick ones
58 // with higher resolution automatically when needed.
59 const QList<QSize> iconSizes = opt.icon.availableSizes();
60 if (!iconSizes.isEmpty()) {
61 opt.iconSize = iconSizes.constFirst();
62
63 const qreal logicalFactor = logicalDpiX() / 96.0;
64
65 // On Linux there's dozens of window managers and ways of setting the scaling.
66 // Some window managers will just change the font dpi (which affects logical dpi), while
67 // others will only change the device pixel ratio. Take care of both cases.
68 // macOS is easier, as it never changes logical DPI.
69 // On Windows, with AA_EnableHighDpiScaling, logical DPI is always 96 and physical is
70 // manipulated instead.
71#if defined(Q_OS_LINUX)
72 const qreal dpr = devicePixelRatioF();
73 const qreal combinedFactor = logicalFactor * dpr;
74
75 if (scalingFactorIsSupported(combinedFactor)) // Older Qt has rendering bugs with fractional
76 // factors
77 opt.iconSize = opt.iconSize * combinedFactor;
78#elif defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
79 // Probably Windows could use the same code path as Linux, but I'm seeing too thick icons on
80 // Windows...
82 && scalingFactorIsSupported(logicalFactor)) // Older Qt has rendering bugs with
83 // fractional factors
84 opt.iconSize = opt.iconSize * logicalFactor;
85#else
86 Q_UNUSED(logicalFactor);
87#endif
88 }
89
91}
92
94{
95 // Pass an opt so it scales against the logical dpi of the correct screen (since Qt 5.14) even
96 // if the HDPI Qt::AA_ attributes are off.
97 QStyleOption opt;
98 opt.initFrom(this);
99
100 const int m = style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, this);
101 return QSize(m, m);
102}
103
104class KDDockWidgets::QtWidgets::TitleBar::Private
105{
106public:
107 KDBindings::ScopedConnection titleChangedConnection;
108 KDBindings::ScopedConnection iconChangedConnection;
109 KDBindings::ScopedConnection screenChangedConnection;
110 KDBindings::ScopedConnection focusChangedConnection;
111
112 KDBindings::ScopedConnection closeButtonEnabledConnection;
113 KDBindings::ScopedConnection floatButtonToolTipConnection;
114 KDBindings::ScopedConnection floatButtonVisibleConnection;
115 KDBindings::ScopedConnection autoHideButtonConnection;
116 KDBindings::ScopedConnection minimizeButtonConnection;
117 KDBindings::ScopedConnection maximizeButtonConnection;
118};
119
121 : View(controller, Core::ViewType::TitleBar, View_qt::asQWidget(parent))
122 , Core::TitleBarViewInterface(controller)
123 , m_layout(new QHBoxLayout(this))
124 , d(new Private())
125{
126}
127
129 : View(new Core::TitleBar(this), Core::ViewType::TitleBar, parent)
130 , Core::TitleBarViewInterface(static_cast<Core::TitleBar *>(controller()))
131 , m_layout(new QHBoxLayout(this))
132 , d(new Private())
133{
134 m_titleBar->init();
135}
136
138{
139 delete d;
140}
141
143{
147
148 if (!hasCustomLayout()) {
149 m_dockWidgetIcon = new QLabel(this);
153
154 auto factory = static_cast<ViewFactory *>(Config::self().viewFactory());
155 m_maximizeButton = factory->createTitleBarButton(this, TitleBarButtonType::Maximize);
156 m_minimizeButton = factory->createTitleBarButton(this, TitleBarButtonType::Minimize);
157 m_floatButton = factory->createTitleBarButton(this, TitleBarButtonType::Float);
158 m_closeButton = factory->createTitleBarButton(this, TitleBarButtonType::Close);
159 m_autoHideButton = factory->createTitleBarButton(this, TitleBarButtonType::AutoHide);
160
166
168
179
180 m_minimizeButton->setToolTip(tr("Minimize"));
181 m_closeButton->setToolTip(tr("Close"));
182
185
186 d->closeButtonEnabledConnection = m_titleBar->dptr()->closeButtonEnabledChanged.connect([this](bool enabled) { m_closeButton->setEnabled(enabled); });
187 d->floatButtonToolTipConnection = m_titleBar->dptr()->floatButtonToolTipChanged.connect([this](const QString &text) { m_floatButton->setToolTip(text); });
188 d->floatButtonVisibleConnection = m_titleBar->dptr()->floatButtonVisibleChanged.connect([this](bool visible) { m_floatButton->setVisible(visible); });
189 d->autoHideButtonConnection = m_titleBar->dptr()->autoHideButtonChanged.connect([this](bool visible, bool enabled, TitleBarButtonType type) { updateAutoHideButton(visible, enabled, type); });
190 d->minimizeButtonConnection = m_titleBar->dptr()->minimizeButtonChanged.connect([this](bool visible, bool enabled) { updateMinimizeButton(visible, enabled); });
191 d->maximizeButtonConnection = m_titleBar->dptr()->maximizeButtonChanged.connect([this](bool visible, bool enabled, TitleBarButtonType type) { updateMaximizeButton(visible, enabled, type); });
192
193 d->iconChangedConnection = m_titleBar->dptr()->iconChanged.connect([this] { if (m_titleBar->icon().isNull()) {
195 } else {
196 const QPixmap pix = m_titleBar->icon().pixmap(QSize(28, 28));
198 }
199 update(); });
200 }
201
202 d->titleChangedConnection = m_titleBar->dptr()->titleChanged.connect([this] { update(); });
203
204 d->screenChangedConnection = DockRegistry::self()->dptr()->windowChangedScreen.connect([this](Core::Window::Ptr w) {
205 if (View::d->isInWindow(w))
207 });
208
209 d->focusChangedConnection = m_titleBar->dptr()->isFocusedChanged.connect([this] {
211 });
212}
213
215{
216 return m_titleBar;
217}
218
220{
221 if (View::d->freed())
222 return;
223
224 QPainter p(this);
225
226 QStyleOptionDockWidget titleOpt;
227 titleOpt.initFrom(this);
228 style()->drawPrimitive(QStyle::PE_Widget, &titleOpt, &p, this);
229 titleOpt.title = m_titleBar->title();
230 titleOpt.rect = iconRect().isEmpty()
231 ? rect().adjusted(2, 0, -buttonAreaWidth(), 0)
232 : rect().adjusted(iconRect().right(), 0, -buttonAreaWidth(), 0);
233
234 if (m_titleBar->isMDI()) {
235 const QColor c = palette().color(QPalette::Base);
236 p.fillRect(rect().adjusted(1, 1, -1, 0), c);
237 }
238
239 style()->drawControl(QStyle::CE_DockWidgetTitle, &titleOpt, &p, this);
240}
241
242void TitleBar::updateMinimizeButton(bool visible, bool enabled)
243{
244 if (!m_minimizeButton)
245 return;
246
249}
250
251void TitleBar::updateAutoHideButton(bool visible, bool enabled, TitleBarButtonType type)
252{
253 if (!m_autoHideButton)
254 return;
255
257 : tr("Disable auto-hide"));
258 auto factory = Config::self().viewFactory();
259 m_autoHideButton->setIcon(factory->iconForButtonType(type, devicePixelRatioF()));
262}
263
264void TitleBar::updateMaximizeButton(bool visible, bool enabled, TitleBarButtonType type)
265{
266 if (!m_maximizeButton)
267 return;
268
271 if (visible) {
272 auto factory = Config::self().viewFactory();
273 m_maximizeButton->setIcon(factory->iconForButtonType(type, devicePixelRatioF()));
275 : tr("Maximize"));
276 }
277}
278
280{
281 if (m_titleBar->icon().isNull()) {
282 return QRect(0, 0, 0, 0);
283 } else {
284 return QRect(3, 3, 30, 30);
285 }
286}
287
289{
290 int smallestX = width();
291
292 for (auto button :
294 if (button && button->isVisible() && button->x() < smallestX)
295 smallestX = button->x();
296 }
297
298 return width() - smallestX;
299}
300
302{
303 const qreal factor = logicalDpiFactor(this);
304 m_layout->setContentsMargins(QMargins(2, 2, 2, 2) * factor);
305 m_layout->setSpacing(int(2 * factor));
306}
307
309{
310 if (!m_titleBar)
311 return;
312
313 if (e->button() == Qt::LeftButton)
315}
316
318{
319 // Pass an opt so it scales against the logical dpi of the correct screen (since Qt 5.14) even
320 // if the HDPI Qt::AA_ attributes are off.
321 QStyleOption opt;
322 opt.initFrom(this);
323
324 const int height =
326
327 return QSize(0, height);
328}
329
331{
332 if (View::d->freed())
333 return;
334
336 m_titleBar->focus(ev->reason());
337}
338
339#ifdef DOCKS_DEVELOPER_MODE
340
341bool TitleBar::isCloseButtonVisible() const
342{
344}
345
346bool TitleBar::isCloseButtonEnabled() const
347{
349}
350
351bool TitleBar::isFloatButtonVisible() const
352{
354}
355
356#endif
A ScopedConnection is a RAII-style way to make sure a Connection is disconnected.
Definition signal.h:533
Core::ViewFactory * viewFactory() const
getter for the framework view factory
Definition Config.cpp:162
static Config & self()
returns the singleton Config instance
Definition Config.cpp:87
void focus(Qt::FocusReason reason)
bool isMDI() const override
From Draggable interface.
static DockRegistry * self()
void paintEvent(QPaintEvent *) override
friend class KDDockWidgets::Core::TitleBar
void updateMinimizeButton(bool visible, bool enabled)
void mouseDoubleClickEvent(QMouseEvent *) override
void updateMaximizeButton(bool visible, bool enabled, TitleBarButtonType)
Core::TitleBar * titleBar() const
Returns the controller.
void updateAutoHideButton(bool visible, bool enabled, TitleBarButtonType)
The default ViewFactory for QtWidgets frontend.
void setFocusPolicy(Qt::FocusPolicy policy) override
qreal logicalDpiFactor(const QWidget *w)
Class to abstract QAction, so code still works with QtQuick and Flutter.
TitleBarButtonType
describes a type of button you can have in the title bar
void clicked(bool checked)
bool isDown() const const
void addStretch(int stretch)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void setSpacing(int spacing)
bool testAttribute(Qt::ApplicationAttribute attribute)
Qt::FocusReason reason() const const
void setPixmap(const QPixmap &)
void setContentsMargins(int left, int top, int right, int bottom)
const T & constFirst() const const
bool isEmpty() const const
Qt::MouseButton button() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString tr(const char *sourceText, const char *disambiguation, int n)
qreal devicePixelRatioF() const const
int logicalDpiX() const const
void fillRect(const QRectF &rectangle, const QBrush &brush)
bool isEmpty() const const
CE_DockWidgetTitle
PM_SmallIconSize
PE_PanelButtonTool
virtual void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const const=0
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
void initFrom(const QWidget *widget)
AA_EnableHighDpiScaling
StrongFocus
LeftButton
A factory class for allowing the user to customize some internal widgets.
bool isEnabled() const const
virtual void focusInEvent(QFocusEvent *event)
void setSizePolicy(QSizePolicy)
QStyle * style() const const
void setToolTip(const QString &)
bool underMouse() const const
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