KDDockWidgets API Documentation 2.0
Loading...
Searching...
No Matches
core/DropArea.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 "DropArea.h"
13#include "Layout_p.h"
14#include "Config.h"
15#include "core/ViewFactory.h"
16#include "DockRegistry.h"
17#include "Platform.h"
18#include "core/Draggable_p.h"
19#include "core/Logging_p.h"
20#include "core/Utils_p.h"
21#include "core/layouting/Item_p.h"
22#include "core/layouting/LayoutingGuest_p.h"
23#include "core/layouting/LayoutingSeparator_p.h"
24#include "core/WindowBeingDragged_p.h"
25#include "core/DelayedCall_p.h"
26#include "core/Group.h"
27#include "core/FloatingWindow.h"
28#include "core/DockWidget_p.h"
29#include "core/MainWindow.h"
34
35#include "Window_p.h"
36#include "kdbindings/signal.h"
37
38#include <algorithm>
39
40using namespace KDDockWidgets;
41using namespace KDDockWidgets::Core;
42
43namespace KDDockWidgets {
58
59namespace Core {
60class DropArea::Private
61{
62public:
63 explicit Private(DropArea *q, MainWindowOptions options, bool isMDIWrapper)
64 : m_isMDIWrapper(isMDIWrapper)
65 , m_dropIndicatorOverlay(createDropIndicatorOverlay(q))
66 , m_centralGroup(createCentralGroup(options))
67 {
68 }
69
70 bool m_inDestructor = false;
71 const bool m_isMDIWrapper;
72 QString m_affinityName;
73 ObjectGuard<DropIndicatorOverlay> m_dropIndicatorOverlay;
74 Core::Group *const m_centralGroup = nullptr;
75 Core::ItemBoxContainer *m_rootItem = nullptr;
76 KDBindings::ScopedConnection m_visibleWidgetCountConnection;
77};
78}
79
80}
81
82DropArea::DropArea(View *parent, MainWindowOptions options, bool isMDIWrapper)
83 : Layout(ViewType::DropArea, Config::self().viewFactory()->createDropArea(this, parent))
84 , d(new Private(this, options, isMDIWrapper))
85{
86 setRootItem(new Core::ItemBoxContainer(asLayoutingHost()));
87
88 if (parent)
89 setLayoutSize(parent->size());
90
91 // Initialize min size
93
94 KDDW_TRACE("DropArea CTOR");
95
96 if (d->m_isMDIWrapper) {
97 d->m_visibleWidgetCountConnection = Layout::d_ptr()->visibleWidgetCountChanged.connect([this] {
98 auto dw = mdiDockWidgetWrapper();
99 if (!dw) {
100 KDDW_ERROR("Unexpected null wrapper dock widget");
101 return;
102 }
103
104 if (visibleCount() > 0) {
105 // The title of our MDI group will need to change to the app name if we have more
106 // than 1 dock widget nested
107 dw->d->titleChanged.emit(dw->title());
108 } else {
109 // Our wrapeper isn't needed anymore
110 dw->destroyLater();
111 }
112 });
113 }
114
115 if (d->m_centralGroup)
116 addWidget(d->m_centralGroup->view(), KDDockWidgets::Location_OnTop, {});
117}
118
120{
121 d->m_inDestructor = true;
122 delete d->m_dropIndicatorOverlay;
123 delete d;
124 KDDW_TRACE("~DropArea");
125}
126
128{
129 const Core::Item::List children = d->m_rootItem->items_recursive();
131
132 for (const Core::Item *child : children) {
133 if (auto guest = child->guest()) {
134 if (!guest->freed()) {
135 if (auto group = Group::fromItem(child)) {
136 groups.push_back(group);
137 }
138 }
139 }
140 }
141
142 return groups;
143}
144
145Core::Group *DropArea::groupContainingPos(Point globalPos) const
146{
147 const Core::Item::List &items = this->items();
148 for (Core::Item *item : items) {
149 auto group = Group::fromItem(item);
150 if (!group || !group->isVisible()) {
151 continue;
152 }
153
154 if (group->containsMouse(globalPos))
155 return group;
156 }
157 return nullptr;
158}
159
160void DropArea::updateFloatingActions()
161{
162 const Core::Group::List groups = this->groups();
163 for (Core::Group *group : groups)
164 group->updateFloatingActions();
165}
166
167Core::Item *DropArea::centralFrame() const
168{
169 const auto items = this->items();
170 for (Core::Item *item : items) {
171 if (auto group = Group::fromItem(item)) {
172 if (group->isCentralGroup())
173 return item;
174 }
175 }
176 return nullptr;
177}
178
180{
181 return d->m_dropIndicatorOverlay;
182}
183
185 Core::DockWidget *relativeTo, const InitialOption &option)
186{
187 if (!dw || dw == relativeTo || location == Location_None) {
188 KDDW_ERROR("Invalid parameters {}, {} {}", ( void * )dw, ( void * )relativeTo, location);
189 return;
190 }
191
192 Core::Group *relativeToGroup = relativeTo ? relativeTo->d->group() : nullptr;
193 Core::Item *relativeToItem = relativeToGroup ? relativeToGroup->layoutItem() : nullptr;
194 _addDockWidget(dw, location, relativeToItem, option);
195}
196
198 Core::Item *relativeToItem, const InitialOption &option)
199{
200 if (!dw || location == Location_None) {
201 KDDW_ERROR("Invalid parameters {}, {}", ( void * )dw, location);
202 return;
203 }
204
205 if ((option.visibility == InitialVisibilityOption::StartHidden) && dw->d->group() != nullptr) {
206 // StartHidden is just to be used at startup, not for moving stuff around
207 KDDW_ERROR("Dock widget was already opened, can't be used with InitialVisibilityOption::StartHidden");
208 return;
209 }
210
211 if (!validateAffinity(dw))
212 return;
213
214 Core::DockWidget::Private::UpdateActions actionsUpdater(dw);
215
216 Core::Group *group = nullptr;
217
218 dw->d->saveLastFloatingGeometry();
219
220 const bool hadSingleFloatingGroup = hasSingleFloatingGroup();
221
222 // Check if the dock widget already exists in the layout
223 if (containsDockWidget(dw)) {
224 Core::Group *oldGroup = dw->d->group();
225 if (oldGroup->hasSingleDockWidget()) {
226 assert(oldGroup->containsDockWidget(dw));
227 // The group only has this dock widget, and the group is already in the layout. So move
228 // the group instead
229 group = oldGroup;
230 } else {
231 group = new Core::Group();
232 group->addTab(dw);
233 }
234 } else {
235 group = new Core::Group();
236 group->addTab(dw);
237 }
238
239 if (option.startsHidden()) {
240 addWidget(dw->view(), location, relativeToItem, option);
241 } else {
242 addWidget(group->view(), location, relativeToItem, option);
243 }
244
245 if (hadSingleFloatingGroup && !hasSingleFloatingGroup()) {
246 // The dock widgets that already existed in our layout need to have their floatAction()
247 // updated otherwise it's still checked. Only the dropped dock widget got updated
248 updateFloatingActions();
249 }
250}
251
253{
254 return dw->d->group() && Layout::containsGroup(dw->d->group());
255}
256
258{
259 const Core::Group::List groups = this->groups();
260 return groups.size() == 1 && groups.first()->isFloating();
261}
262
264{
265 return visibleCount() == 1;
266}
267
269{
270 if (auto mw = mainWindow()) {
271 return mw->affinities();
272 } else if (auto fw = floatingWindow()) {
273 return fw->affinities();
274 }
275
276 return {};
277}
278
280{
281 Core::Item *item = itemForGroup(dw->d->group());
282 if (!item) {
283 KDDW_ERROR("Item not found for dw={}, group={}", ( void * )dw, ( void * )dw->d->group());
284 return;
285 }
286
287 layoutEqually(item->parentBoxContainer());
288}
289
290DropLocation DropArea::hover(WindowBeingDragged *draggedWindow, Point globalPos)
291{
292 if (Config::self().dropIndicatorsInhibited() || !validateAffinity(draggedWindow))
293 return DropLocation_None;
294
295 if (!d->m_dropIndicatorOverlay) {
296 KDDW_ERROR("The frontend is missing a drop indicator overlay");
297 return DropLocation_None;
298 }
299
300 Core::Group *group = groupContainingPos(
301 globalPos); // Group is nullptr if MainWindowOption_HasCentralFrame isn't set
302 d->m_dropIndicatorOverlay->setWindowBeingDragged(true);
303 d->m_dropIndicatorOverlay->setHoveredGroup(group);
304 draggedWindow->updateTransparency(true);
305
306 return d->m_dropIndicatorOverlay->hover(globalPos);
307}
308
309static bool isOutterLocation(DropLocation location)
310{
311 switch (location) {
316 return true;
317 default:
318 return false;
319 }
320}
321
322bool DropArea::drop(WindowBeingDragged *droppedWindow, Point globalPos)
323{
324 // fv might be null, if on wayland
325 Core::View *fv = droppedWindow->floatingWindowView();
326
327 if (fv && fv->equals(window())) {
328 KDDW_ERROR("Refusing to drop onto itself"); // Doesn't happen
329 return false;
330 }
331
332 if (d->m_dropIndicatorOverlay->currentDropLocation() == DropLocation_None) {
333 KDDW_DEBUG("DropArea::drop: bailing out, drop location = none");
334 return false;
335 }
336
337 KDDW_DEBUG("DropArea::drop: {}", ( void * )droppedWindow);
338
339 hover(droppedWindow, globalPos);
340 auto droploc = d->m_dropIndicatorOverlay->currentDropLocation();
341 Core::Group *acceptingGroup = d->m_dropIndicatorOverlay->hoveredGroup();
342 if (!(acceptingGroup || isOutterLocation(droploc))) {
343 KDDW_ERROR("DropArea::drop: asserted with group={}, location={}", ( void * )acceptingGroup, droploc);
344 return false;
345 }
346
347 return drop(droppedWindow, acceptingGroup, droploc);
348}
349
350bool DropArea::drop(WindowBeingDragged *draggedWindow, Core::Group *acceptingGroup,
351 DropLocation droploc)
352{
353 Core::FloatingWindow *droppedWindow =
354 draggedWindow ? draggedWindow->floatingWindow() : nullptr;
355
356 if (isWayland() && !droppedWindow) {
357 // This is the Wayland special case.
358 // With other platforms, when detaching a tab or dock widget we create the FloatingWindow
359 // immediately. With Wayland we delay the floating window until we drop it. Ofc, we could
360 // just dock the dockwidget without the temporary FloatingWindow, but this way we reuse 99%
361 // of the rest of the code, without adding more wayland special cases
362 droppedWindow =
363 draggedWindow ? draggedWindow->draggable()->makeWindow()->floatingWindow() : nullptr;
364 if (!droppedWindow) {
365 // Doesn't happen
366 KDDW_ERROR("Wayland: Expected window {}", ( void * )draggedWindow);
367 return false;
368 }
369 }
370
371 bool result = true;
372 const bool needToFocusNewlyDroppedWidgets =
374 const Core::DockWidget::List droppedDockWidgets = needToFocusNewlyDroppedWidgets
375 ? droppedWindow->layout()->dockWidgets()
376 : Core::DockWidget::List(); // just so save some memory allocations for the case
377 // where this
378 // variable isn't used
379
380 switch (droploc) {
382 case DropLocation_Top:
385 result = drop(droppedWindow->view(),
386 DropIndicatorOverlay::multisplitterLocationFor(droploc), acceptingGroup);
387 break;
392 result = drop(droppedWindow->view(),
394 break;
396 KDDW_DEBUG("Tabbing window={} into group={}", ( void * )droppedWindow, ( void * )acceptingGroup);
397
398 if (!validateAffinity(droppedWindow, acceptingGroup))
399 return false;
400 acceptingGroup->addTab(droppedWindow);
401 break;
402
403 default:
404 KDDW_ERROR("DropArea::drop: Unexpected drop location = {}", d->m_dropIndicatorOverlay->currentDropLocation());
405 result = false;
406 break;
407 }
408
409 if (result) {
410 // Window receiving the drop gets raised
411 // Window receiving the drop gets raised.
412 // Exception: Under EGLFS we don't raise the fullscreen main window, as then all floating
413 // windows would go behind. It's also unneeded to raise, as it's fullscreen.
414
415 const bool isEGLFSRootWindow =
416 isEGLFS() && (view()->window()->isFullScreen() || window()->isMaximized());
417 if (!isEGLFSRootWindow)
419
420 if (needToFocusNewlyDroppedWidgets) {
421 // Let's also focus the newly dropped dock widget
422 if (!droppedDockWidgets.isEmpty()) {
423 // If more than 1 was dropped, we only focus the first one
424 Core::Group *group = droppedDockWidgets.first()->d->group();
425 group->FocusScope::focus(Qt::MouseFocusReason);
426 } else {
427 // Doesn't happen.
428 KDDW_ERROR("Nothing was dropped?");
429 }
430 }
431 }
432
433 return result;
434}
435
436bool DropArea::drop(View *droppedWindow, KDDockWidgets::Location location,
437 Core::Group *relativeTo)
438{
439 KDDW_DEBUG("DropArea::drop");
440
441 if (auto dock = droppedWindow->asDockWidgetController()) {
442 if (!validateAffinity(dock))
443 return false;
444
445 auto group = new Core::Group();
446 group->addTab(dock);
447 Item *relativeToItem = relativeTo ? relativeTo->layoutItem() : nullptr;
448 addWidget(group->view(), location, relativeToItem, DefaultSizeMode::FairButFloor);
449 } else if (auto floatingWindow = droppedWindow->asFloatingWindowController()) {
450 if (!validateAffinity(floatingWindow))
451 return false;
452
453 addMultiSplitter(floatingWindow->dropArea(), location, relativeTo,
455
457 return true;
458 } else {
459 KDDW_ERROR("Unknown dropped widget {}", ( void * )droppedWindow);
460 return false;
461 }
462
463 return true;
464}
465
467{
468 d->m_dropIndicatorOverlay->removeHover();
469}
470
471template<typename T>
472bool DropArea::validateAffinity(T *window, Core::Group *acceptingGroup) const
473{
474 if (!DockRegistry::self()->affinitiesMatch(window->affinities(), affinities())) {
475 return false;
476 }
477
478 if (acceptingGroup) {
479 // We're dropping into another group (as tabbed), so also check the affinity of the group
480 // not only of the main window, which might be more forgiving
481 if (!DockRegistry::self()->affinitiesMatch(window->affinities(),
482 acceptingGroup->affinities())) {
483 return false;
484 }
485 }
486
487 return true;
488}
489
491{
492 return d->m_isMDIWrapper;
493}
494
496{
497 if (d->m_isMDIWrapper) {
498 return view()->parentView()->asDockWidgetController();
499 }
500
501 return nullptr;
502}
503
504Core::Group *DropArea::createCentralGroup(MainWindowOptions options)
505{
506 Core::Group *group = nullptr;
507
508 if (options & MainWindowOption_HasCentralFrame) {
509 FrameOptions groupOptions = FrameOption_IsCentralFrame;
510 const bool hasPersistentCentralWidget =
512 if (hasPersistentCentralWidget) {
513 groupOptions |= FrameOption_NonDockable;
514 } else {
515 // With a persistent central widget we don't allow detaching it
516 groupOptions |= FrameOption_AlwaysShowsTabs;
517 }
518
519 group = new Core::Group(nullptr, groupOptions);
520 group->setObjectName(QStringLiteral("central group"));
521 }
522
523 return group;
524}
525
526bool DropArea::validateInputs(View *widget, Location location,
527 const Core::Item *relativeToItem, const InitialOption &option) const
528{
529 if (!widget) {
530 KDDW_ERROR("Widget is null");
531 return false;
532 }
533
534 const bool isDockWidget = widget->is(ViewType::DockWidget);
535 const bool isStartHidden = option.startsHidden();
536
537 const bool isLayout = widget->is(ViewType::DropArea) || widget->is(ViewType::MDILayout);
538 if (!widget->is(ViewType::Group) && !isLayout && !isDockWidget) {
539 KDDW_ERROR("Unknown widget type {}", ( void * )widget);
540 return false;
541 }
542
543 if (isDockWidget != isStartHidden) {
544 KDDW_ERROR("Wrong parameters isDockWidget={}, isStartHidden={}", isDockWidget, isStartHidden);
545 return false;
546 }
547
548 if (relativeToItem) {
549 auto relativeToGroup = Group::fromItem(relativeToItem);
550 if (relativeToGroup && relativeToGroup->view()->equals(widget)) {
551 KDDW_ERROR("widget can't be relative to itself");
552 return false;
553 }
554 }
555
556 Core::Item *item = itemForGroup(widget->asGroupController());
557
558 if (containsItem(item)) {
559 KDDW_ERROR("DropArea::addWidget: Already contains w={}", ( void * )widget);
560 return false;
561 }
562
563 if (location == Location_None) {
564 KDDW_ERROR("DropArea::addWidget: not adding to location None");
565 return false;
566 }
567
568 const bool relativeToThis = relativeToItem == nullptr;
569 if (!relativeToThis && !containsItem(relativeToItem)) {
570 KDDW_ERROR("DropArea::addWidget: Doesn't contain relativeTo: relativeToItem{}, options={}", "; relativeToItem=", ( void * )relativeToItem, option);
571 return false;
572 }
573
574 return true;
575}
576
577void DropArea::addWidget(View *w, Location location, Core::Item *relativeToItem,
578 const InitialOption &option)
579{
580
581 auto group = w->asGroupController();
582 if (itemForGroup(group) != nullptr) {
583 // Item already exists, remove it.
584 // Changing the group parent will make the item clean itself up. It turns into a placeholder
585 // and is removed by unrefOldPlaceholders
586 group->setParentView(nullptr); // so ~Item doesn't delete it
587 group->setLayoutItem(nullptr); // so Item is destroyed, as there's no refs to it
588 }
589
590 // Make some sanity checks:
591 if (!validateInputs(w, location, relativeToItem, option))
592 return;
593
594 if (!relativeToItem)
595 relativeToItem = d->m_rootItem;
596
597 Core::Item *newItem = nullptr;
598
601 auto dw = w->asDockWidgetController();
602
603 if (group) {
604 newItem = new Core::Item(asLayoutingHost());
605 newItem->setGuest(group->asLayoutingGuest());
606 } else if (dw) {
607 newItem = new Core::Item(asLayoutingHost());
608 group = new Core::Group();
609 newItem->setGuest(group->asLayoutingGuest());
610 group->addTab(dw, option);
611 } else if (auto ms = w->asDropAreaController()) {
612 newItem = ms->d->m_rootItem;
613 newItem->setHost(asLayoutingHost());
614
615 if (auto fw = ms->floatingWindow()) {
616 newItem->setSize_recursive(fw->size());
617 }
618
619 delete ms;
620 } else {
621 // This doesn't happen but let's make coverity happy.
622 // Tests will fail if this is ever printed.
623 KDDW_ERROR("Unknown widget added", ( void * )w);
624 return;
625 }
626
627 assert(!newItem->geometry().isEmpty());
628 Core::ItemBoxContainer::insertItemRelativeTo(newItem, relativeToItem, location, option);
629
630 if (dw && option.startsHidden())
631 delete group;
632}
633
634void DropArea::addMultiSplitter(Core::DropArea *sourceMultiSplitter, Location location,
635 Core::Group *relativeToGroup, const InitialOption &option)
636{
637 KDDW_DEBUG("DropArea::addMultiSplitter: {} {} {}", ( void * )sourceMultiSplitter, ( int )location, ( void * )relativeToGroup);
638 Item *relativeToItem = relativeToGroup ? relativeToGroup->layoutItem() : nullptr;
639
640 addWidget(sourceMultiSplitter->view(), location, relativeToItem, option);
641
642 // Some widgets changed to/from floating
643 updateFloatingActions();
644}
645
647{
648 return d->m_rootItem->separators_recursive();
649}
650
651int DropArea::availableLengthForOrientation(Qt::Orientation orientation) const
652{
653 if (orientation == Qt::Vertical)
654 return availableSize().height();
655 else
656 return availableSize().width();
657}
658
659Size DropArea::availableSize() const
660{
661 return d->m_rootItem->availableSize();
662}
663
665{
666 if (!checkSanity())
667 return;
668
669 layoutEqually(d->m_rootItem);
670}
671
672void DropArea::layoutEqually(Core::ItemBoxContainer *container)
673{
674 if (container) {
675 container->layoutEqually_recursive();
676 } else {
677 KDDW_ERROR("null container");
678 }
679}
680
681void DropArea::setRootItem(Core::ItemBoxContainer *root)
682{
684 d->m_rootItem = root;
685}
686
687Core::ItemBoxContainer *DropArea::rootItem() const
688{
689 return d->m_rootItem;
690}
691
692Rect DropArea::rectForDrop(const WindowBeingDragged *wbd, Location location,
693 const Core::Item *relativeTo) const
694{
695 Core::Item item(nullptr);
696 if (!wbd)
697 return {};
698
699 item.setSize(wbd->size().boundedTo(wbd->maxSize()));
700 item.setMinSize(wbd->minSize());
701 item.setMaxSizeHint(wbd->maxSize());
702
703 Core::ItemBoxContainer *container =
704 relativeTo ? relativeTo->parentBoxContainer() : d->m_rootItem;
705
706 return container->suggestedDropRect(&item, relativeTo, location);
707}
708
709bool DropArea::deserialize(const LayoutSaver::MultiSplitter &l)
710{
711 setRootItem(new Core::ItemBoxContainer(asLayoutingHost()));
712 return Layout::deserialize(l);
713}
714
716{
717 return d->m_rootItem->numSideBySide_recursive(o);
718}
719
721{
722 return d->m_dropIndicatorOverlay ? d->m_dropIndicatorOverlay->currentDropLocation() : DropLocation_None;
723}
724
725Core::Group *DropArea::centralGroup() const
726{
727 return d->m_centralGroup;
728}
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
Singleton to allow to choose certain behaviours of the framework.
Definition Config.h:64
static Config & self()
returns the singleton Config instance
Definition Config.cpp:88
Flags flags() const
returns the chosen flags
Definition Config.cpp:102
void setParentView(View *parent)
View * view() const
Returns the view associated with this controller, if any.
std::shared_ptr< View > window() const
The DockWidget base-class. DockWidget and Core::DockWidget are only split in two so we can share some...
Vector< DockWidget * > List
void layoutParentContainerEqually(DockWidget *)
void addWidget(View *widget, KDDockWidgets::Location location, Core::Item *relativeToItem=nullptr, const InitialOption &option=DefaultSizeMode::Fair)
Adds a widget to this MultiSplitter.
static Core::Group * createCentralGroup(MainWindowOptions options)
DropArea(View *parent, MainWindowOptions options, bool isMDIWrapper=false)
Vector< Core::Group * > groups() const
bool deserialize(const LayoutSaver::MultiSplitter &) override
DropIndicatorOverlay * dropIndicatorOverlay() const
Vector< Core::LayoutingSeparator * > separators() const
returns the list of separators
bool containsDockWidget(DockWidget *) const
void _addDockWidget(DockWidget *dw, KDDockWidgets::Location location, Item *relativeTo, const InitialOption &initialOption)
Vector< QString > affinities() const
Core::Item * centralFrame() const
int numSideBySide_recursive(Qt::Orientation) const
Returns the number of items layed-out horizontally or vertically But honours nesting.
DropLocation currentDropLocation() const
Core::ItemBoxContainer * rootItem() const
bool drop(WindowBeingDragged *droppedWindow, Point globalPos)
Called when a user drops a widget via DND.
Core::DockWidget * mdiDockWidgetWrapper() const
Returns the helper dock widget for implementing DockWidgetOption_MDINestable.
void addDockWidget(DockWidget *dw, KDDockWidgets::Location location, DockWidget *relativeTo, const InitialOption &initialOption={})
Rect rectForDrop(const WindowBeingDragged *wbd, KDDockWidgets::Location location, const Core::Item *relativeTo) const
void addMultiSplitter(Core::DropArea *splitter, KDDockWidgets::Location location, Core::Group *relativeToGroup=nullptr, const InitialOption &option=DefaultSizeMode::Fair)
void layoutEqually()
See docs for MainWindowBase::layoutEqually()
DropLocation hover(WindowBeingDragged *draggedWindow, Point globalPos)
static KDDockWidgets::Location multisplitterLocationFor(DropLocation)
std::unique_ptr< WindowBeingDragged > makeWindow() override
Layout * layout() const
Returns the Layout.
void scheduleDeleteLater()
Equivalent to deleteLater() but sets beingDeleted() to true.
bool hasSingleDockWidget() const
returns whether there's only 1 dock widget.
Definition core/Group.h:196
Core::Item * layoutItem() const
returns the layout item that either contains this Frame in the layout or is a placeholder
static Core::Group * fromItem(const Core::Item *)
Returns the group that's in the specified item.
Vector< QString > affinities() const
void addTab(DockWidget *, const InitialOption &={})
Adds a widget into the Group's Stack.
bool containsDockWidget(DockWidget *w) const
returns whether the dockwidget w is inside this group
The widget (QWidget or QQuickItem) which holds a layout of dock widgets.
Definition Layout.h:57
bool containsItem(const Core::Item *) const
Returns true if this layout contains the specified item.
Definition Layout.cpp:199
Layout::Private * d_ptr()
Definition Layout.cpp:372
void unrefOldPlaceholders(const Vector< Core::Group * > &groupsBeingAdded) const
Removes unneeded placeholder items when adding new groups.
Definition Layout.cpp:175
int visibleCount() const
Returns the number of visible Items in this layout. Which is count minus placeholderCount.
Definition Layout.cpp:214
void setRootItem(Core::ItemContainer *root)
Definition Layout.cpp:101
void setLayoutSize(Size)
setter for the contents size The "contents size" is just the size() of this layout....
Definition Layout.cpp:185
virtual bool deserialize(const LayoutSaver::MultiSplitter &)
Definition Layout.cpp:285
LayoutingHost * asLayoutingHost() const
Definition Layout.cpp:367
bool checkSanity() const
Runs some sanity checks. Returns true if everything is OK.
Definition Layout.cpp:141
Core::Item * itemForGroup(const Core::Group *group) const
returns the Item that holds group in this layout
Definition Layout.cpp:224
Vector< Core::Group * > groupsFrom(View *groupOrMultiSplitter) const
returns the groups contained in groupOrMultiSplitter- If groupOrMultiSplitter- is a Group,...
Definition Layout.cpp:242
Vector< Core::Item * > items() const
The list of items in this layout.
Definition Layout.cpp:194
bool containsGroup(const Core::Group *) const
Returns true if this layout contains the specified group.
Definition Layout.cpp:204
void updateSizeConstraints()
Updates the min size of this layout.
Definition Layout.cpp:279
Core::MainWindow * mainWindow(bool honourNesting=false) const
Definition Layout.cpp:73
Vector< Core::DockWidget * > dockWidgets() const
Returns the list of dock widgets contained in this layout.
Definition Layout.cpp:232
Core::FloatingWindow * floatingWindow() const
Definition Layout.cpp:95
A dummy DropIndicatorOverlay implementation which doesn't do anything.
static DropIndicatorType s_dropIndicatorType
@ The drop indicator type
bool equals(const View *other) const
Returns whether this view represents the same GUI element as the other.
virtual void raiseAndActivate()=0
virtual std::shared_ptr< View > parentView() const =0
Returns the gui element's parent. Like QWidget::parentWidget()
Core::FloatingWindow * asFloatingWindowController() const
asFooController() are deprecated. Use asController<T>() instead
virtual bool is(ViewType) const
Returns whether the view is of the specified type Virtual so it can be overridden by ViewWrapper....
Core::Group * asGroupController() const
virtual std::shared_ptr< Core::Window > window() const =0
Returns the window this view is inside For the Qt frontend, this wraps a QWindow. Like QWidget::windo...
Core::DropArea * asDropAreaController() const
Core::DockWidget * asDockWidgetController() const
static DockRegistry * self()
static bool isOutterLocation(DropLocation location)
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
ViewType
Each View type also has a specific Controller associated with, except for ViewType::None.
Definition Controller.h:26
Class to abstract QAction, so code still works with QtQuick and Flutter.
@ MainWindowOption_HasCentralWidget
@ MainWindowOption_HasCentralFrame
‍No option set
@ Location_OnTop
‍Left docking location
@ None
Don't show any drop indicators while dragging.
@ Segmented
Segmented indicators.
DropLocation
Enum describing the different drop indicator types.
static Core::DropIndicatorOverlay * createDropIndicatorOverlay(Core::DropArea *dropArea)
@ StartHidden
Don't show the dock widget when adding it.
MouseFocusReason
Orientation
A MultiSplitter with support for drop indicators when hovering over.
Struct describing the preferred dock widget size and visibility when adding it to a layout.
InitialVisibilityOption visibility
Allows a dock widget to be docked as hidden.

© 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