KDDockWidgets API Documentation 2.1
Loading...
Searching...
No Matches
qtwidgets/views/Stack.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 "Stack.h"
15#include "core/Controller.h"
16#include "core/Stack.h"
17#include "core/TitleBar.h"
18#include "core/Window_p.h"
19#include "core/DockRegistry_p.h"
20#include "core/Stack_p.h"
21#include "Config.h"
22#include "core/View_p.h"
23
25
26#include <QMouseEvent>
27#include <QTabBar>
28#include <QHBoxLayout>
29#include <QAbstractButton>
30#include <QMenu>
31
32#include "kdbindings/signal.h"
33
34using namespace KDDockWidgets;
35using namespace KDDockWidgets::QtWidgets;
36
38class Stack::Private
39{
40public:
41 KDBindings::ScopedConnection tabBarAutoHideChanged;
42 KDBindings::ScopedConnection screenChangedConnection;
43 KDBindings::ScopedConnection buttonsToHideIfDisabledConnection;
44
45 QHBoxLayout *cornerWidgetLayout = nullptr;
46 QAbstractButton *floatButton = nullptr;
47 QAbstractButton *closeButton = nullptr;
48};
49}
50
51
52Stack::Stack(Core::Stack *controller, QWidget *parent)
53 : View<QTabWidget>(controller, Core::ViewType::Stack, parent)
54 , StackViewInterface(controller)
55 , d(new Private())
56{
57}
58
60{
61 delete d;
62}
63
65{
68
71
72 // In case tabs closable is set by the factory, a tabClosedRequested() is emitted when the user
73 // presses [x]
74 connect(this, &QTabWidget::tabCloseRequested, this, [this](int index) {
75 if (auto dw = m_stack->tabBar()->dockWidgetAt(index)) {
76 if (dw->options() & DockWidgetOption_NotClosable) {
77 qWarning() << "QTabWidget::tabCloseRequested: Refusing to close dock widget with "
78 "Option_NotClosable option. name="
79 << dw->uniqueName();
80 } else {
81 dw->view()->close();
82 }
83 } else {
84 qWarning() << "QTabWidget::tabCloseRequested Couldn't find dock widget for index"
85 << index << "; count=" << count();
86 }
87 });
88
89 QTabWidget::setTabBarAutoHide(m_stack->tabBarAutoHide());
90
91 d->tabBarAutoHideChanged = m_stack->d->tabBarAutoHideChanged.connect(
92 [this](bool is) { QTabWidget::setTabBarAutoHide(is); });
93
95 setFocusProxy(nullptr);
96
97 setupTabBarButtons();
98
99 setDocumentMode(m_stack->options() & StackOption_DocumentMode);
100}
101
103{
104 if (m_stack->onMouseDoubleClick(ev->pos())) {
105 ev->accept();
106 } else {
107 ev->ignore();
108 }
109}
110
112{
114
116 && !m_stack->group()->isFocused()) {
117 // User clicked on the tab widget itself
118 m_stack->group()->FocusScope::focus(Qt::MouseFocusReason);
119 }
120}
121
122void Stack::setupTabBarButtons()
123{
125 return;
126
127 auto factory = static_cast<ViewFactory *>(Config::self().viewFactory());
128 d->closeButton = factory->createTitleBarButton(this, TitleBarButtonType::Close);
129 d->floatButton = factory->createTitleBarButton(this, TitleBarButtonType::Float);
130
131 auto cornerWidget = new QWidget(this);
132 cornerWidget->setObjectName(QStringLiteral("Corner Widget"));
133
135
136 d->cornerWidgetLayout = new QHBoxLayout(cornerWidget);
137
138 d->cornerWidgetLayout->addWidget(d->floatButton);
139 d->cornerWidgetLayout->addWidget(d->closeButton);
140
141 connect(d->floatButton, &QAbstractButton::clicked, this, [this] {
142 Core::TitleBar *tb = m_stack->group()->titleBar();
143 tb->onFloatClicked();
144 });
145
146 connect(d->closeButton, &QAbstractButton::clicked, this, [this] {
147 Core::TitleBar *tb = m_stack->group()->titleBar();
148 tb->onCloseClicked();
149 });
150
151 updateMargins();
152 d->screenChangedConnection = DockRegistry::self()->dptr()->windowChangedScreen.connect([this](Core::Window::Ptr w) {
153 if (View::d->isInWindow(w))
154 updateMargins();
155 });
156
157 d->buttonsToHideIfDisabledConnection = m_stack->d->buttonsToHideIfDisabledChanged.connect([this] {
158 updateTabBarButtons();
159 });
160
161 if (auto tb = qobject_cast<QtWidgets::TabBar *>(tabBar()))
162 connect(tb, &QtWidgets::TabBar::countChanged, this, &Stack::updateTabBarButtons);
163
164 updateTabBarButtons();
165}
166
167void Stack::updateTabBarButtons()
168{
169 if (d->closeButton) {
170 const bool enabled = !m_stack->group()->anyNonClosable();
172 d->closeButton->setEnabled(enabled);
173 d->closeButton->setVisible(visible);
174 }
175}
176
177void Stack::updateMargins()
178{
179 const qreal factor = logicalDpiFactor(this);
180 d->cornerWidgetLayout->setContentsMargins(QMargins(0, 0, 2, 0) * factor);
181 d->cornerWidgetLayout->setSpacing(int(2 * factor));
182}
183
185{
187 return;
188
190 // We don't want context menu if there is only one tab
191 if (tabBar->count() <= 1)
192 return;
193
194 // Click on a tab => No menu
195 if (tabBar->tabAt(pos) >= 0)
196 return;
197
198 // Right click is allowed only on the tabs area
199 QRect tabAreaRect = tabBar->rect();
200 tabAreaRect.setWidth(this->width());
201 if (!tabAreaRect.contains(pos))
202 return;
203
204 QMenu menu(this);
205 for (int i = 0; i < tabBar->count(); ++i) {
206 QAction *action = menu.addAction(tabText(i), this, [this, i] { setCurrentIndex(i); });
207 if (i == currentIndex())
208 action->setDisabled(true);
209 }
210 menu.exec(mapToGlobal(pos));
211}
212
214{
215 return static_cast<QTabBar *>(View_qt::asQWidget((m_stack->tabBar())));
216}
217
222
224{
225 return m_stack;
226}
227
229{
231 qWarning() << Q_FUNC_INFO << "Not implemented yet. Only North is supported";
232 return false;
233 }
234
235 return p.y() >= 0 && p.y() <= tabBar()->height();
236}
237
239{
240 switch (type) {
241
243 return d->closeButton;
245 return d->floatButton;
252 return nullptr;
253 }
254
255 return nullptr;
256}
Application-wide config to tune certain behaviours of the framework.
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:182
static Config & self()
returns the singleton Config instance
Definition Config.cpp:88
@ Flag_ShowButtonsOnTabBarIfTitleBarHidden
Definition Config.h:125
@ Flag_TabsHaveCloseButton
Tabs will have a close button. Equivalent to QTabWidget::setTabsClosable(true).
Definition Config.h:93
bool isFocused() const
Returns true if this FocusScope is focused. This is similar to the QWidget::hasFocus(),...
Group * group() const
getter for the group
Core::TabBar * tabBar() const
Returns the tab bar.
bool buttonHidesIfDisabled(TitleBarButtonType) const
bool onMouseDoubleClick(Point localPos)
DockWidget * dockWidgetAt(int index) const
returns the dock widgets at tab number index
virtual bool is(ViewType) const
Returns whether the view is of the specified type Virtual so it can be overridden by ViewWrapper....
static DockRegistry * self()
void setDocumentMode(bool) override
Sets QTabWidget::documentMode(). Only implemented for QtWidgets. Probably not interesting for other f...
Core::Stack * stack() const
Returns the controller.
bool isPositionDraggable(QPoint p) const override
virtual void showContextMenu(QPoint pos)
Shows the context menu. Override to implement your own context menu. By default it's used to honour C...
Stack(Core::Stack *controller, QWidget *parent=nullptr)
void mousePressEvent(QMouseEvent *) override
QAbstractButton * button(TitleBarButtonType) const
Returns the requested button. Only relevant with Flag_ShowButtonsOnTabBarIfTitleBarHidden.
void mouseDoubleClickEvent(QMouseEvent *) override
QTabBar * tabBar() const
Returns the QTabBar associated with this QTabWidget.
The default ViewFactory for QtWidgets frontend.
QPoint mapToGlobal(QPoint localPt) const 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)
void setDisabled(bool b)
void accept()
void ignore()
QAction * addAction(const QString &text)
QAction * exec()
QPoint pos() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setObjectName(const QString &name)
int y() const const
bool contains(const QRect &rectangle, bool proper) const const
void setWidth(int width)
CustomContextMenu
TopRightCorner
MouseFocusReason
int tabAt(const QPoint &position) const const
QWidget * cornerWidget(Qt::Corner corner) const const
void setCurrentIndex(int index)
void setDocumentMode(bool set)
void setCornerWidget(QWidget *widget, Qt::Corner corner)
void setTabBar(QTabBar *tb)
QTabBar * tabBar() const const
void setTabBarAutoHide(bool enabled)
void tabCloseRequested(int index)
QString tabText(int index) const const
void setTabsClosable(bool closeable)
A factory class for allowing the user to customize some internal widgets.
Represents a dock widget.
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
void customContextMenuRequested(const QPoint &pos)
virtual void mousePressEvent(QMouseEvent *event)
bool isVisible() const const

© 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