KDDockWidgets API Documentation 2.1
Loading...
Searching...
No Matches
qtquick/views/Group.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
19#include "Group.h"
20
22#include "qtquick/ViewFactory.h"
23#include "qtquick/Platform.h"
25#include "qtquick/views/ViewWrapper_p.h"
26
27#include "kddockwidgets/core/Group.h"
28#include "kddockwidgets/core/Stack.h"
29#include "kddockwidgets/core/TitleBar.h"
30#include "kddockwidgets/core/DockWidget.h"
31#include "core/DockWidget_p.h"
32#include "core/Group_p.h"
33#include "core/layouting/Item_p.h"
34#include "core/Logging_p.h"
35#include "core/MDILayout.h"
36
37#include "Stack.h"
38#include "Config.h"
39#include "core/WidgetResizeHandler_p.h"
40#include "core/TabBar_p.h"
41
42#include <QDebug>
43
44using namespace KDDockWidgets;
45using namespace KDDockWidgets::QtQuick;
46
47namespace KDDockWidgets::QtQuick {
48
49class Group::Private
50{
51public:
52 KDBindings::ScopedConnection isMDIConnection;
53 KDBindings::ScopedConnection currentDockWidgetChangedConnection;
54 KDBindings::ScopedConnection updateConstraintsConnection;
55};
56
57}
58
59Group::Group(Core::Group *controller, QQuickItem *parent)
60 : QtQuick::View(controller, Core::ViewType::Group, parent)
61 , Core::GroupViewInterface(controller)
62 , d(new Private())
63{
64}
65
67{
68 delete d;
69
70 // The QML item must be deleted with deleteLater(), as we might be currently with its mouse
71 // handler in the stack. QML doesn't support it being deleted in that case.
72 // So unparent it and deleteLater().
73 m_visualItem->setParent(nullptr);
74 m_visualItem->deleteLater();
75}
76
77void Group::init()
78{
79 d->updateConstraintsConnection = m_group->tabBar()->dptr()->countChanged.connect([this] {
81 });
82
83 d->currentDockWidgetChangedConnection = m_group->tabBar()->dptr()->currentDockWidgetChanged.connect([this] {
85 });
86
87 connect(this, &View::geometryUpdated, this,
88 [this] { Core::View::d->layoutInvalidated.emit(); });
89
90 d->isMDIConnection = m_group->dptr()->isMDIChanged.connect([this] { Q_EMIT isMDIChanged(); });
91
92 // Minor hack: While the controllers keep track of "current widget",
93 // the QML StackLayout deals in "current index", these can differ when removing a non-current
94 // tab. The currentDockWidgetChanged() won't be emitted but the index did decrement.
95 // As a workaround, always emit the signal, which is harmless if not needed.
96
97 m_group->dptr()->numDockWidgetsChanged.connect([this] { Q_EMIT currentDockWidgetChanged(); });
98 m_group->dptr()->actualTitleBarChanged.connect([this] { Q_EMIT actualTitleBarChanged(); });
99
100 connect(this, &View::itemGeometryChanged, this, [this] {
101 const auto docks = m_group->dockWidgets();
102 for (auto dw : docks) {
103 auto dwView = static_cast<DockWidget *>(QtQuick::asView_qtquick(dw->view()));
104 Q_EMIT dwView->groupGeometryChanged(geometry());
105 }
106 });
107
108 QQmlComponent component(plat()->qmlEngine(), plat()->viewFactory()->groupFilename());
109
110 m_visualItem = static_cast<QQuickItem *>(component.create());
111
112 if (!m_visualItem) {
113 qWarning() << Q_FUNC_INFO << "Failed to create item" << component.errorString();
114 return;
115 }
116
117 m_visualItem->setProperty("groupCpp", QVariant::fromValue(this));
118 m_visualItem->setParentItem(this);
119 m_visualItem->setParent(this);
120}
121
123{
125
126 // QtQuick doesn't have layouts, so we need to do constraint propagation manually
127
128 setProperty("kddockwidgets_min_size", minSize());
129 setProperty("kddockwidgets_max_size", maxSizeHint());
130
131 Core::View::d->layoutInvalidated.emit();
132}
133
138
140{
141 return m_group->currentIndex();
142}
143
145{
146 QPointer<Core::Group> oldFrame = dw->d->group();
147 m_group->tabBar()->insertDockWidget(index, dw, {}, {});
148
149 dw->setParentView(ViewWrapper::create(m_stackLayout).get());
150 makeItemFillParent(View::asQQuickItem(dw->view()));
152
153 if (oldFrame && oldFrame->beingDeletedLater()) {
154 // give it a push and delete it immediately.
155 // Having too many deleteLater() puts us in an inconsistent state. For example if
156 // LayoutSaver::saveState() would to be called while the Frame hadn't been deleted yet
157 // it would count with that group unless hacks. Also the unit-tests are full of
158 // waitForDeleted() due to deleteLater.
159
160 // Ideally we would just remove the deleteLater from Group.cpp, but
161 // QTabWidget::insertTab() would crash, as it accesses the old tab-widget we're stealing
162 // from
163
164 delete oldFrame;
165 }
166}
167
168void Group::setStackLayout(QQuickItem *stackLayout)
169{
170 if (m_stackLayout || !stackLayout) {
171 qWarning() << Q_FUNC_INFO << "Shouldn't happen";
172 return;
173 }
174
175 m_stackLayout = stackLayout;
176}
177
179{
180 if (auto handler = m_group->resizeHandler()) {
181 if (handler->enabled()) {
183 KDDW_ERROR("Group::startMDIResize: Handler is already enabled!");
184 } else {
185 handler->setEnabled(true);
186 }
187 } else {
188 KDDW_ERROR("Group::startMDIResize: No WidgetResizeHandler found. isMDI={}", isMDI());
189 }
190}
191
193{
194 const QSize contentsSize = m_group->dockWidgetsMinSize();
195 return contentsSize + QSize(0, nonContentsHeight());
196}
197
199{
200 if (isMDI()) {
201 const auto dockwidgets = m_group->dockWidgets();
202 if (dockwidgets.size() == 1) {
203 auto dw = dockwidgets[0];
204 if (dw->inDtor()) {
205 // Destruction case, nothing to do
206 return View::maxSizeHint();
207 }
208
209 return (dw->view()->maxSizeHint() + QSize(0, nonContentsHeight())).boundedTo(Core::Item::hardcodedMaximumSize);
210 } else {
211 KDDW_WARN("Group::maxSizeHint: Max size not supported for mixed MDI case yet");
212 }
213 }
214
215 return View::maxSizeHint();
216}
217
219{
220 return tabBarView();
221}
222
223QQuickItem *Group::visualItem() const
224{
225 return m_visualItem;
226}
227
229{
230 return m_visualItem->property("nonContentsHeight").toInt();
231}
232
233Stack *Group::stackView() const
234{
235 if (auto stack = m_group->stack())
236 return qobject_cast<Stack *>(asQQuickItem(stack->view()));
237
238 return nullptr;
239}
240
241TabBar *Group::tabBarView() const
242{
243 if (auto tabBar = m_group->tabBar())
244 return qobject_cast<TabBar *>(asQQuickItem(tabBar->view()));
245
246 return nullptr;
247}
248
250{
251 if (auto tb = m_group->titleBar()) {
252 return dynamic_cast<KDDockWidgets::QtQuick::TitleBar *>(tb->view());
253 }
254
255 return nullptr;
256}
257
259{
260 if (auto tb = m_group->actualTitleBar()) {
261 return dynamic_cast<KDDockWidgets::QtQuick::TitleBar *>(tb->view());
262 }
263
264 return nullptr;
265}
266
268{
269 return 0;
270}
271
273{
274 if (!isMDI() || m_inDtor)
275 return;
276
277 auto layout = m_group->mdiLayout();
278 if (!layout)
279 return;
280
281 layout->resizeDockWidget(m_group, sz);
282}
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
void setParentView(View *parent)
View * view() const
Returns the view associated with this controller, if any.
The DockWidget base-class. DockWidget and Core::DockWidget are only split in two so we can share some...
Core::TitleBar * titleBar() const
Vector< DockWidget * > dockWidgets() const
WidgetResizeHandler * resizeHandler() const
Returns the resize handler. Used mostly in MDI mode.
void setCurrentDockWidget(DockWidget *)
Sets the specified dock widget to be the current tab.
int currentIndex() const
returns the index of the current tab
Size dockWidgetsMinSize() const
Returns the minimum size of the dock widgets. This might be slightly smaller than Frame::minSize() du...
Core::Stack * stack() const
returns the tab widget
Core::TitleBar * actualTitleBar() const
Core::TabBar * tabBar() const
MDILayout * mdiLayout() const
Returns the MDI layout. Or nullptr if this group isn't in a MDI layout.
void resizeDockWidget(Core::DockWidget *dw, Size size)
Sets the size of dock widget dw to size.
void removeDockWidget(Core::DockWidget *dw)
void insertDockWidget(int index, Core::DockWidget *dw, const Icon &icon, const QString &title)
void groupGeometryChanged(QRect)
The geometry of the group container this dock widget is in changed For example, when dragging a dockw...
QSize minSize() const override
Reimplemented for internal purposes. .
QSize maxSizeHint() const override
Reimplemented for internal purposes. .
Group(Core::Group *controller, QQuickItem *parent=nullptr)
Q_INVOKABLE void setStackLayout(QQuickItem *)
int nonContentsHeight() const override
Returns the height of the "non-dockwidget" part. i.e.: the height of the titlebar (if any),...
void removeDockWidget(Core::DockWidget *dw) override
Q_INVOKABLE void setMDISize(QSize)
Sets the size of this group in the MDI layout.
QQuickItem * visualItem() const override
Returns the QQuickItem which represents this group on the screen.
void insertDockWidget(Core::DockWidget *dw, int index) override
KDDockWidgets::QtQuick::TitleBar * actualTitleBar
KDDockWidgets::QtQuick::TitleBar * titleBar
QSize maxSizeHint() const override
static void makeItemFillParent(QQuickItem *item)
This is equivalent to "anchors.fill: parent but in C++.
View * asView_qtquick(Core::View *view)
QQuickItem * asQQuickItem(Core::View *view)
Class to abstract QAction, so code still works with QtQuick and Flutter.
QtQuick::Platform * plat()
void connect(T &&future, QObjectSubclass *context, Callback func)
Definition qcorotask.h:721
A factory class for allowing the user to customize some internal widgets.
Represents a dock widget.
Implements a QTabWidget derived class with support for docking and undocking KDockWidget::DockWidget ...
QVariant fromValue(const T &value)

© 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