KDDockWidgets API Documentation 1.7
Loading...
Searching...
No Matches
MainWindowBase.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2019-2023 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
20#include "MainWindowBase.h"
21#include "private/DockRegistry_p.h"
22#include "private/MDILayoutWidget_p.h"
23#include "private/DropArea_p.h"
24#include "private/Frame_p.h"
25#include "private/Utils_p.h"
26#include "private/SideBar_p.h"
27#include "private/Logging_p.h"
28#include "private/WidgetResizeHandler_p.h"
30#include "private/DropAreaWithCentralFrame_p.h"
31#include "private/LayoutSaver_p.h"
32#include "private/DockWidgetBase_p.h"
33#include "private/multisplitter/Item_p.h"
34
35// Or we can have a createDockWidget() in the factory
36#ifdef KDDOCKWIDGETS_QTQUICK
37#include "DockWidgetQuick.h"
38#else
39#include "DockWidget.h"
40#endif
41
42#include <QCloseEvent>
43
44using namespace KDDockWidgets;
45
46static LayoutWidget *createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
47{
48 if (options & MainWindowOption_MDI)
49 return new MDILayoutWidget(mainWindow);
50
51 return new DropAreaWithCentralFrame(mainWindow, options);
52}
53
54class MainWindowBase::Private
55{
56public:
57 explicit Private(MainWindowBase *mainWindow, const QString &uniqueName, MainWindowOptions options)
58 : m_options(options)
59 , q(mainWindow)
60 , m_layoutWidget(createLayoutWidget(mainWindow, options))
61 , m_persistentCentralDockWidget(createPersistentCentralDockWidget(uniqueName))
62 {
63 }
64
65 bool supportsCentralFrame() const
66 {
67 return m_options & MainWindowOption_HasCentralFrame;
68 }
69
70 bool supportsPersistentCentralWidget() const
71 {
72 if (!dropArea()) {
73 // This is the MDI case
74 return false;
75 }
76
78 }
79
80 DockWidgetBase *createPersistentCentralDockWidget(const QString &uniqueName) const
81 {
82 if (!supportsPersistentCentralWidget())
83 return nullptr;
84
85 auto dw = new DockWidgetType(QStringLiteral("%1-persistentCentralDockWidget").arg(uniqueName));
86 dw->dptr()->m_isPersistentCentralDockWidget = true;
87 Frame *frame = dropArea()->m_centralFrame;
88 if (!frame) {
89 qWarning() << Q_FUNC_INFO << "Expected central frame";
90 return nullptr;
91 }
92
93 frame->addWidget(dw);
94 return dw;
95 }
96
97 DropAreaWithCentralFrame *dropArea() const
98 {
99 return qobject_cast<DropAreaWithCentralFrame *>(m_layoutWidget);
100 }
101
102 CursorPositions allowedResizeSides(SideBarLocation loc) const;
103
104 QRect rectForOverlay(Frame *, SideBarLocation) const;
105 SideBarLocation preferredSideBar(DockWidgetBase *) const;
106 void updateOverlayGeometry(QSize suggestedSize);
107 void clearSideBars();
108
109 QString name;
110 QStringList affinities;
111 const MainWindowOptions m_options;
112 MainWindowBase *const q;
113 QPointer<DockWidgetBase> m_overlayedDockWidget;
114 LayoutWidget *const m_layoutWidget;
115 DockWidgetBase *const m_persistentCentralDockWidget;
116 int m_overlayMargin = 1;
117};
118
119MainWindowBase::MainWindowBase(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
120 WidgetType *parent, Qt::WindowFlags flags)
121 : QMainWindowOrQuick(parent, flags)
122 , d(new Private(this, uniqueName, options))
123{
125
126 connect(d->m_layoutWidget, &LayoutWidget::visibleWidgetCountChanged, this,
128}
129
131{
132 DockRegistry::self()->unregisterMainWindow(this);
133 delete d;
134}
135
137{
138 Q_ASSERT(widget);
139 qCDebug(addwidget) << Q_FUNC_INFO << widget;
140
141 if (!DockRegistry::self()->affinitiesMatch(d->affinities, widget->affinities())) {
142 qWarning() << Q_FUNC_INFO << "Refusing to dock widget with incompatible affinity."
143 << widget->affinities() << affinities();
144 return;
145 }
146
148 qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << widget;
149 return;
150 }
151
152 if (isMDI()) {
153 // Not applicable to MDI
154 return;
155 }
156
157 if (d->supportsPersistentCentralWidget()) {
158 qWarning() << Q_FUNC_INFO << "Not supported with MainWindowOption_HasCentralWidget."
159 << "MainWindowOption_HasCentralWidget can only have 1 widget in the center."
160 << "Use MainWindowOption_HasCentralFrame instead, which is similar but supports tabbing";
161 } else if (d->supportsCentralFrame()) {
162 dropArea()->m_centralFrame->addWidget(widget);
163 } else {
164 qWarning() << Q_FUNC_INFO << "Not supported without MainWindowOption_HasCentralFrame";
165 }
166}
167
169 DockWidgetBase *relativeTo, InitialOption option)
170{
171 Q_ASSERT(dw);
172 if (dw->options() & DockWidgetBase::Option_NotDockable) {
173 qWarning() << Q_FUNC_INFO << "Refusing to dock non-dockable widget" << dw;
174 return;
175 }
176
177 if (isMDI()) {
178 // Not applicable to MDI
179 return;
180 }
181
182 dropArea()->addDockWidget(dw, location, relativeTo, option);
183}
184
186{
187 return d->name;
188}
189
190MainWindowOptions MainWindowBase::options() const
191{
192 return d->m_options;
193}
194
195DropAreaWithCentralFrame *MainWindowBase::dropArea() const
196{
197 return qobject_cast<DropAreaWithCentralFrame *>(d->m_layoutWidget);
198}
199
200MultiSplitter *MainWindowBase::multiSplitter() const
201{
202 return dropArea();
203}
204
205LayoutWidget *MainWindowBase::layoutWidget() const
206{
207 return d->m_layoutWidget;
208}
209
210MDILayoutWidget *MainWindowBase::mdiLayoutWidget() const
211{
213}
214
216{
219
220 if (d->affinities == affinities)
221 return;
222
223 if (!d->affinities.isEmpty()) {
225 << "Affinity is already set, refusing to change."
226 << "Submit a feature request with a good justification.";
227 return;
228 }
229
230 d->affinities = affinities;
231}
232
234{
235 return d->affinities;
236}
237
239{
240 dropArea()->layoutEqually();
241}
242
244{
245 dropArea()->layoutParentContainerEqually(dockWidget);
246}
247
248CursorPositions MainWindowBase::Private::allowedResizeSides(SideBarLocation loc) const
249{
250 // When a sidebar is on top, you can only resize its bottom.
251 // and so forth...
252
253 switch (loc) {
257 return CursorPosition_Left;
261 return CursorPosition_Top;
264 }
265
267}
268
269QRect MainWindowBase::Private::rectForOverlay(Frame *frame, SideBarLocation location) const
270{
271 SideBar *sb = q->sideBar(location);
272 if (!sb)
273 return {};
274
275 const QRect centralAreaGeo = q->centralAreaGeometry();
276 const QMargins centerWidgetMargins = q->centerWidgetMargins();
277
278 QRect rect;
279 const int margin = m_overlayMargin;
280 switch (location) {
283
284 SideBar *leftSideBar = q->sideBar(SideBarLocation::West);
285 SideBar *rightSideBar = q->sideBar(SideBarLocation::East);
286 const int leftSideBarWidth = (leftSideBar && leftSideBar->isVisible()) ? leftSideBar->width()
287 : 0;
288 const int rightSideBarWidth = (rightSideBar && rightSideBar->isVisible()) ? rightSideBar->width()
289 : 0;
290 rect.setHeight(qMax(300, frame->minSize().height()));
291 rect.setWidth(centralAreaGeo.width() - margin * 2 - leftSideBarWidth - rightSideBarWidth);
292 rect.moveLeft(margin + leftSideBarWidth);
293 if (location == SideBarLocation::South) {
294 rect.moveTop(centralAreaGeo.bottom() - centerWidgetMargins.bottom() - rect.height() - sb->height());
295 } else {
296 rect.moveTop(centralAreaGeo.y() + sb->height() + centerWidgetMargins.top());
297 }
298 break;
299 }
302 SideBar *topSideBar = q->sideBar(SideBarLocation::North);
303 SideBar *bottomSideBar = q->sideBar(SideBarLocation::South);
304 const int topSideBarHeight = (topSideBar && topSideBar->isVisible()) ? topSideBar->height()
305 : 0;
306 const int bottomSideBarHeight = (bottomSideBar && bottomSideBar->isVisible()) ? bottomSideBar->height()
307 : 0;
308 rect.setWidth(qMax(300, frame->minSize().width()));
309 rect.setHeight(centralAreaGeo.height() - topSideBarHeight - bottomSideBarHeight - centerWidgetMargins.top() - centerWidgetMargins.bottom());
310 rect.moveTop(sb->mapTo(q, QPoint(0, 0)).y() + topSideBarHeight - 1);
311 if (location == SideBarLocation::East) {
312 rect.moveLeft(centralAreaGeo.x() + centralAreaGeo.width() - rect.width() - sb->width() - centerWidgetMargins.right() - margin);
313 } else {
314 rect.moveLeft(margin + centralAreaGeo.x() + centerWidgetMargins.left() + sb->width());
315 }
316
317 break;
318 }
320 break;
321 }
322
323 return rect;
324}
325
326static SideBarLocation opposedSideBarLocationForBorder(Layouting::LayoutBorderLocation loc)
327{
328 switch (loc) {
329 case Layouting::LayoutBorderLocation_North:
331 case Layouting::LayoutBorderLocation_East:
333 case Layouting::LayoutBorderLocation_West:
335 case Layouting::LayoutBorderLocation_South:
337 case Layouting::LayoutBorderLocation_All:
338 case Layouting::LayoutBorderLocation_Verticals:
339 case Layouting::LayoutBorderLocation_Horizontals:
340 case Layouting::LayoutBorderLocation_None:
341 break;
342 }
343
344 qWarning() << Q_FUNC_INFO << "Unknown loc" << loc;
346}
347
348static SideBarLocation sideBarLocationForBorder(Layouting::LayoutBorderLocations loc)
349{
350 switch (loc) {
351 case Layouting::LayoutBorderLocation_North:
353 case Layouting::LayoutBorderLocation_East:
355 case Layouting::LayoutBorderLocation_West:
357 case Layouting::LayoutBorderLocation_South:
359 case Layouting::LayoutBorderLocation_All:
360 case Layouting::LayoutBorderLocation_Verticals:
361 case Layouting::LayoutBorderLocation_Horizontals:
362 case Layouting::LayoutBorderLocation_None:
363 break;
364 }
365
367}
368
369SideBarLocation MainWindowBase::Private::preferredSideBar(DockWidgetBase *dw) const
370{
371 // TODO: Algorithm can still be made smarter
372
373 Layouting::Item *item = q->layoutWidget()->itemForFrame(dw->d->frame());
374 if (!item) {
375 qWarning() << Q_FUNC_INFO << "No item for dock widget";
377 }
378
379 const Layouting::LayoutBorderLocations borders = item->adjacentLayoutBorders();
380 const qreal aspectRatio = dw->width() / (std::max(1, dw->height()) * 1.0);
381
383 if (borders == Layouting::LayoutBorderLocation_All) {
384 return aspectRatio > 1.0 ? SideBarLocation::South
386 }
387
389 for (auto borderLoc : { Layouting::LayoutBorderLocation_North, Layouting::LayoutBorderLocation_East,
390 Layouting::LayoutBorderLocation_West, Layouting::LayoutBorderLocation_South }) {
391 if (borders == (Layouting::LayoutBorderLocation_All & ~borderLoc))
392 return opposedSideBarLocationForBorder(borderLoc);
393 }
394
396 if ((borders & Layouting::LayoutBorderLocation_Verticals) == Layouting::LayoutBorderLocation_Verticals) {
397 // We could measure the distance to the top though.
399 }
400
402 if ((borders & Layouting::LayoutBorderLocation_Horizontals) == Layouting::LayoutBorderLocation_Horizontals) {
403 // We could measure the distance to the left though.
405 }
406
407 // 5. It's in a corner
408 if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_South)) {
409 return aspectRatio > 1.0 ? SideBarLocation::South
411 } else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_South)) {
412 return aspectRatio > 1.0 ? SideBarLocation::South
414 } else if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_North)) {
415 return aspectRatio > 1.0 ? SideBarLocation::North
417 } else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_North)) {
418 return aspectRatio > 1.0 ? SideBarLocation::North
420 }
421
422
423 {
424 // 6. It's only touching 1 border
426 if (loc != SideBarLocation::None)
427 return loc;
428 }
429
430 // It's not touching any border, use aspect ratio.
431 return aspectRatio > 1.0 ? SideBarLocation::South
433}
434
435void MainWindowBase::Private::updateOverlayGeometry(QSize suggestedSize)
436{
437 if (!m_overlayedDockWidget)
438 return;
439
440 SideBar *sb = q->sideBarForDockWidget(m_overlayedDockWidget);
441 if (!sb) {
442 qWarning() << Q_FUNC_INFO << "Expected a sidebar";
443 return;
444 }
445
446 const QRect defaultGeometry = rectForOverlay(m_overlayedDockWidget->d->frame(), sb->location());
447 QRect newGeometry = defaultGeometry;
448
449 Frame *frame = m_overlayedDockWidget->d->frame();
450
451 if (suggestedSize.isValid() && !suggestedSize.isEmpty()) {
452 // Let's try to honour the suggested overlay size
453 switch (sb->location()) {
455 const int maxHeight = q->height() - frame->pos().y() - 10; // gap
456 newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
457 break;
458 }
460 const int maxHeight = sb->pos().y() - m_layoutWidget->pos().y() - 10; // gap
461 const int bottom = newGeometry.bottom();
462 newGeometry.setHeight(qMin(suggestedSize.height(), maxHeight));
463 newGeometry.moveBottom(bottom);
464 break;
465 }
467 const int maxWidth = sb->pos().x() - m_layoutWidget->pos().x() - 10; // gap
468 const int right = newGeometry.right();
469 newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
470 newGeometry.moveRight(right);
471 break;
472 }
474 const int maxWidth = q->width() - frame->pos().x() - 10; // gap
475 newGeometry.setWidth(qMin(suggestedSize.width(), maxWidth));
476 break;
477 }
479 qWarning() << Q_FUNC_INFO << "Unexpected sidebar value";
480 break;
481 }
482 }
483
484 m_overlayedDockWidget->d->frame()->QWidgetAdapter::setGeometry(newGeometry);
485}
486
487void MainWindowBase::Private::clearSideBars()
488{
491 if (SideBar *sb = q->sideBar(loc))
492 sb->clear();
493 }
494}
495
497{
498 moveToSideBar(dw, d->preferredSideBar(dw));
499}
500
502{
503 if (dw->isPersistentCentralDockWidget())
504 return;
505
506 if (SideBar *sb = sideBar(location)) {
507 QScopedValueRollback<bool> rollback(dw->d->m_isMovingToSideBar, true);
508 dw->forceClose();
509 sb->addDockWidget(dw);
510 } else {
511 // Shouldn't happen
512 qWarning() << Q_FUNC_INFO << "Minimization supported, probably disabled in Config::self().flags()";
513 }
514}
515
517{
518 // First un-overlay it, if it's overlayed
519 if (dw == d->m_overlayedDockWidget)
521
523 if (!sb) {
524 // Doesn't happen
525 qWarning() << Q_FUNC_INFO << "Dock widget isn't in any sidebar";
526 return;
527 }
528
529 sb->removeDockWidget(dw);
530 dw->setFloating(false); // dock it
531}
532
534{
535 if (!dw || dw->isPersistentCentralDockWidget())
536 return;
537
539 if (!sb) {
540 qWarning() << Q_FUNC_INFO << "You need to add the dock widget to the sidebar before you can overlay it";
541 return;
542 }
543
544 if (d->m_overlayedDockWidget == dw) {
545 // Already overlayed
546 return;
547 }
548
549 // We only support one overlay at a time, remove any existing overlay
551
553 d->m_overlayedDockWidget = dw;
554 frame->addWidget(dw);
555 d->updateOverlayGeometry(dw->d->lastPosition()->lastOverlayedGeometry(sb->location()).size());
556 connect(frame, &QWidgetAdapter::widgetGeometryChanged, this, [dw, sb, frame] {
557 dw->d->lastPosition()->setLastOverlayedGeometry(sb->location(), frame->QWidgetAdapter::geometry());
558 });
559
560 frame->setAllowedResizeSides(d->allowedResizeSides(sb->location()));
561 frame->QWidgetAdapter::show();
562
563 Q_EMIT dw->isOverlayedChanged(true);
564}
565
567{
568 const bool wasOverlayed = d->m_overlayedDockWidget == dw;
569 clearSideBarOverlay(); // Because only 1 dock widget can be overlayed each time
570 if (!wasOverlayed) {
572 }
573}
574
576{
577 if (!d->m_overlayedDockWidget)
578 return;
579
580 Frame *frame = d->m_overlayedDockWidget->d->frame();
581 if (!frame) { // prophylactic check
582 d->m_overlayedDockWidget = nullptr;
583 return;
584 }
585
586 frame->disconnect(this);
587 frame->unoverlay();
588
589 if (deleteFrame) {
590 d->m_overlayedDockWidget->setParent(nullptr);
591 Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
592 d->m_overlayedDockWidget = nullptr;
593 delete frame;
594 } else {
595 // No cleanup, just unset. When we drag the overlay it becomes a normal floating window
596 // meaning we reuse Frame. Don't delete it.
597 Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(false);
598 d->m_overlayedDockWidget = nullptr;
599 }
600}
601
603{
606
607 if (SideBar *sb = sideBar(loc)) {
608 if (sb->containsDockWidget(const_cast<DockWidgetBase *>(dw)))
609 return sb;
610 }
611 }
612
613 return nullptr;
614}
615
617{
618 return d->m_overlayedDockWidget;
619}
620
622{
623 if (SideBar *sb = sideBar(loc)) {
624 return !sb->isEmpty(); // isVisible() is always true, but its height is 0 when empty.
625 }
626
627 return false;
628}
629
631{
635 return true;
636 }
637
638 return false;
639}
640
642{
643 return d->m_options & MainWindowOption_MDI;
644}
645
647{
648 bool allClosed = true;
649
650 const auto dockWidgets = d->m_layoutWidget->dockWidgets();
651 for (DockWidgetBase *dw : dockWidgets) {
652 Frame *frame = dw->d->frame();
653
654 if (force) {
655 dw->forceClose();
656 } else {
657 const bool closed = dw->close();
659 }
660
661 if (frame->beingDeletedLater()) {
662 // The dock widget was closed and this frame is empty, delete immediately instead of
663 // waiting. I'm not a big fan of deleting stuff later, as state becomes inconsistent
664
665 // Empty frames are historically deleted later since they are triggered by mouse click
666 // on the title bar, and the title bar is inside the frame.
667 // When doing it programmatically we can delete immediately.
668
669 delete frame;
670 }
671 }
672
673 return allClosed;
674}
675
677{
678 if (uniqueName.isEmpty())
679 return;
680
681 if (d->name.isEmpty()) {
682 d->name = uniqueName;
684 DockRegistry::self()->registerMainWindow(this);
685 } else {
686 qWarning() << Q_FUNC_INFO << "Already has a name." << this->uniqueName() << uniqueName;
687 }
688}
689
691{
692 if (d->m_overlayedDockWidget)
693 d->updateOverlayGeometry(d->m_overlayedDockWidget->d->frame()->QWidgetAdapter::size());
694}
695
696bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw)
697{
698 if (mw.options != options()) {
699 qWarning() << Q_FUNC_INFO << "Refusing to restore MainWindow with different options"
700 << "; expected=" << mw.options << "; has=" << options();
701 return false;
702 }
703
704 if (d->affinities != mw.affinities) {
705 qWarning() << Q_FUNC_INFO << "Affinity name changed from" << d->affinities
706 << "; to" << mw.affinities;
707
708 d->affinities = mw.affinities;
709 }
710
711 const bool success = layoutWidget()->deserialize(mw.multiSplitterLayout);
712
713 // Restore the SideBars
714 d->clearSideBars();
716 SideBar *sb = sideBar(loc);
717 if (!sb)
718 continue;
719
720 const QStringList dockWidgets = mw.dockWidgetsPerSideBar.value(loc);
721 for (const QString &uniqueName : dockWidgets) {
722
723 DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName, DockRegistry::DockByNameFlag::CreateIfNotFound);
724 if (!dw) {
725 qWarning() << Q_FUNC_INFO << "Could not find dock widget" << uniqueName
726 << ". Won't restore it to sidebar";
727 continue;
728 }
729
730 sb->addDockWidget(dw);
731 }
732 }
733
734 // Commented-out for now, we don't want to restore the popup/overlay. popups are perishable
735 // if (!mw.overlayedDockWidget.isEmpty())
736 // overlayOnSideBar(DockRegistry::self()->dockByName(mw.overlayedDockWidget));
737
738 return success;
739}
740
741LayoutSaver::MainWindow MainWindowBase::serialize() const
742{
743 LayoutSaver::MainWindow m;
744
745 m.options = options();
746 m.geometry = windowGeometry();
747 m.normalGeometry = normalGeometry();
748 m.isVisible = isVisible();
749 m.uniqueName = uniqueName();
750 m.screenIndex = screenNumberForWidget(this);
751 m.screenSize = screenSizeForWidget(this);
752 m.multiSplitterLayout = layoutWidget()->serialize();
753 m.affinities = d->affinities;
754 m.windowState = windowHandle() ? windowHandle()->windowState()
756
758 if (SideBar *sb = sideBar(loc)) {
759 const QStringList dockwidgets = sb->serialize();
760 if (!dockwidgets.isEmpty())
761 m.dockWidgetsPerSideBar.insert(loc, dockwidgets);
762 }
763 }
764
765 return m;
766}
767
769{
770 if (QWindow *window = windowHandle())
771 return window->geometry();
772
773 return window()->geometry();
774}
775
777{
778 return d->m_overlayMargin;
779}
780
782{
783 if (margin == d->m_overlayMargin) {
784 return;
785 }
786
787 d->m_overlayMargin = margin;
789}
790
792{
793 if (!d->supportsPersistentCentralWidget()) {
794 qWarning() << "MainWindow::setPersistentCentralWidget() requires MainWindowOption_HasCentralWidget";
795 return;
796 }
797
798 auto dw = d->m_persistentCentralDockWidget;
799 if (dw) {
800 dw->setWidget(widget);
801 } else {
802 qWarning() << Q_FUNC_INFO << "Unexpected null central dock widget";
803 }
804}
805
807{
808 if (auto dw = d->m_persistentCentralDockWidget)
809 return dw->widget();
810
811 return nullptr;
812}
813
815{
816 d->m_layoutWidget->onCloseEvent(e);
817}
Represents a dock widget.
Represents a dock widget.
A factory class for allowing the user to customize some internal widgets.
static LayoutWidget * createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
static SideBarLocation sideBarLocationForBorder(Layouting::LayoutBorderLocations loc)
static SideBarLocation opposedSideBarLocationForBorder(Layouting::LayoutBorderLocation loc)
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
FrameworkWidgetFactory * frameworkWidgetFactory() const
getter for the framework widget factory
Definition Config.cpp:145
static Config & self()
returns the singleton Config instance
Definition Config.cpp:84
The DockWidget base-class. DockWidget and DockWidgetBase are only split in two so we can share some c...
KDDockWidgets::DockWidgetBase::Options options
QStringList affinities() const
Returns the affinity name. Empty by default.
@ Option_NotDockable
The DockWidget can't be docked, it's always floating.
virtual Frame * createFrame(QWidgetOrQuick *parent=nullptr, FrameOptions options=FrameOption_None) const =0
Called internally by the framework to create a Frame class Override to provide your own Frame sub-cla...
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Q_INVOKABLE void toggleOverlayOnSideBar(KDDockWidgets::DockWidgetBase *)
Shows or hides an overlay. It's assumed the dock widget is already in a side-bar.
Q_INVOKABLE void moveToSideBar(KDDockWidgets::DockWidgetBase *)
Moves the dock widget into one of the MainWindow's sidebar. Means the dock widget is removed from the...
MainWindowBase(const QString &uniqueName, MainWindowOptions options=MainWindowOption_HasCentralFrame, WidgetType *parent=nullptr, Qt::WindowFlags flags=Qt::WindowFlags())
virtual SideBar * sideBar(SideBarLocation) const =0
Q_INVOKABLE void overlayOnSideBar(KDDockWidgets::DockWidgetBase *)
Shows the dock widget overlayed on top of the main window, placed next to the sidebar.
DockWidgetBase * overlayedDockWidget() const
returns the dock widget which is currently overlayed. nullptr if none. This is only relevant when usi...
MDILayoutWidget * mdiLayoutWidget() const
Q_INVOKABLE void setPersistentCentralWidget(KDDockWidgets::QWidgetOrQuick *widget)
Sets a persistent central widget. It can't be detached.
Q_INVOKABLE void restoreFromSideBar(KDDockWidgets::DockWidgetBase *)
Removes the dock widget from the sidebar and docks it into the main window again.
void setAffinities(const QStringList &names)
Sets the affinities names. Dock widgets can only dock into main windows of the same affinity.
QRect windowGeometry() const
Returns the window geometry This is usually the same as MainWindowBase::geometry() But fixes the foll...
void setUniqueName(const QString &uniqueName)
Q_INVOKABLE void layoutParentContainerEqually(KDDockWidgets::DockWidgetBase *dockWidget)
like layoutEqually() but starts with the container that has dockWidget. While layoutEqually() starts ...
LayoutWidget * layoutWidget() const
Q_INVOKABLE KDDockWidgets::SideBar * sideBarForDockWidget(const KDDockWidgets::DockWidgetBase *) const
Returns the sidebar this dockwidget is in. nullptr if not in any.
DropAreaWithCentralFrame * dropArea() const
Q_INVOKABLE void clearSideBarOverlay(bool deleteFrame=true)
closes any overlayed dock widget. The sidebar still displays them as button.
void frameCountChanged(int)
emitted when the number of docked frames changes Note that we're using the "Frame" nomenculature inst...
void setOverlayMargin(int margin)
Sets the margin used by overlay docks. Does not modify currently overlayed docks.
Q_INVOKABLE bool sideBarIsVisible(KDDockWidgets::SideBarLocation) const
Returns whether the specified sidebar is visible.
Q_INVOKABLE void addDockWidgetAsTab(KDDockWidgets::DockWidgetBase *dockwidget)
Docks a DockWidget into the central frame, tabbed.
Q_INVOKABLE void layoutEqually()
layouts all the widgets so they have an equal size within their parent container
Q_INVOKABLE void addDockWidget(KDDockWidgets::DockWidgetBase *dockWidget, KDDockWidgets::Location location, KDDockWidgets::DockWidgetBase *relativeTo=nullptr, KDDockWidgets::InitialOption initialOption={})
Docks a DockWidget into this main window.
bool anySideBarIsVisible() const
Returns whether any side bar is visible.
QWidgetOrQuick * persistentCentralWidget() const
KDDockWidgets::MainWindowOptions options
Q_INVOKABLE bool closeDockWidgets(bool force=false)
Closes all dock widgets which are docked into this main window This is convenience to calling DockWid...
MultiSplitter * multiSplitter() const
@ MainWindowOption_MDI
‍Makes the MainWindow always have a central frame, for tabbing documents
@ MainWindowOption_HasCentralWidget
‍The layout will be MDI. DockWidgets can have arbitrary positions, not restricted by any layout
@ MainWindowOption_HasCentralFrame
‍No option set
SideBarLocation
Each main window supports 4 sidebars.
KDDockWidgets::DockWidget DockWidgetType
void insert(int i, const T &value)
int removeAll(const T &value)
T value(int i) const const
int bottom() const const
int left() const const
int right() const const
int top() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
int bottom() const const
int height() const const
void moveBottom(int y)
void moveLeft(int x)
void moveRight(int x)
void moveTop(int y)
int right() const const
void setHeight(int height)
void setWidth(int width)
int width() const const
int x() const const
int y() const const
int height() const const
bool isEmpty() const const
bool isValid() const const
int width() const const
bool isEmpty() const const
WindowNoState
typedef WindowFlags
QTextStream & right(QTextStream &stream)
bool isVisible() const const
QWidget * window() const const
QWindow * windowHandle() const const
Qt::WindowState windowState() const const
Struct describing the preferred dock widget size and visibility when adding it to a layout.

© 2019-2023 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 on Wed Nov 1 2023 00:02:31 for KDDockWidgets API Documentation by doxygen 1.9.8