6#include "QtWidgets/qapplication.h"
7#include "QtWidgets/qwidget.h"
9#include "QtWidgets/qtabbar.h"
11#include "QtWidgets/qstyle.h"
12#include "QtWidgets/qapplication.h"
13#include "QtCore/qvariant.h"
21#include <private/qlayoutengine_p.h>
25#include "qtoolbarlayout_p.h"
29#include <qstyleoption.h>
33Q_LOGGING_CATEGORY(lcQpaDockWidgets,
"qt.widgets.dockwidgets");
41
42
44QPlaceHolderItem::QPlaceHolderItem(QWidget *w)
46 objectName = w->objectName();
47 hidden = w->isHidden();
48 window = w->isWindow();
50 topLevelRect = w->geometry();
54
55
57QDockAreaLayoutItem::QDockAreaLayoutItem(QLayoutItem *_widgetItem)
58 : widgetItem(_widgetItem), subinfo(
nullptr), placeHolderItem(
nullptr), pos(0), size(-1), flags(NoFlags)
62QDockAreaLayoutItem::QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo)
63 : widgetItem(
nullptr), subinfo(_subinfo), placeHolderItem(
nullptr), pos(0), size(-1), flags(NoFlags)
67QDockAreaLayoutItem::QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem)
68 : widgetItem(
nullptr), subinfo(
nullptr), placeHolderItem(_placeHolderItem), pos(0), size(-1), flags(NoFlags)
72QDockAreaLayoutItem::QDockAreaLayoutItem(
const QDockAreaLayoutItem &other)
73 : widgetItem(other.widgetItem), subinfo(
nullptr), placeHolderItem(
nullptr), pos(other.pos),
74 size(other.size), flags(other.flags)
76 if (other.subinfo !=
nullptr)
77 subinfo =
new QDockAreaLayoutInfo(*other.subinfo);
78 else if (other.placeHolderItem !=
nullptr)
79 placeHolderItem =
new QPlaceHolderItem(*other.placeHolderItem);
82QDockAreaLayoutItem::~QDockAreaLayoutItem()
85 delete placeHolderItem;
88bool QDockAreaLayoutItem::skip()
const
90 if (placeHolderItem !=
nullptr)
96 if (widgetItem !=
nullptr)
97 return widgetItem->isEmpty();
99 if (subinfo !=
nullptr) {
100 for (
int i = 0; i < subinfo->item_list.size(); ++i) {
101 if (!subinfo->item_list.at(i).skip())
109QSize QDockAreaLayoutItem::minimumSize()
const
112 return widgetItem->minimumSize().grownBy(widgetItem->widget()->contentsMargins());
113 if (subinfo !=
nullptr)
114 return subinfo->minimumSize();
118QSize QDockAreaLayoutItem::maximumSize()
const
121 return widgetItem->maximumSize().grownBy(widgetItem->widget()->contentsMargins());
122 if (subinfo !=
nullptr)
123 return subinfo->maximumSize();
124 return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
127bool QDockAreaLayoutItem::hasFixedSize(Qt::Orientation o)
const
129 return perp(o, minimumSize()) == perp(o, maximumSize());
132bool QDockAreaLayoutItem::expansive(Qt::Orientation o)
const
134 if ((flags & GapItem) || placeHolderItem !=
nullptr)
136 if (widgetItem !=
nullptr)
137 return ((widgetItem->expandingDirections() & o) == o);
138 if (subinfo !=
nullptr)
139 return subinfo->expansive(o);
143QSize QDockAreaLayoutItem::sizeHint()
const
145 if (placeHolderItem !=
nullptr)
148 return widgetItem->sizeHint().grownBy(widgetItem->widget()->contentsMargins());
149 if (subinfo !=
nullptr)
150 return subinfo->sizeHint();
151 return QSize(-1, -1);
155 &QDockAreaLayoutItem::operator = (
const QDockAreaLayoutItem &other)
160 widgetItem = other.widgetItem;
162 if (other.subinfo ==
nullptr)
165 subinfo =
new QDockAreaLayoutInfo(*other.subinfo);
167 delete placeHolderItem;
168 if (other.placeHolderItem ==
nullptr)
169 placeHolderItem =
nullptr;
171 placeHolderItem =
new QPlaceHolderItem(*other.placeHolderItem);
180#ifndef QT_NO_DEBUG_STREAM
181QDebug operator<<(QDebug dbg,
const QDockAreaLayoutItem *item)
183 QDebugStateSaver saver(dbg);
185 return item ? dbg << *item : dbg <<
"QDockAreaLayoutItem(0x0)";
188QDebug operator<<(QDebug dbg,
const QDockAreaLayoutItem &item)
190 QDebugStateSaver saver(dbg);
192 dbg <<
"QDockAreaLayoutItem(" <<
static_cast<
const void *>(&item) <<
"->";
193 if (item.widgetItem) {
194 QWidget *widget = item.widgetItem->widget();
195 if (
auto *dockWidget = qobject_cast<QDockWidget *>(widget)) {
196 dbg <<
"widgetItem(" << dockWidget <<
")";
197 }
else if (
auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(widget)) {
198 dbg <<
"widgetItem(" << groupWindow <<
"->(" << groupWindow->dockWidgets() <<
"))";
200 dbg <<
"widgetItem(" << widget <<
")";
202 }
else if (item.subinfo) {
203 dbg <<
"subInfo(" << item.subinfo <<
"->(" << item.subinfo->item_list <<
")";
204 }
else if (item.placeHolderItem) {
205 dbg <<
"placeHolderItem(" << item.placeHolderItem <<
")";
213
214
217static quintptr tabId(
const QDockAreaLayoutItem &item)
219 if (item.widgetItem ==
nullptr)
221 return reinterpret_cast<quintptr>(item.widgetItem->widget());
227QDockAreaLayoutInfo::QDockAreaLayoutInfo()
228 : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(
nullptr)
230 , tabbed(
false), tabBar(
nullptr), tabBarShape(QTabBar::RoundedSouth)
235QDockAreaLayoutInfo::QDockAreaLayoutInfo(
const int *_sep, QInternal::DockPosition _dockPos,
236 Qt::Orientation _o,
int tbshape,
238 : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window)
240 , tabbed(
false), tabBar(
nullptr), tabBarShape(
static_cast<QTabBar::Shape>(tbshape))
243#if !QT_CONFIG(tabbar)
248QSize QDockAreaLayoutInfo::size()
const
250 return isEmpty() ? QSize(0, 0) : rect.size();
253void QDockAreaLayoutInfo::clear()
263bool QDockAreaLayoutInfo::isEmpty()
const
265 return next(-1) == -1;
268bool QDockAreaLayoutInfo::onlyHasPlaceholders()
const
270 for (
const QDockAreaLayoutItem &item : item_list) {
271 if (!item.placeHolderItem)
278QSize QDockAreaLayoutInfo::minimumSize()
const
285 for (
int i = 0; i < item_list.size(); ++i) {
286 const QDockAreaLayoutItem &item = item_list.at(i);
290 QSize min_size = item.minimumSize();
293 a = qMax(a, pick(o, min_size));
299 a += pick(o, min_size);
301 b = qMax(b, perp(o, min_size));
307 rpick(o, result) = a;
308 rperp(o, result) = b;
311 QSize tbm = tabBarMinimumSize();
313 switch (tabBarShape) {
314 case QTabBar::RoundedNorth:
315 case QTabBar::RoundedSouth:
316 case QTabBar::TriangularNorth:
317 case QTabBar::TriangularSouth:
318 result.rheight() += tbm.height();
319 result.rwidth() = qMax(tbm.width(), result.width());
321 case QTabBar::RoundedEast:
322 case QTabBar::RoundedWest:
323 case QTabBar::TriangularEast:
324 case QTabBar::TriangularWest:
325 result.rheight() = qMax(tbm.height(), result.height());
326 result.rwidth() += tbm.width();
337QSize QDockAreaLayoutInfo::maximumSize()
const
340 return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
342 int a = 0, b = QWIDGETSIZE_MAX;
351 for (
int i = 0; i < item_list.size(); ++i) {
352 const QDockAreaLayoutItem &item = item_list.at(i);
356 QSize max_size = item.maximumSize();
357 min_perp = qMax(min_perp, perp(o, item.minimumSize()));
361 a = qMin(a, pick(o, max_size));
367 a += pick(o, max_size);
369 b = qMin(b, perp(o, max_size));
371 a = qMin(a,
int(QWIDGETSIZE_MAX));
372 b = qMin(b,
int(QWIDGETSIZE_MAX));
377 b = qMax(b, min_perp);
380 rpick(o, result) = a;
381 rperp(o, result) = b;
384 QSize tbh = tabBarSizeHint();
386 switch (tabBarShape) {
387 case QTabBar::RoundedNorth:
388 case QTabBar::RoundedSouth:
389 result.rheight() += tbh.height();
391 case QTabBar::RoundedEast:
392 case QTabBar::RoundedWest:
393 result.rwidth() += tbh.width();
404QSize QDockAreaLayoutInfo::sizeHint()
const
411 int max_perp = QWIDGETSIZE_MAX;
412 const QDockAreaLayoutItem *previous =
nullptr;
413 for (
int i = 0; i < item_list.size(); ++i) {
414 const QDockAreaLayoutItem &item = item_list.at(i);
418 bool gap = item.flags & QDockAreaLayoutItem::GapItem;
420 QSize size_hint = item.sizeHint();
421 min_perp = qMax(min_perp, perp(o, item.minimumSize()));
422 max_perp = qMin(max_perp, perp(o, item.maximumSize()));
426 a = qMax(a, gap ? item.size : pick(o, size_hint));
430 if (previous && !gap && !(previous->flags & QDockAreaLayoutItem::GapItem)
431 && !previous->hasFixedSize(o)) {
434 a += gap ? item.size : pick(o, size_hint);
436 b = qMax(b, perp(o, size_hint));
441 max_perp = qMax(max_perp, min_perp);
442 b = qMax(b, min_perp);
443 b = qMin(b, max_perp);
446 rpick(o, result) = a;
447 rperp(o, result) = b;
451 QSize tbh = tabBarSizeHint();
452 switch (tabBarShape) {
453 case QTabBar::RoundedNorth:
454 case QTabBar::RoundedSouth:
455 case QTabBar::TriangularNorth:
456 case QTabBar::TriangularSouth:
457 result.rheight() += tbh.height();
458 result.rwidth() = qMax(tbh.width(), result.width());
460 case QTabBar::RoundedEast:
461 case QTabBar::RoundedWest:
462 case QTabBar::TriangularEast:
463 case QTabBar::TriangularWest:
464 result.rheight() = qMax(tbh.height(), result.height());
465 result.rwidth() += tbh.width();
476bool QDockAreaLayoutInfo::expansive(Qt::Orientation o)
const
478 for (
int i = 0; i < item_list.size(); ++i) {
479 if (item_list.at(i).expansive(o))
486
487
488
489
490
496 for (
int i = 0; i < info.item_list.size(); ++i) {
497 const QDockAreaLayoutItem &item = info.item_list.at(i);
502 if ((item.flags & QDockAreaLayoutItem::KeepSize) && item.size != -1)
505 min = pick(info.o, item.minimumSize());
521 for (
int i = 0; i < info.item_list.size(); ++i) {
522 const QDockAreaLayoutItem &item = info.item_list.at(i);
527 if ((item.flags & QDockAreaLayoutItem::KeepSize) && item.size != -1)
530 max = pick(info.o, item.maximumSize());
536 if (result >= QWIDGETSIZE_MAX)
537 return QWIDGETSIZE_MAX;
545void QDockAreaLayoutInfo::fitItems()
553 QList<QLayoutStruct> layout_struct_list(item_list.size() * 2);
556 int size = pick(o, rect.size());
557 int min_size = realMinSize(*
this);
558 int max_size = realMaxSize(*
this);
561 const QDockAreaLayoutItem *previous =
nullptr;
562 for (
int i = 0; i < item_list.size(); ++i) {
563 QDockAreaLayoutItem &item = item_list[i];
567 bool gap = item.flags & QDockAreaLayoutItem::GapItem;
568 if (previous && !gap) {
569 if (!(previous->flags & QDockAreaLayoutItem::GapItem)) {
570 QLayoutStruct &ls = layout_struct_list[j++];
572 ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : *sep;
577 if (item.flags & QDockAreaLayoutItem::KeepSize) {
581 if (size < min_size) {
583 item.flags &= ~QDockAreaLayoutItem::KeepSize;
584 min_size -= item.size;
585 min_size += pick(o, item.minimumSize());
586 min_size = qMax(0, min_size);
587 }
else if (size > max_size) {
589 item.flags &= ~QDockAreaLayoutItem::KeepSize;
590 max_size -= item.size;
591 max_size += pick(o, item.maximumSize());
592 max_size = qMin<
int>(QWIDGETSIZE_MAX, max_size);
597 QLayoutStruct &ls = layout_struct_list[j++];
600 if (item.flags & QDockAreaLayoutItem::KeepSize) {
601 ls.minimumSize = ls.maximumSize = ls.sizeHint = item.size;
602 ls.expansive =
false;
605 ls.maximumSize = pick(o, item.maximumSize());
606 ls.expansive = item.expansive(o);
607 ls.minimumSize = pick(o, item.minimumSize());
608 ls.sizeHint = item.size == -1 ? pick(o, item.sizeHint()) : item.size;
609 ls.stretch = ls.expansive ? ls.sizeHint : 0;
612 item.flags &= ~QDockAreaLayoutItem::KeepSize;
615 layout_struct_list.resize(j);
619 if (size > max_size && last_index != -1) {
620 layout_struct_list[last_index].maximumSize = QWIDGETSIZE_MAX;
621 layout_struct_list[last_index].expansive =
true;
624 qGeomCalc(layout_struct_list, 0, j, pick(o, rect.topLeft()), size, 0);
627 bool prev_gap =
false;
629 for (
int i = 0; i < item_list.size(); ++i) {
630 QDockAreaLayoutItem &item = item_list[i];
634 bool gap = item.flags & QDockAreaLayoutItem::GapItem;
635 if (!first && !gap && !prev_gap)
638 const QLayoutStruct &ls = layout_struct_list.at(j++);
642 if (item.subinfo !=
nullptr) {
643 item.subinfo->rect = itemRect(i);
644 item.subinfo->fitItems();
655 QDockAreaLayoutInfo::TabMode tabMode)
657 if (tabMode == QDockAreaLayoutInfo::ForceTabs)
658 return QInternal::DockCount;
660 QPoint pos = _pos - rect.topLeft();
664 int w = rect.width();
665 int h = rect.height();
667 if (tabMode != QDockAreaLayoutInfo::NoTabs) {
669 if (nestingEnabled) {
671
672
673
674
675
676
677
679 QRect center(w/6, h/6, 2*w/3, 2*h/3);
680 if (center.contains(pos))
681 return QInternal::DockCount;
682 }
else if (o == Qt::Horizontal) {
684
685
686
687
688
689
690
692 if (x > w/6 && x < w*5/6)
693 return QInternal::DockCount;
696
697
698
699
700
701
702 if (y > h/6 && y < 5*h/6)
703 return QInternal::DockCount;
708 if (nestingEnabled) {
709 if (o == Qt::Horizontal) {
711
712
713
714
715
716
719 return QInternal::LeftDock;
721 return QInternal::RightDock;
723 return QInternal::TopDock;
724 return QInternal::BottomDock;
727
728
729
730
731
734 return QInternal::TopDock;
736 return QInternal::BottomDock;
738 return QInternal::LeftDock;
739 return QInternal::RightDock;
742 if (o == Qt::Horizontal) {
744 ? QInternal::LeftDock
745 : QInternal::RightDock;
749 : QInternal::BottomDock;
754QList<
int> QDockAreaLayoutInfo::gapIndex(
const QPoint& _pos,
755 bool nestingEnabled, TabMode tabMode)
const
763 item_rect = tabContentRect();
767 int pos = pick(o, _pos);
770 for (
int i = 0; i < item_list.size(); ++i) {
771 const QDockAreaLayoutItem &item = item_list.at(i);
777 if (item.pos + item.size < pos)
780 if (item.subinfo !=
nullptr
782 && !item.subinfo->tabbed
785 result = item.subinfo->gapIndex(_pos, nestingEnabled,
791 item_rect = itemRect(i);
796 if (item_rect.isNull()) {
797 result.append(last + 1);
802 Q_ASSERT(!item_rect.isNull());
804 QInternal::DockPosition dock_pos
805 = dockPosHelper(item_rect, _pos, o, nestingEnabled, tabMode);
808 case QInternal::LeftDock:
809 if (o == Qt::Horizontal)
810 result << item_index;
812 result << item_index << 0;
815 case QInternal::RightDock:
816 if (o == Qt::Horizontal)
817 result << item_index + 1;
819 result << item_index << 1;
821 case QInternal::TopDock:
822 if (o == Qt::Horizontal)
823 result << item_index << 0;
825 result << item_index;
827 case QInternal::BottomDock:
828 if (o == Qt::Horizontal)
829 result << item_index << 1;
831 result << item_index + 1;
833 case QInternal::DockCount:
834 result << (-item_index - 1) << 0;
849 int old_size = ls.size;
850 ls.size = qMax(ls.size - delta, ls.minimumSize);
851 return old_size - ls.size;
858 int old_size = ls.size;
859 ls.size = qMin(ls.size + delta, ls.maximumSize);
860 return ls.size - old_size;
867 for (
int i = 0; i < list.size(); ++i) {
879 for (
int i = 0; i<=index; ++i) {
883 if (ls.maximumSize == QLAYOUTSIZE_MAX) {
884 growlimit = QLAYOUTSIZE_MAX;
887 growlimit += ls.maximumSize - ls.size;
889 if (delta > growlimit)
893 for (
int i = index + 1; d < delta && i < list.size(); ++i)
894 d += shrink(list[i], delta - d);
897 for (
int i = index; d < delta && i >= 0; --i)
898 d += grow(list[i], delta - d);
899 }
else if (delta < 0) {
901 for (
int i = index + 1; i < list.size(); ++i) {
905 if (ls.maximumSize == QLAYOUTSIZE_MAX) {
906 growlimit = QLAYOUTSIZE_MAX;
909 growlimit += ls.maximumSize - ls.size;
911 if (-delta > growlimit)
915 for (
int i = index; d < -delta && i >= 0; --i)
916 d += shrink(list[i], -delta - d);
919 for (
int i = index + 1; d < -delta && i < list.size(); ++i)
920 d += grow(list[i], -delta - d);
925 for (
int i = 0; i < list.size(); ++i) {
928 ls.pos = pos + (first ? 0 : sep);
941int QDockAreaLayoutInfo::separatorMove(
int index,
int delta)
947 QList<QLayoutStruct> list(item_list.size());
948 for (
int i = 0; i < list.size(); ++i) {
949 const QDockAreaLayoutItem &item = item_list.at(i);
950 QLayoutStruct &ls = list[i];
951 Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
955 const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
958 ls.size = item.size + separatorSpace;
959 ls.minimumSize = pick(o, item.minimumSize()) + separatorSpace;
960 ls.maximumSize = pick(o, item.maximumSize()) + separatorSpace;
966 delta = separatorMoveHelper(list, index, delta, 0 );
968 for (
int i = 0; i < list.size(); ++i) {
969 QDockAreaLayoutItem &item = item_list[i];
972 QLayoutStruct &ls = list[i];
973 const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
974 item.size = ls.size - separatorSpace;
976 if (item.subinfo !=
nullptr) {
977 item.subinfo->rect = itemRect(i);
978 item.subinfo->fitItems();
985void QDockAreaLayoutInfo::unnest(
int index)
987 QDockAreaLayoutItem &item = item_list[index];
988 if (item.subinfo ==
nullptr)
990 if (item.subinfo->item_list.size() > 1)
993 if (item.subinfo->item_list.size() == 0) {
994 item_list.removeAt(index);
995 }
else if (item.subinfo->item_list.size() == 1) {
996 QDockAreaLayoutItem &child = item.subinfo->item_list.first();
997 if (child.widgetItem !=
nullptr) {
998 item.widgetItem = child.widgetItem;
1000 item.subinfo =
nullptr;
1001 }
else if (child.subinfo !=
nullptr) {
1002 QDockAreaLayoutInfo *tmp = item.subinfo;
1003 item.subinfo = child.subinfo;
1004 child.subinfo =
nullptr;
1005 tmp->item_list.clear();
1011void QDockAreaLayoutInfo::remove(
const QList<
int> &path)
1013 Q_ASSERT(!path.isEmpty());
1015 if (path.size() > 1) {
1016 const int index = path.first();
1017 QDockAreaLayoutItem &item = item_list[index];
1018 Q_ASSERT(item.subinfo !=
nullptr);
1019 item.subinfo->remove(path.mid(1));
1022 int index = path.first();
1023 item_list.removeAt(index);
1027void QDockAreaLayoutInfo::remove(QWidget *widget)
1029 const QList<
int> path = indexOf(widget);
1035QLayoutItem *QDockAreaLayoutInfo::plug(
const QList<
int> &path)
1037 Q_ASSERT(!path.isEmpty());
1039 int index = path.first();
1043 if (path.size() > 1) {
1044 QDockAreaLayoutItem &item = item_list[index];
1045 Q_ASSERT(item.subinfo !=
nullptr);
1046 return item.subinfo->plug(path.mid(1));
1049 QDockAreaLayoutItem &item = item_list[index];
1051 Q_ASSERT(item.widgetItem !=
nullptr);
1052 Q_ASSERT(item.flags & QDockAreaLayoutItem::GapItem);
1053 item.flags &= ~QDockAreaLayoutItem::GapItem;
1054 return item.widgetItem;
1057QLayoutItem *QDockAreaLayoutInfo::unplug(
const QList<
int> &path)
1059 Q_ASSERT(!path.isEmpty());
1061 const int index = path.first();
1062 if (path.size() > 1) {
1063 QDockAreaLayoutItem &item = item_list[index];
1064 Q_ASSERT(item.subinfo !=
nullptr);
1065 return item.subinfo->unplug(path.mid(1));
1068 QDockAreaLayoutItem &item = item_list[index];
1069 int prev =
this->prev(index);
1070 int next =
this->next(index);
1072 Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
1073 item.flags |= QDockAreaLayoutItem::GapItem;
1075#if QT_CONFIG(tabbar)
1080 if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
1084 if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
1088 return item.widgetItem;
1091#if QT_CONFIG(tabbar)
1093quintptr QDockAreaLayoutInfo::currentTabId()
const
1095 if (!tabbed || tabBar ==
nullptr)
1098 int index = tabBar->currentIndex();
1102 return qvariant_cast<quintptr>(tabBar->tabData(index));
1105void QDockAreaLayoutInfo::setCurrentTab(QWidget *widget)
1107 setCurrentTabId(
reinterpret_cast<quintptr>(widget));
1110void QDockAreaLayoutInfo::setCurrentTabId(quintptr id)
1112 if (!tabbed || tabBar ==
nullptr)
1115 for (
int i = 0; i < tabBar->count(); ++i) {
1116 if (qvariant_cast<quintptr>(tabBar->tabData(i)) == id) {
1117 tabBar->setCurrentIndex(i);
1127 int titleHeight = 0;
1129 QDockWidgetLayout *layout
1130 = qobject_cast<QDockWidgetLayout*>(widget->layout());
1131 if (layout && layout->nativeWindowDeco())
1132 titleHeight = layout->titleHeight();
1134 QRect result = widget->geometry();
1135 result.adjust(0, -titleHeight, 0, 0);
1139bool QDockAreaLayoutInfo::hasGapItem(
const QList<
int> &path)
const
1147 const int index = path.constFirst();
1148 if (index < 0 || index >= item_list.count())
1151 return item_list[index].flags & QDockAreaLayoutItem::GapItem;
1154bool QDockAreaLayoutInfo::insertGap(
const QList<
int> &path, QLayoutItem *dockWidgetItem)
1156 Q_ASSERT(!path.isEmpty());
1158 bool insert_tabbed =
false;
1159 int index = path.first();
1161 insert_tabbed =
true;
1165 if (path.size() > 1) {
1166 QDockAreaLayoutItem &item = item_list[index];
1168 if (item.subinfo ==
nullptr
1169#if QT_CONFIG(tabbar)
1170 || (item.subinfo->tabbed && !insert_tabbed)
1176 QDockAreaLayoutInfo *subinfo = item.subinfo;
1177 QLayoutItem *widgetItem = item.widgetItem;
1178 QPlaceHolderItem *placeHolderItem = item.placeHolderItem;
1179 QRect r = subinfo ==
nullptr ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect;
1181 Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal;
1182#if !QT_CONFIG(tabbar)
1183 const int tabBarShape = 0;
1185 QDockAreaLayoutInfo *new_info
1186 =
new QDockAreaLayoutInfo(sep, dockPos, opposite, tabBarShape, mainWindow);
1189 item.subinfo = new_info;
1190 item.widgetItem =
nullptr;
1191 item.placeHolderItem =
nullptr;
1193 QDockAreaLayoutItem new_item
1194 = widgetItem ==
nullptr
1195 ? QDockAreaLayoutItem(subinfo)
1196 : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem);
1197 new_item.size = pick(opposite, r.size());
1198 new_item.pos = pick(opposite, r.topLeft());
1199 new_info->item_list.append(new_item);
1200#if QT_CONFIG(tabbar)
1201 if (insert_tabbed) {
1202 new_info->tabbed =
true;
1207 return item.subinfo->insertGap(path.mid(1), dockWidgetItem);
1211 QDockAreaLayoutItem gap_item;
1212 gap_item.flags |= QDockAreaLayoutItem::GapItem;
1213 gap_item.widgetItem = dockWidgetItem;
1215#if QT_CONFIG(tabbar)
1219 int prev =
this->prev(index);
1220 int next =
this->next(index - 1);
1226 case QInternal::LeftDock:
1227 case QInternal::RightDock:
1228 if (o == Qt::Vertical) {
1230 space = pick(Qt::Vertical, rect.size());
1232 space = pick(Qt::Horizontal, dockWidgetItem->widget()->size());
1235 case QInternal::TopDock:
1236 case QInternal::BottomDock:
1238 if (o == Qt::Horizontal) {
1240 space = pick(Qt::Horizontal, rect.size());
1242 space = pick(Qt::Vertical, dockWidgetItem->widget()->size());
1247 for (
int i = 0; i < item_list.size(); ++i) {
1248 const QDockAreaLayoutItem &item = item_list.at(i);
1251 Q_ASSERT_X(!(item.flags & QDockAreaLayoutItem::GapItem),
1252 "QDockAreaLayoutInfo::insertGap",
"inserting two gaps after each other");
1253 space += item.size - pick(o, item.minimumSize());
1254 qCDebug(lcQpaDockWidgets) <<
"Item space:" << item.flags <<
this;
1265 QRect r = dockedGeometry(dockWidgetItem->widget());
1266 gap_size = pick(o, r.size());
1267 if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem))
1269 if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
1272 if (gap_size + sep_size > space)
1273 gap_size = pick(o, gap_item.minimumSize());
1274 gap_item.size = gap_size + sep_size;
1278 item_list.insert(index, gap_item);
1279 qCDebug(lcQpaDockWidgets) <<
"Insert gap after:" << index <<
this;
1284QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QWidget *widget)
1286 for (
int i = 0; i < item_list.size(); ++i) {
1287 const QDockAreaLayoutItem &item = item_list.at(i);
1291#if QT_CONFIG(tabbar)
1292 if (tabbed && widget == tabBar)
1296 if (item.widgetItem !=
nullptr && item.widgetItem->widget() == widget)
1299 if (item.subinfo !=
nullptr) {
1300 if (QDockAreaLayoutInfo *result = item.subinfo->info(widget))
1308QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(
const QList<
int> &path)
1310 int index = path.first();
1313 if (index >= item_list.size())
1315 if (path.size() == 1 || item_list[index].subinfo ==
nullptr)
1317 return item_list[index].subinfo->info(path.mid(1));
1320QRect QDockAreaLayoutInfo::itemRect(
int index,
bool isGap)
const
1322 const QDockAreaLayoutItem &item = item_list.at(index);
1327 if (isGap && !(item.flags & QDockAreaLayoutItem::GapItem))
1332#if QT_CONFIG(tabbar)
1334 if (isGap || tabId(item) == currentTabId())
1335 result = tabContentRect();
1340 int size = item.size;
1343 int prev =
this->prev(index);
1344 int next =
this->next(index);
1345 if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
1349 if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
1355 rperp(o, p) = perp(o, rect.topLeft());
1358 rperp(o, s) = perp(o, rect.size());
1359 result = QRect(p, s);
1365QRect QDockAreaLayoutInfo::itemRect(
const QList<
int> &path)
const
1367 Q_ASSERT(!path.isEmpty());
1369 const int index = path.first();
1370 if (path.size() > 1) {
1371 const QDockAreaLayoutItem &item = item_list.at(index);
1372 Q_ASSERT(item.subinfo !=
nullptr);
1373 return item.subinfo->itemRect(path.mid(1));
1376 return itemRect(index);
1379QRect QDockAreaLayoutInfo::separatorRect(
int index)
const
1381#if QT_CONFIG(tabbar)
1386 const QDockAreaLayoutItem &item = item_list.at(index);
1390 QPoint pos = rect.topLeft();
1391 rpick(o, pos) = item.pos + item.size;
1392 QSize s = rect.size();
1395 return QRect(pos, s);
1398QRect QDockAreaLayoutInfo::separatorRect(
const QList<
int> &path)
const
1400 Q_ASSERT(!path.isEmpty());
1402 const int index = path.first();
1403 if (path.size() > 1) {
1404 const QDockAreaLayoutItem &item = item_list.at(index);
1405 Q_ASSERT(item.subinfo !=
nullptr);
1406 return item.subinfo->separatorRect(path.mid(1));
1408 return separatorRect(index);
1411QList<
int> QDockAreaLayoutInfo::findSeparator(
const QPoint &_pos)
const
1413#if QT_CONFIG(tabbar)
1415 return QList<
int>();
1418 int pos = pick(o, _pos);
1420 for (
int i = 0; i < item_list.size(); ++i) {
1421 const QDockAreaLayoutItem &item = item_list.at(i);
1422 if (item.skip() || (item.flags & QDockAreaLayoutItem::GapItem))
1425 if (item.pos + item.size > pos) {
1426 if (item.subinfo !=
nullptr) {
1427 QList<
int> result = item.subinfo->findSeparator(_pos);
1428 if (!result.isEmpty()) {
1432 return QList<
int>();
1437 int next =
this->next(i);
1438 if (next == -1 || (item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
1441 QRect sepRect = separatorRect(i);
1442 if (!sepRect.isNull() && *sep == 1)
1443 sepRect.adjust(-2, -2, 2, 2);
1445 if (sepRect.contains(_pos) && !item.hasFixedSize(o)) {
1446 return QList<
int>() << i;
1451 return QList<
int>();
1454QList<
int> QDockAreaLayoutInfo::indexOfPlaceHolder(
const QString &objectName)
const
1456 for (
int i = 0; i < item_list.size(); ++i) {
1457 const QDockAreaLayoutItem &item = item_list.at(i);
1459 if (item.subinfo !=
nullptr) {
1460 QList<
int> result = item.subinfo->indexOfPlaceHolder(objectName);
1461 if (!result.isEmpty()) {
1468 if (item.placeHolderItem !=
nullptr && item.placeHolderItem->objectName == objectName) {
1475 return QList<
int>();
1478QList<
int> QDockAreaLayoutInfo::indexOf(
const QWidget *widget)
const
1480 for (
int i = 0; i < item_list.size(); ++i) {
1481 const QDockAreaLayoutItem &item = item_list.at(i);
1483 if (item.placeHolderItem !=
nullptr)
1486 if (item.subinfo !=
nullptr) {
1487 QList<
int> result = item.subinfo->indexOf(widget);
1488 if (!result.isEmpty()) {
1495 if (!(item.flags & QDockAreaLayoutItem::GapItem) && item.widgetItem && item.widgetItem->widget() == widget) {
1502 return QList<
int>();
1505std::unique_ptr<QLayoutItem> QDockAreaLayoutInfo::takeWidgetItem(QWidget *widget)
1507 std::unique_ptr<QLayoutItem> widgetItem;
1508 if (
const auto path = indexOf(widget); !path.isEmpty())
1509 widgetItem.reset(item(path).widgetItem);
1513QMainWindowLayout *QDockAreaLayoutInfo::mainWindowLayout()
const
1515 QMainWindowLayout *result = qt_mainwindow_layout(mainWindow);
1516 Q_ASSERT(result !=
nullptr);
1520bool QDockAreaLayoutInfo::hasFixedSize()
const
1522 return perp(o, minimumSize()) == perp(o, maximumSize());
1526
1527
1528QDockWidget *QDockAreaLayoutInfo::apply(
bool animate)
1530 QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator;
1532#if QT_CONFIG(tabbar)
1535 QSize tbh = tabBarSizeHint();
1537 if (!tbh.isNull()) {
1538 switch (tabBarShape) {
1539 case QTabBar::RoundedNorth:
1540 case QTabBar::TriangularNorth:
1541 tab_rect = QRect(rect.left(), rect.top(), rect.width(), tbh.height());
1543 case QTabBar::RoundedSouth:
1544 case QTabBar::TriangularSouth:
1545 tab_rect = QRect(rect.left(), rect.bottom() - tbh.height() + 1,
1546 rect.width(), tbh.height());
1548 case QTabBar::RoundedEast:
1549 case QTabBar::TriangularEast:
1550 tab_rect = QRect(rect.right() - tbh.width() + 1, rect.top(),
1551 tbh.width(), rect.height());
1553 case QTabBar::RoundedWest:
1554 case QTabBar::TriangularWest:
1555 tab_rect = QRect(rect.left(), rect.top(),
1556 tbh.width(), rect.height());
1563 widgetAnimator.animate(tabBar, tab_rect, animate);
1567 QDockWidget *activated =
nullptr;
1569 for (
int i = 0; i < item_list.size(); ++i) {
1570 QDockAreaLayoutItem &item = item_list[i];
1572 if (item.flags & QDockAreaLayoutItem::GapItem)
1575 if (item.subinfo !=
nullptr) {
1576 item.subinfo->apply(animate);
1583 Q_ASSERT(item.widgetItem);
1584 QRect r = itemRect(i);
1585 QWidget *w = item.widgetItem->widget();
1587 QRect geo = w->geometry();
1588 widgetAnimator.animate(w, r, animate);
1589 if (!w->isHidden() && w->window()->isVisible()) {
1590 QDockWidget *dw = qobject_cast<QDockWidget*>(w);
1591 if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) {
1593 emit dw->visibilityChanged(
false);
1594 }
else if (r.isValid()
1595 && (geo.right() < 0 || geo.bottom() < 0)) {
1596 emit dw->visibilityChanged(
true);
1601#if QT_CONFIG(tabbar)
1603 updateSeparatorWidgets();
1609static void paintSep(QPainter *p, QWidget *w,
const QRect &r, Qt::Orientation o,
bool mouse_over)
1611 QStyleOption opt(0);
1612 opt.state = QStyle::State_None;
1614 opt.state |= QStyle::State_Enabled;
1615 if (o != Qt::Horizontal)
1616 opt.state |= QStyle::State_Horizontal;
1618 opt.state |= QStyle::State_MouseOver;
1620 opt.palette = w->palette();
1622 w->style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &opt, p, w);
1625QRegion QDockAreaLayoutInfo::separatorRegion()
const
1631#if QT_CONFIG(tabbar)
1636 for (
int i = 0; i < item_list.size(); ++i) {
1637 const QDockAreaLayoutItem &item = item_list.at(i);
1642 int next =
this->next(i);
1645 result |= item.subinfo->separatorRegion();
1649 result |= separatorRect(i);
1655void QDockAreaLayoutInfo::paintSeparators(QPainter *p, QWidget *widget,
1656 const QRegion &clip,
1657 const QPoint &mouse)
const
1661#if QT_CONFIG(tabbar)
1666 for (
int i = 0; i < item_list.size(); ++i) {
1667 const QDockAreaLayoutItem &item = item_list.at(i);
1672 int next =
this->next(i);
1673 if ((item.flags & QDockAreaLayoutItem::GapItem)
1674 || (next != -1 && (item_list.at(next).flags & QDockAreaLayoutItem::GapItem)))
1678 if (clip.contains(item.subinfo->rect))
1679 item.subinfo->paintSeparators(p, widget, clip, mouse);
1684 QRect r = separatorRect(i);
1685 if (clip.contains(r) && !item.hasFixedSize(o))
1686 paintSep(p, widget, r, o, r.contains(mouse));
1690int QDockAreaLayoutInfo::next(
int index)
const
1692 for (
int i = index + 1; i < item_list.size(); ++i) {
1693 if (!item_list.at(i).skip())
1699int QDockAreaLayoutInfo::prev(
int index)
const
1701 for (
int i = index - 1; i >= 0; --i) {
1702 if (!item_list.at(i).skip())
1708#if QT_CONFIG(tabbar)
1709void QDockAreaLayoutInfo::tab(
int index, QLayoutItem *dockWidgetItem)
1712 item_list.append(QDockAreaLayoutItem(dockWidgetItem));
1714 setCurrentTab(dockWidgetItem->widget());
1716 QDockAreaLayoutInfo *new_info
1717 =
new QDockAreaLayoutInfo(sep, dockPos, o, tabBarShape, mainWindow);
1718 item_list[index].subinfo = new_info;
1719 new_info->item_list.append(QDockAreaLayoutItem(item_list.at(index).widgetItem));
1720 item_list[index].widgetItem =
nullptr;
1721 new_info->item_list.append(QDockAreaLayoutItem(dockWidgetItem));
1722 new_info->tabbed =
true;
1723 new_info->updateTabBar();
1724 new_info->setCurrentTab(dockWidgetItem->widget());
1729void QDockAreaLayoutInfo::split(
int index, Qt::Orientation orientation,
1730 QLayoutItem *dockWidgetItem)
1732 if (orientation == o) {
1733 item_list.insert(index + 1, QDockAreaLayoutItem(dockWidgetItem));
1735#if !QT_CONFIG(tabbar)
1736 const int tabBarShape = 0;
1738 QDockAreaLayoutInfo *new_info
1739 =
new QDockAreaLayoutInfo(sep, dockPos, orientation, tabBarShape, mainWindow);
1740 item_list[index].subinfo = new_info;
1741 new_info->item_list.append(QDockAreaLayoutItem(item_list.at(index).widgetItem));
1742 item_list[index].widgetItem =
nullptr;
1743 new_info->item_list.append(QDockAreaLayoutItem(dockWidgetItem));
1747QDockAreaLayoutItem &QDockAreaLayoutInfo::item(
const QList<
int> &path)
1749 Q_ASSERT(!path.isEmpty());
1750 const int index = path.first();
1751 if (path.size() > 1) {
1752 const QDockAreaLayoutItem &item = item_list[index];
1753 Q_ASSERT(item.subinfo !=
nullptr);
1754 return item.subinfo->item(path.mid(1));
1756 return item_list[index];
1759QLayoutItem *QDockAreaLayoutInfo::itemAt(
int *x,
int index)
const
1761 for (
int i = 0; i < item_list.size(); ++i) {
1762 const QDockAreaLayoutItem &item = item_list.at(i);
1763 if (item.placeHolderItem !=
nullptr)
1766 if (QLayoutItem *ret = item.subinfo->itemAt(x, index))
1768 }
else if (item.widgetItem) {
1769 if ((*x)++ == index)
1770 return item.widgetItem;
1776QLayoutItem *QDockAreaLayoutInfo::takeAt(
int *x,
int index)
1778 for (
int i = 0; i < item_list.size(); ++i) {
1779 QDockAreaLayoutItem &item = item_list[i];
1780 if (item.placeHolderItem !=
nullptr)
1782 else if (item.subinfo) {
1783 if (QLayoutItem *ret = item.subinfo->takeAt(x, index)) {
1787 }
else if (item.widgetItem) {
1788 if ((*x)++ == index) {
1789 QWidget *widget = item.widgetItem->widget();
1790 if (widget->isWidgetType())
1791 item.placeHolderItem =
new QPlaceHolderItem(widget);
1793 qCDebug(lcQpaDockWidgets) << widget <<
"is in destruction. No gap created.";
1794 QLayoutItem *ret = item.widgetItem;
1795 item.widgetItem =
nullptr;
1796 if (item.size != -1)
1797 item.flags |= QDockAreaLayoutItem::KeepSize;
1806void QDockAreaLayoutInfo::add(QWidget *widget)
1809 if (!indexOf(widget).isEmpty())
1812 if (
auto *dockWidget = qobject_cast<QDockWidget *>(widget)) {
1813 item_list.append(QDockAreaLayoutItem(
new QDockWidgetItem(dockWidget)));
1817 if (
auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(widget)) {
1818 item_list.append(QDockAreaLayoutItem(
new QDockWidgetGroupWindowItem(groupWindow)));
1822 qFatal(
"Coding error. Add supports only QDockWidget and QDockWidgetGroupWindow");
1825void QDockAreaLayoutInfo::deleteAllLayoutItems()
1827 for (
int i = 0; i < item_list.size(); ++i) {
1828 QDockAreaLayoutItem &item= item_list[i];
1830 item.subinfo->deleteAllLayoutItems();
1832 delete item.widgetItem;
1833 item.widgetItem =
nullptr;
1838void QDockAreaLayoutInfo::saveState(QDataStream &stream)
const
1840#if QT_CONFIG(tabbar)
1842 stream << (uchar) TabMarker;
1845 quintptr id = currentTabId();
1847 for (
int i = 0; i < item_list.size(); ++i) {
1848 if (tabId(item_list.at(i)) == id) {
1857 stream << (uchar) SequenceMarker;
1860 stream << (uchar) o <<
int(item_list.size());
1862 for (
int i = 0; i < item_list.size(); ++i) {
1863 const QDockAreaLayoutItem &item = item_list.at(i);
1864 if (item.widgetItem !=
nullptr) {
1865 stream << (uchar) WidgetMarker;
1866 QWidget *w = item.widgetItem->widget();
1867 QString name = w->objectName();
1868 if (Q_UNLIKELY(name.isEmpty())) {
1869 qWarning(
"QMainWindow::saveState(): 'objectName' not set for QDockWidget %p '%ls;",
1870 w, qUtf16Printable(w->windowTitle()));
1876 flags |= StateFlagVisible;
1878 flags |= StateFlagFloating;
1881 if (w->isWindow()) {
1882 const QRect geometry = w->geometry();
1883 stream << geometry.x() << geometry.y() << geometry.width() << geometry.height();
1885 stream << item.pos << item.size << pick(o, item.minimumSize())
1886 << pick(o, item.maximumSize());
1888 }
else if (item.placeHolderItem !=
nullptr) {
1889 stream << (uchar) WidgetMarker;
1890 stream << item.placeHolderItem->objectName;
1892 if (!item.placeHolderItem->hidden)
1893 flags |= StateFlagVisible;
1894 if (item.placeHolderItem->window)
1895 flags |= StateFlagFloating;
1897 if (item.placeHolderItem->window) {
1898 QRect r = item.placeHolderItem->topLevelRect;
1899 stream << r.x() << r.y() << r.width() << r.height();
1901 stream << item.pos << item.size << (
int)0 << (
int)0;
1903 }
else if (item.subinfo !=
nullptr) {
1904 stream << (uchar) SequenceMarker << item.pos << item.size << pick(o, item.minimumSize()) << pick(o, item.maximumSize());
1905 item.subinfo->saveState(stream);
1913 case QInternal::LeftDock:
return Qt::LeftDockWidgetArea;
1914 case QInternal::RightDock:
return Qt::RightDockWidgetArea;
1915 case QInternal::TopDock:
return Qt::TopDockWidgetArea;
1916 case QInternal::BottomDock:
return Qt::BottomDockWidgetArea;
1919 return Qt::NoDockWidgetArea;
1922bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> &widgets,
bool testing)
1926 if (marker != TabMarker && marker != SequenceMarker)
1929#if QT_CONFIG(tabbar)
1930 tabbed = marker == TabMarker;
1938 stream >> orientation;
1939 o =
static_cast<Qt::Orientation>(orientation);
1944 for (
int i = 0; i < cnt; ++i) {
1946 stream >> nextMarker;
1947 if (nextMarker == WidgetMarker) {
1950 stream >> name >> flags;
1951 if (name.isEmpty()) {
1953 stream >> dummy >> dummy >> dummy >> dummy;
1957 QDockWidget *widget =
nullptr;
1958 for (
int j = 0; j < widgets.size(); ++j) {
1959 if (widgets.at(j)->objectName() == name) {
1960 widget = widgets.takeAt(j);
1965 if (widget ==
nullptr) {
1966 QPlaceHolderItem *placeHolder =
new QPlaceHolderItem;
1967 QDockAreaLayoutItem item(placeHolder);
1969 placeHolder->objectName = name;
1970 placeHolder->window = flags & StateFlagFloating;
1971 placeHolder->hidden = !(flags & StateFlagVisible);
1972 if (placeHolder->window) {
1974 stream >> x >> y >> w >> h;
1975 placeHolder->topLevelRect = QRect(x, y, w, h);
1978 stream >> item.pos >> item.size >> dummy >> dummy;
1980 if (item.size != -1)
1981 item.flags |= QDockAreaLayoutItem::KeepSize;
1983 item_list.append(item);
1985 QDockAreaLayoutItem item(
new QDockWidgetItem(widget));
1986 if (flags & StateFlagFloating) {
1987 bool drawer =
false;
1992 widget->setFloating(
true);
1996 stream >> x >> y >> w >> h;
1999 widget->setGeometry(QDockAreaLayout::constrainedRect(QRect(x, y, w, h), widget));
2002 widget->setVisible(flags & StateFlagVisible);
2003 item_list.append(item);
2007 stream >> item.pos >> item.size >> dummy >> dummy;
2009 item_list.append(item);
2010 widget->setFloating(
false);
2011 widget->setVisible(flags & StateFlagVisible);
2012 emit widget->dockLocationChanged(toDockWidgetArea(dockPos));
2017 delete item.widgetItem;
2018 item.widgetItem =
nullptr;
2021 }
else if (nextMarker == SequenceMarker) {
2023#if !QT_CONFIG(tabbar)
2024 const int tabBarShape = 0;
2026 QDockAreaLayoutItem item(
new QDockAreaLayoutInfo(sep, dockPos, o,
2027 tabBarShape, mainWindow));
2028 stream >> item.pos >> item.size >> dummy >> dummy;
2031 item_list.append(item);
2034 QDockAreaLayoutItem &lastItem = testing ? item : item_list.last();
2036 if (!lastItem.subinfo->restoreState(stream, widgets, testing))
2044#if QT_CONFIG(tabbar)
2045 if (!testing && tabbed && index >= 0 && index < item_list.size()) {
2047 setCurrentTabId(tabId(item_list.at(index)));
2049 if (!testing && *sep == 1)
2050 updateSeparatorWidgets();
2056#if QT_CONFIG(tabbar)
2058static void raiseSeparatorWidget(QWidget *separatorWidget)
2060 Q_ASSERT(separatorWidget);
2062#if QT_CONFIG(toolbar)
2065 Q_ASSERT(separatorWidget->parent());
2066 const auto toolBars = separatorWidget->parent()->findChildren<QToolBar*>(Qt::FindDirectChildrenOnly);
2067 for (
auto *toolBar : toolBars) {
2068 if (
auto *toolBarLayout = qobject_cast<QToolBarLayout*>(toolBar->layout())) {
2069 if (toolBarLayout->expanded) {
2070 separatorWidget->stackUnder(toolBar);
2077 separatorWidget->raise();
2081void QDockAreaLayoutInfo::updateSeparatorWidgets()
const
2084 separatorWidgets.clear();
2089 for (
int i = 0; i < item_list.size(); ++i) {
2090 const QDockAreaLayoutItem &item = item_list.at(i);
2095 int next =
this->next(i);
2096 if ((item.flags & QDockAreaLayoutItem::GapItem)
2097 || (next != -1 && (item_list.at(next).flags & QDockAreaLayoutItem::GapItem)))
2101 item.subinfo->updateSeparatorWidgets();
2108 if (j < separatorWidgets.size()) {
2109 sepWidget = separatorWidgets.at(j);
2111 qWarning(
"QDockAreaLayoutInfo::updateSeparatorWidgets: null separator widget");
2112 sepWidget = mainWindowLayout()->getSeparatorWidget();
2113 separatorWidgets[j] = sepWidget;
2116 sepWidget = mainWindowLayout()->getSeparatorWidget();
2117 separatorWidgets.append(sepWidget);
2121 Q_ASSERT(sepWidget);
2122 raiseSeparatorWidget(sepWidget);
2124 QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
2125 sepWidget->setGeometry(sepRect);
2126 sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
2130 for (
int k = j; k < separatorWidgets.size(); ++k) {
2131 separatorWidgets[k]->hide();
2133 separatorWidgets.resize(j);
2137
2138
2139
2140
2141void QDockAreaLayoutInfo::reparentWidgets(QWidget *parent)
2144 tabBar->setParent(parent);
2146 for (
int i = 0; i < item_list.size(); ++i) {
2147 const QDockAreaLayoutItem &item = item_list.at(i);
2148 if (item.flags & QDockAreaLayoutItem::GapItem)
2151 item.subinfo->reparentWidgets(parent);
2152 if (item.widgetItem) {
2153 QWidget *w = item.widgetItem->widget();
2154 if (qobject_cast<QDockWidgetGroupWindow *>(w))
2156 if (w->parent() != parent) {
2157 bool hidden = w->isHidden();
2158 w->setParent(parent, w->windowFlags());
2167bool QDockAreaLayoutInfo::updateTabBar()
const
2172 QDockAreaLayoutInfo *that =
const_cast<QDockAreaLayoutInfo*>(
this);
2174 if (that->tabBar ==
nullptr) {
2175 that->tabBar = mainWindowLayout()->getTabBar();
2176 that->tabBar->setShape(
static_cast<QTabBar::Shape>(tabBarShape));
2177 that->tabBar->setDrawBase(
true);
2180 const QSignalBlocker blocker(tabBar);
2183 const quintptr oldCurrentId = currentTabId();
2186 for (
int i = 0; i < item_list.size(); ++i) {
2187 const QDockAreaLayoutItem &item = item_list.at(i);
2190 if (item.flags & QDockAreaLayoutItem::GapItem) {
2194 if (item.widgetItem ==
nullptr)
2197 QDockWidget *dw = qobject_cast<QDockWidget*>(item.widgetItem->widget());
2198 QString title = dw->d_func()->fixedWindowTitle;
2199 quintptr id = tabId(item);
2200 const QIcon windowIcon = dw->testAttribute(Qt::WA_SetWindowIcon) ? dw->windowIcon()
2202 if (tab_idx == tabBar->count()) {
2203 tabBar->insertTab(tab_idx, windowIcon, title);
2204#if QT_CONFIG(tooltip)
2205 tabBar->setTabToolTip(tab_idx, title);
2207 tabBar->setTabData(tab_idx, id);
2208 }
else if (qvariant_cast<quintptr>(tabBar->tabData(tab_idx)) != id) {
2209 if (tab_idx + 1 < tabBar->count()
2210 && qvariant_cast<quintptr>(tabBar->tabData(tab_idx + 1)) == id)
2211 tabBar->removeTab(tab_idx);
2213 tabBar->insertTab(tab_idx, windowIcon, title);
2214#if QT_CONFIG(tooltip)
2215 tabBar->setTabToolTip(tab_idx, title);
2217 tabBar->setTabData(tab_idx, id);
2221 if (title != tabBar->tabText(tab_idx)) {
2222 tabBar->setTabText(tab_idx, title);
2223#if QT_CONFIG(tooltip)
2224 tabBar->setTabToolTip(tab_idx, title);
2231 while (tab_idx < tabBar->count()) {
2232 tabBar->removeTab(tab_idx);
2235 if (oldCurrentId > 0 && currentTabId() != oldCurrentId)
2236 that->setCurrentTabId(oldCurrentId);
2238 if (QDockWidgetGroupWindow *dwgw = qobject_cast<QDockWidgetGroupWindow *>(tabBar->parent()))
2239 dwgw->adjustFlags();
2242 return ( (gap ? 1 : 0) + tabBar->count()) > 1;
2245void QDockAreaLayoutInfo::setTabBarShape(
int shape)
2247 if (shape == tabBarShape)
2249 tabBarShape = shape;
2250 if (tabBar !=
nullptr)
2251 tabBar->setShape(
static_cast<QTabBar::Shape>(shape));
2253 for (
int i = 0; i < item_list.size(); ++i) {
2254 QDockAreaLayoutItem &item = item_list[i];
2255 if (item.subinfo !=
nullptr)
2256 item.subinfo->setTabBarShape(shape);
2260QSize QDockAreaLayoutInfo::tabBarMinimumSize()
const
2262 if (!updateTabBar())
2265 return tabBar->minimumSizeHint();
2268QSize QDockAreaLayoutInfo::tabBarSizeHint()
const
2270 if (!updateTabBar())
2273 return tabBar->sizeHint();
2276QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars()
const
2278 QSet<QTabBar*> result;
2282 result.insert(tabBar);
2285 for (
int i = 0; i < item_list.size(); ++i) {
2286 const QDockAreaLayoutItem &item = item_list.at(i);
2287 if (item.subinfo !=
nullptr)
2288 result += item.subinfo->usedTabBars();
2296QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets()
const
2298 QSet<QWidget*> result;
2299 const int numSeparatorWidgets = separatorWidgets.size();
2300 result.reserve(numSeparatorWidgets);
2302 for (
int i = 0; i < numSeparatorWidgets; ++i)
2303 result << separatorWidgets.at(i);
2305 for (
int i = 0; i < item_list.size(); ++i) {
2306 const QDockAreaLayoutItem &item = item_list.at(i);
2307 if (item.subinfo !=
nullptr)
2308 result += item.subinfo->usedSeparatorWidgets();
2314QRect QDockAreaLayoutInfo::tabContentRect()
const
2319 QRect result = rect;
2320 QSize tbh = tabBarSizeHint();
2322 if (!tbh.isNull()) {
2323 switch (tabBarShape) {
2324 case QTabBar::RoundedNorth:
2325 case QTabBar::TriangularNorth:
2326 result.adjust(0, tbh.height(), 0, 0);
2328 case QTabBar::RoundedSouth:
2329 case QTabBar::TriangularSouth:
2330 result.adjust(0, 0, 0, -tbh.height());
2332 case QTabBar::RoundedEast:
2333 case QTabBar::TriangularEast:
2334 result.adjust(0, 0, -tbh.width(), 0);
2336 case QTabBar::RoundedWest:
2337 case QTabBar::TriangularWest:
2338 result.adjust(tbh.width(), 0, 0, 0);
2348int QDockAreaLayoutInfo::tabIndexToListIndex(
int tabIndex)
const
2350 Q_ASSERT(tabbed && tabBar);
2351 quintptr data = qvariant_cast<quintptr>(tabBar->tabData(tabIndex));
2352 for (
int i = 0; i < item_list.size(); ++i) {
2353 if (tabId(item_list.at(i)) == data)
2359void QDockAreaLayoutInfo::moveTab(
int from,
int to)
2361 item_list.move(tabIndexToListIndex(from), tabIndexToListIndex(to));
2366
2367
2369QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(
true)
2372 sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent,
nullptr, win);
2373#if QT_CONFIG(tabbar)
2374 const int tabShape = QTabBar::RoundedSouth;
2376 const int tabShape = 0;
2378 docks[QInternal::LeftDock]
2379 = QDockAreaLayoutInfo(&sep, QInternal::LeftDock, Qt::Vertical, tabShape, win);
2380 docks[QInternal::RightDock]
2381 = QDockAreaLayoutInfo(&sep, QInternal::RightDock, Qt::Vertical, tabShape, win);
2382 docks[QInternal::TopDock]
2383 = QDockAreaLayoutInfo(&sep, QInternal::TopDock, Qt::Horizontal, tabShape, win);
2384 docks[QInternal::BottomDock]
2385 = QDockAreaLayoutInfo(&sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win);
2386 centralWidgetItem =
nullptr;
2389 corners[Qt::TopLeftCorner] = Qt::TopDockWidgetArea;
2390 corners[Qt::TopRightCorner] = Qt::TopDockWidgetArea;
2391 corners[Qt::BottomLeftCorner] = Qt::BottomDockWidgetArea;
2392 corners[Qt::BottomRightCorner] = Qt::BottomDockWidgetArea;
2395bool QDockAreaLayout::isValid()
const
2397 return rect.isValid();
2400void QDockAreaLayout::saveState(QDataStream &stream)
const
2402 stream << (uchar) DockWidgetStateMarker;
2404 for (
int i = 0; i < QInternal::DockCount; ++i) {
2405 if (!docks[i].item_list.isEmpty())
2409 for (
int i = 0; i < QInternal::DockCount; ++i) {
2410 if (docks[i].item_list.isEmpty())
2412 stream << i << docks[i].rect.size();
2413 docks[i].saveState(stream);
2416 stream << centralWidgetRect.size();
2418 for (
int i = 0; i < 4; ++i)
2419 stream <<
static_cast<
int>(corners[i]);
2422bool QDockAreaLayout::restoreState(QDataStream &stream,
const QList<QDockWidget*> &_dockwidgets,
bool testing)
2424 QList<QDockWidget*> dockwidgets = _dockwidgets;
2428 for (
int i = 0; i < cnt; ++i) {
2434 docks[pos].rect = QRect(QPoint(0, 0), size);
2436 if (!docks[pos].restoreState(stream, dockwidgets, testing)) {
2437 stream.setStatus(QDataStream::ReadCorruptData);
2444 centralWidgetRect = QRect(QPoint(0, 0), size);
2446 bool ok = stream.status() == QDataStream::Ok;
2450 for (
int i = 0; i < 4; ++i)
2451 stream >> cornerData[i];
2452 if (stream.status() == QDataStream::Ok) {
2453 for (
int i = 0; i < 4; ++i)
2454 corners[i] =
static_cast<Qt::DockWidgetArea>(cornerData[i]);
2458 fallbackToSizeHints =
false;
2464QList<
int> QDockAreaLayout::indexOfPlaceHolder(
const QString &objectName)
const
2466 for (
int i = 0; i < QInternal::DockCount; ++i) {
2467 QList<
int> result = docks[i].indexOfPlaceHolder(objectName);
2468 if (!result.isEmpty()) {
2473 return QList<
int>();
2476QList<
int> QDockAreaLayout::indexOf(
const QWidget *dockWidget)
const
2478 for (
int i = 0; i < QInternal::DockCount; ++i) {
2479 QList<
int> result = docks[i].indexOf(dockWidget);
2480 if (!result.isEmpty()) {
2485 return QList<
int>();
2488QList<
int> QDockAreaLayout::gapIndex(
const QPoint &pos,
bool disallowTabs)
const
2490 QMainWindow::DockOptions opts = mainWindow->dockOptions();
2491 bool nestingEnabled = opts & QMainWindow::AllowNestedDocks;
2492 QDockAreaLayoutInfo::TabMode tabMode = QDockAreaLayoutInfo::NoTabs;
2493#if QT_CONFIG(tabbar)
2494 if (!disallowTabs) {
2495 if (opts & QMainWindow::AllowTabbedDocks || opts & QMainWindow::VerticalTabs)
2496 tabMode = QDockAreaLayoutInfo::AllowTabs;
2497 if (opts & QMainWindow::ForceTabbedDocks)
2498 tabMode = QDockAreaLayoutInfo::ForceTabs;
2500 if (tabMode == QDockAreaLayoutInfo::ForceTabs)
2501 nestingEnabled =
false;
2506 for (
int i = 0; i < QInternal::DockCount; ++i) {
2507 const QDockAreaLayoutInfo &info = docks[i];
2509 if (!info.isEmpty() && info.rect.contains(pos)) {
2511 = docks[i].gapIndex(pos, nestingEnabled, tabMode);
2512 if (!result.isEmpty())
2518 for (
int i = 0; i < QInternal::DockCount; ++i) {
2519 const QDockAreaLayoutInfo &info = docks[i];
2521 if (info.isEmpty()) {
2522 const QRect r = gapRect(
static_cast<QInternal::DockPosition>(i));
2523 if (r.contains(pos)) {
2524 if (opts & QMainWindow::ForceTabbedDocks && !info.item_list.isEmpty()) {
2527 return QList<
int>() << i << -1 << 0;
2529 return QList<
int>() << i << 0;
2535 return QList<
int>();
2538QRect QDockAreaLayout::gapRect(QInternal::DockPosition dockPos)
const
2540 Q_ASSERT_X(mainWindow,
"QDockAreaLayout::gapRect",
"Called without valid mainWindow pointer.");
2543 const QSize gapSize = (mainWindow->size()/2).boundedTo(QSize(EmptyDropAreaSize, EmptyDropAreaSize));
2547 if (mainWindow->height() < (2 * sep)) {
2548 qCWarning(lcQpaDockWidgets,
2549 "QDockAreaLayout::gapRect: Main window height %i is too small. Docking will not be possible.",
2550 mainWindow->height());
2553 if (mainWindow->width() < (2 * sep)) {
2554 qCWarning(lcQpaDockWidgets,
2555 "QDockAreaLayout::gapRect: Main window width %i is too small. Docking will not be possible.",
2556 mainWindow->width());
2561 case QInternal::LeftDock:
2562 return QRect(rect.left(), rect.top(), gapSize.width(), rect.height());
2563 case QInternal::RightDock:
2564 return QRect(rect.right() - gapSize.width(), rect.top(), gapSize.width(), rect.height());
2565 case QInternal::TopDock:
2566 return QRect(rect.left(), rect.top(), rect.width(), gapSize.height());
2567 case QInternal::BottomDock:
2568 return QRect(rect.left(), rect.bottom() - gapSize.height(), rect.width(), gapSize.height());
2569 case QInternal::DockCount:
2575QList<
int> QDockAreaLayout::findSeparator(
const QPoint &pos)
const
2578 for (
int i = 0; i < QInternal::DockCount; ++i) {
2579 const QDockAreaLayoutInfo &info = docks[i];
2582 QRect rect = separatorRect(i);
2583 if (!rect.isNull() && sep == 1)
2584 rect.adjust(-2, -2, 2, 2);
2585 if (rect.contains(pos) && !info.hasFixedSize()) {
2588 }
else if (info.rect.contains(pos)) {
2589 result = docks[i].findSeparator(pos);
2590 if (!result.isEmpty()) {
2600QDockAreaLayoutInfo *QDockAreaLayout::info(QWidget *widget)
2602 for (
int i = 0; i < QInternal::DockCount; ++i) {
2603 if (QDockAreaLayoutInfo *result = docks[i].info(widget))
2610QDockAreaLayoutInfo *QDockAreaLayout::info(
const QList<
int> &path)
2612 Q_ASSERT(!path.isEmpty());
2613 const int index = path.first();
2614 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2616 if (path.size() == 1)
2617 return &docks[index];
2619 return docks[index].info(path.mid(1));
2622const QDockAreaLayoutInfo *QDockAreaLayout::info(
const QList<
int> &path)
const
2624 return const_cast<QDockAreaLayout*>(
this)->info(path);
2627QDockAreaLayoutItem &QDockAreaLayout::item(
const QList<
int> &path)
2629 Q_ASSERT(!path.isEmpty());
2630 const int index = path.first();
2631 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2632 return docks[index].item(path.mid(1));
2635QRect QDockAreaLayout::itemRect(
const QList<
int> &path)
const
2637 Q_ASSERT(!path.isEmpty());
2638 const int index = path.first();
2639 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2640 return docks[index].itemRect(path.mid(1));
2643QRect QDockAreaLayout::separatorRect(
int index)
const
2645 const QDockAreaLayoutInfo &dock = docks[index];
2648 QRect r = dock.rect;
2650 case QInternal::LeftDock:
2651 return QRect(r.right() + 1, r.top(), sep, r.height());
2652 case QInternal::RightDock:
2653 return QRect(r.left() - sep, r.top(), sep, r.height());
2654 case QInternal::TopDock:
2655 return QRect(r.left(), r.bottom() + 1, r.width(), sep);
2656 case QInternal::BottomDock:
2657 return QRect(r.left(), r.top() - sep, r.width(), sep);
2664QRect QDockAreaLayout::separatorRect(
const QList<
int> &path)
const
2666 Q_ASSERT(!path.isEmpty());
2668 const int index = path.first();
2669 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2671 if (path.size() == 1)
2672 return separatorRect(index);
2674 return docks[index].separatorRect(path.mid(1));
2677bool QDockAreaLayout::insertGap(
const QList<
int> &path, QLayoutItem *dockWidgetItem)
2679 Q_ASSERT(!path.isEmpty());
2680 const int index = path.first();
2681 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2682 return docks[index].insertGap(path.mid(1), dockWidgetItem);
2685QLayoutItem *QDockAreaLayout::plug(
const QList<
int> &path)
2687#if QT_CONFIG(tabbar)
2688 Q_ASSERT(!path.isEmpty());
2689 const int index = path.first();
2690 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2691 QLayoutItem *item = docks[index].plug(path.mid(1));
2692 docks[index].reparentWidgets(mainWindow);
2699QLayoutItem *QDockAreaLayout::unplug(
const QList<
int> &path)
2701 Q_ASSERT(!path.isEmpty());
2702 const int index = path.first();
2703 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2704 return docks[index].unplug(path.mid(1));
2707void QDockAreaLayout::remove(
const QList<
int> &path)
2709 Q_ASSERT(!path.isEmpty());
2710 const int index = path.first();
2711 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2712 docks[index].remove(path.mid(1));
2715void QDockAreaLayout::removePlaceHolder(
const QString &name)
2717 QList<
int> index = indexOfPlaceHolder(name);
2718 if (!index.isEmpty())
2721 mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly);
2722 for (QDockWidgetGroupWindow *dwgw : groups) {
2723 index = dwgw->layoutInfo()->indexOfPlaceHolder(name);
2724 if (!index.isEmpty()) {
2725 dwgw->layoutInfo()->remove(index);
2726 dwgw->destroyOrHideIfEmpty();
2731static inline int qMax(
int i1,
int i2,
int i3) {
return qMax(i1, qMax(i2, i3)); }
2733void QDockAreaLayout::getGrid(QList<QLayoutStruct> *_ver_struct_list,
2734 QList<QLayoutStruct> *_hor_struct_list)
2736 QSize center_hint(0, 0);
2737 QSize center_min(0, 0);
2738 QSize center_max(0, 0);
2739 const bool have_central = centralWidgetItem !=
nullptr && !centralWidgetItem->isEmpty();
2741 center_hint = centralWidgetRect.size();
2742 if (!center_hint.isValid())
2743 center_hint = centralWidgetItem->sizeHint();
2744 center_min = centralWidgetItem->minimumSize();
2745 center_max = centralWidgetItem->maximumSize();
2748 QRect center_rect = rect;
2749 if (!docks[QInternal::LeftDock].isEmpty())
2750 center_rect.setLeft(rect.left() + docks[QInternal::LeftDock].rect.width() + sep);
2751 if (!docks[QInternal::TopDock].isEmpty())
2752 center_rect.setTop(rect.top() + docks[QInternal::TopDock].rect.height() + sep);
2753 if (!docks[QInternal::RightDock].isEmpty())
2754 center_rect.setRight(rect.right() - docks[QInternal::RightDock].rect.width() - sep);
2755 if (!docks[QInternal::BottomDock].isEmpty())
2756 center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep);
2758 QSize left_hint = docks[QInternal::LeftDock].size();
2759 if (left_hint.isNull() || fallbackToSizeHints)
2760 left_hint = docks[QInternal::LeftDock].sizeHint();
2761 QSize left_min = docks[QInternal::LeftDock].minimumSize();
2762 QSize left_max = docks[QInternal::LeftDock].maximumSize();
2763 left_hint = left_hint.boundedTo(left_max).expandedTo(left_min);
2765 QSize right_hint = docks[QInternal::RightDock].size();
2766 if (right_hint.isNull() || fallbackToSizeHints)
2767 right_hint = docks[QInternal::RightDock].sizeHint();
2768 QSize right_min = docks[QInternal::RightDock].minimumSize();
2769 QSize right_max = docks[QInternal::RightDock].maximumSize();
2770 right_hint = right_hint.boundedTo(right_max).expandedTo(right_min);
2772 QSize top_hint = docks[QInternal::TopDock].size();
2773 if (top_hint.isNull() || fallbackToSizeHints)
2774 top_hint = docks[QInternal::TopDock].sizeHint();
2775 QSize top_min = docks[QInternal::TopDock].minimumSize();
2776 QSize top_max = docks[QInternal::TopDock].maximumSize();
2777 top_hint = top_hint.boundedTo(top_max).expandedTo(top_min);
2779 QSize bottom_hint = docks[QInternal::BottomDock].size();
2780 if (bottom_hint.isNull() || fallbackToSizeHints)
2781 bottom_hint = docks[QInternal::BottomDock].sizeHint();
2782 QSize bottom_min = docks[QInternal::BottomDock].minimumSize();
2783 QSize bottom_max = docks[QInternal::BottomDock].maximumSize();
2784 bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min);
2786 if (_ver_struct_list !=
nullptr) {
2787 QList<QLayoutStruct> &ver_struct_list = *_ver_struct_list;
2788 ver_struct_list.resize(3);
2791 ver_struct_list[0].init();
2792 ver_struct_list[0].stretch = 0;
2793 ver_struct_list[0].sizeHint = top_hint.height();
2794 ver_struct_list[0].minimumSize = top_min.height();
2795 ver_struct_list[0].maximumSize = top_max.height();
2796 ver_struct_list[0].expansive =
false;
2797 ver_struct_list[0].empty = docks[QInternal::TopDock].isEmpty();
2798 ver_struct_list[0].pos = docks[QInternal::TopDock].rect.top();
2799 ver_struct_list[0].size = docks[QInternal::TopDock].rect.height();
2802 ver_struct_list[1].init();
2803 ver_struct_list[1].stretch = center_hint.height();
2805 bool tl_significant = corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
2806 || docks[QInternal::TopDock].isEmpty();
2807 bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
2808 || docks[QInternal::BottomDock].isEmpty();
2809 bool tr_significant = corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
2810 || docks[QInternal::TopDock].isEmpty();
2811 bool br_significant = corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
2812 || docks[QInternal::BottomDock].isEmpty();
2814 int left = (tl_significant && bl_significant) ? left_hint.height() : 0;
2815 int right = (tr_significant && br_significant) ? right_hint.height() : 0;
2816 ver_struct_list[1].sizeHint = qMax(left, center_hint.height(), right);
2818 left = (tl_significant && bl_significant) ? left_min.height() : 0;
2819 right = (tr_significant && br_significant) ? right_min.height() : 0;
2820 ver_struct_list[1].minimumSize = qMax(left, center_min.height(), right);
2821 ver_struct_list[1].maximumSize = center_max.height();
2822 ver_struct_list[1].expansive = have_central;
2823 ver_struct_list[1].empty = docks[QInternal::LeftDock].isEmpty()
2825 && docks[QInternal::RightDock].isEmpty();
2826 ver_struct_list[1].pos = center_rect.top();
2827 ver_struct_list[1].size = center_rect.height();
2830 ver_struct_list[2].init();
2831 ver_struct_list[2].stretch = 0;
2832 ver_struct_list[2].sizeHint = bottom_hint.height();
2833 ver_struct_list[2].minimumSize = bottom_min.height();
2834 ver_struct_list[2].maximumSize = bottom_max.height();
2835 ver_struct_list[2].expansive =
false;
2836 ver_struct_list[2].empty = docks[QInternal::BottomDock].isEmpty();
2837 ver_struct_list[2].pos = docks[QInternal::BottomDock].rect.top();
2838 ver_struct_list[2].size = docks[QInternal::BottomDock].rect.height();
2840 for (
int i = 0; i < 3; ++i) {
2841 ver_struct_list[i].sizeHint
2842 = qMax(ver_struct_list[i].sizeHint, ver_struct_list[i].minimumSize);
2844 if (have_central && ver_struct_list[0].empty && ver_struct_list[2].empty)
2845 ver_struct_list[1].maximumSize = QWIDGETSIZE_MAX;
2848 if (_hor_struct_list !=
nullptr) {
2849 QList<QLayoutStruct> &hor_struct_list = *_hor_struct_list;
2850 hor_struct_list.resize(3);
2853 hor_struct_list[0].init();
2854 hor_struct_list[0].stretch = 0;
2855 hor_struct_list[0].sizeHint = left_hint.width();
2856 hor_struct_list[0].minimumSize = left_min.width();
2857 hor_struct_list[0].maximumSize = left_max.width();
2858 hor_struct_list[0].expansive =
false;
2859 hor_struct_list[0].empty = docks[QInternal::LeftDock].isEmpty();
2860 hor_struct_list[0].pos = docks[QInternal::LeftDock].rect.left();
2861 hor_struct_list[0].size = docks[QInternal::LeftDock].rect.width();
2864 hor_struct_list[1].init();
2865 hor_struct_list[1].stretch = center_hint.width();
2867 bool tl_significant = corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
2868 || docks[QInternal::LeftDock].isEmpty();
2869 bool tr_significant = corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
2870 || docks[QInternal::RightDock].isEmpty();
2871 bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
2872 || docks[QInternal::LeftDock].isEmpty();
2873 bool br_significant = corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
2874 || docks[QInternal::RightDock].isEmpty();
2876 int top = (tl_significant && tr_significant) ? top_hint.width() : 0;
2877 int bottom = (bl_significant && br_significant) ? bottom_hint.width() : 0;
2878 hor_struct_list[1].sizeHint = qMax(top, center_hint.width(), bottom);
2880 top = (tl_significant && tr_significant) ? top_min.width() : 0;
2881 bottom = (bl_significant && br_significant) ? bottom_min.width() : 0;
2882 hor_struct_list[1].minimumSize = qMax(top, center_min.width(), bottom);
2884 hor_struct_list[1].maximumSize = center_max.width();
2885 hor_struct_list[1].expansive = have_central;
2886 hor_struct_list[1].empty = !have_central;
2887 hor_struct_list[1].pos = center_rect.left();
2888 hor_struct_list[1].size = center_rect.width();
2891 hor_struct_list[2].init();
2892 hor_struct_list[2].stretch = 0;
2893 hor_struct_list[2].sizeHint = right_hint.width();
2894 hor_struct_list[2].minimumSize = right_min.width();
2895 hor_struct_list[2].maximumSize = right_max.width();
2896 hor_struct_list[2].expansive =
false;
2897 hor_struct_list[2].empty = docks[QInternal::RightDock].isEmpty();
2898 hor_struct_list[2].pos = docks[QInternal::RightDock].rect.left();
2899 hor_struct_list[2].size = docks[QInternal::RightDock].rect.width();
2901 for (
int i = 0; i < 3; ++i) {
2902 hor_struct_list[i].sizeHint
2903 = qMax(hor_struct_list[i].sizeHint, hor_struct_list[i].minimumSize);
2905 if (have_central && hor_struct_list[0].empty && hor_struct_list[2].empty)
2906 hor_struct_list[1].maximumSize = QWIDGETSIZE_MAX;
2911void QDockAreaLayout::setGrid(QList<QLayoutStruct> *ver_struct_list,
2912 QList<QLayoutStruct> *hor_struct_list)
2917 if (!docks[QInternal::TopDock].isEmpty()) {
2918 QRect r = docks[QInternal::TopDock].rect;
2919 if (hor_struct_list !=
nullptr) {
2920 r.setLeft(corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
2921 || docks[QInternal::LeftDock].isEmpty()
2922 ? rect.left() : hor_struct_list->at(1).pos);
2923 r.setRight(corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
2924 || docks[QInternal::RightDock].isEmpty()
2925 ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
2927 if (ver_struct_list !=
nullptr) {
2928 r.setTop(rect.top());
2929 r.setBottom(ver_struct_list->at(1).pos - sep - 1);
2931 docks[QInternal::TopDock].rect = r;
2932 docks[QInternal::TopDock].fitItems();
2937 if (!docks[QInternal::BottomDock].isEmpty()) {
2938 QRect r = docks[QInternal::BottomDock].rect;
2939 if (hor_struct_list !=
nullptr) {
2940 r.setLeft(corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
2941 || docks[QInternal::LeftDock].isEmpty()
2942 ? rect.left() : hor_struct_list->at(1).pos);
2943 r.setRight(corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
2944 || docks[QInternal::RightDock].isEmpty()
2945 ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
2947 if (ver_struct_list !=
nullptr) {
2948 r.setTop(ver_struct_list->at(2).pos);
2949 r.setBottom(rect.bottom());
2951 docks[QInternal::BottomDock].rect = r;
2952 docks[QInternal::BottomDock].fitItems();
2957 if (!docks[QInternal::LeftDock].isEmpty()) {
2958 QRect r = docks[QInternal::LeftDock].rect;
2959 if (hor_struct_list !=
nullptr) {
2960 r.setLeft(rect.left());
2961 r.setRight(hor_struct_list->at(1).pos - sep - 1);
2963 if (ver_struct_list !=
nullptr) {
2964 r.setTop(corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
2965 || docks[QInternal::TopDock].isEmpty()
2966 ? rect.top() : ver_struct_list->at(1).pos);
2967 r.setBottom(corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
2968 || docks[QInternal::BottomDock].isEmpty()
2969 ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
2971 docks[QInternal::LeftDock].rect = r;
2972 docks[QInternal::LeftDock].fitItems();
2977 if (!docks[QInternal::RightDock].isEmpty()) {
2978 QRect r = docks[QInternal::RightDock].rect;
2979 if (hor_struct_list !=
nullptr) {
2980 r.setLeft(hor_struct_list->at(2).pos);
2981 r.setRight(rect.right());
2983 if (ver_struct_list !=
nullptr) {
2984 r.setTop(corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
2985 || docks[QInternal::TopDock].isEmpty()
2986 ? rect.top() : ver_struct_list->at(1).pos);
2987 r.setBottom(corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
2988 || docks[QInternal::BottomDock].isEmpty()
2989 ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
2991 docks[QInternal::RightDock].rect = r;
2992 docks[QInternal::RightDock].fitItems();
2997 if (hor_struct_list !=
nullptr) {
2998 centralWidgetRect.setLeft(hor_struct_list->at(1).pos);
2999 centralWidgetRect.setWidth(hor_struct_list->at(1).size);
3001 if (ver_struct_list !=
nullptr) {
3002 centralWidgetRect.setTop(ver_struct_list->at(1).pos);
3003 centralWidgetRect.setHeight(ver_struct_list->at(1).size);
3007void QDockAreaLayout::fitLayout()
3009 QList<QLayoutStruct> ver_struct_list(3);
3010 QList<QLayoutStruct> hor_struct_list(3);
3011 getGrid(&ver_struct_list, &hor_struct_list);
3013 qGeomCalc(ver_struct_list, 0, 3, rect.top(), rect.height(), sep);
3014 qGeomCalc(hor_struct_list, 0, 3, rect.left(), rect.width(), sep);
3016 setGrid(&ver_struct_list, &hor_struct_list);
3019void QDockAreaLayout::clear()
3021 for (
int i = 0; i < QInternal::DockCount; ++i)
3025 centralWidgetRect = QRect();
3028template<
typename SizePMF,
typename CenterPMF>
3029QSize QDockAreaLayout::size_helper(SizePMF sizeFn, CenterPMF centerFn)
const
3036 if (centralWidgetItem !=
nullptr) {
3037 left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep;
3038 right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep;
3039 top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep;
3040 bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
3043 const QSize left = (docks[QInternal::LeftDock].*sizeFn)() + QSize(left_sep, 0);
3044 const QSize right = (docks[QInternal::RightDock].*sizeFn)() + QSize(right_sep, 0);
3045 const QSize top = (docks[QInternal::TopDock].*sizeFn)() + QSize(0, top_sep);
3046 const QSize bottom = (docks[QInternal::BottomDock].*sizeFn)() + QSize(0, bottom_sep);
3047 const QSize center = centralWidgetItem ==
nullptr
3048 ? QSize(0, 0) : (centralWidgetItem->*centerFn)();
3050 int row1 = top.width();
3051 int row2 = left.width() + center.width() + right.width();
3052 int row3 = bottom.width();
3053 int col1 = left.height();
3054 int col2 = top.height() + center.height() + bottom.height();
3055 int col3 = right.height();
3057 if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea)
3058 row1 += left.width();
3060 col1 += top.height();
3062 if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea)
3063 row1 += right.width();
3065 col3 += top.height();
3067 if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea)
3068 row3 += left.width();
3070 col1 += bottom.height();
3072 if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea)
3073 row3 += right.width();
3075 col3 += bottom.height();
3077 return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
3080QSize QDockAreaLayout::sizeHint()
const
3082 return size_helper(&QDockAreaLayoutInfo::sizeHint, &QLayoutItem::sizeHint);
3085QSize QDockAreaLayout::minimumSize()
const
3087 return size_helper(&QDockAreaLayoutInfo::minimumSize, &QLayoutItem::minimumSize);
3091
3092
3093
3094
3095QSize QDockAreaLayout::minimumStableSize()
const
3097 return size_helper(&QDockAreaLayoutInfo::size, &QLayoutItem::minimumSize);
3101
3102
3103
3104
3105
3106QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget)
3108 QScreen *screen =
nullptr;
3109 if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1)
3110 screen = QGuiApplication::screenAt(rect.topLeft());
3112 screen = widget->screen();
3114 const QRect screenRect = screen->geometry();
3115 if (screenRect.isValid()) {
3116 rect.setWidth(qMin(rect.width(), screenRect.width()));
3117 rect.setHeight(qMin(rect.height(), screenRect.height()));
3118 rect.moveLeft(qMax(rect.left(), screenRect.left()));
3119 rect.moveTop(qMax(rect.top(), screenRect.top()));
3120 rect.moveRight(qMin(rect.right(), screenRect.right()));
3121 rect.moveBottom(qMin(rect.bottom(), screenRect.bottom()));
3127bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
3129 QDockAreaLayoutItem *item =
nullptr;
3131 mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly);
3132 for (QDockWidgetGroupWindow *dwgw : groups) {
3133 QList<
int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName());
3134 if (!index.isEmpty()) {
3135 dockWidget->setParent(dwgw);
3136 item =
const_cast<QDockAreaLayoutItem *>(&dwgw->layoutInfo()->item(index));
3141 QList<
int> index = indexOfPlaceHolder(dockWidget->objectName());
3142 if (index.isEmpty())
3144 item =
const_cast<QDockAreaLayoutItem *>(&
this->item(index));
3147 QPlaceHolderItem *placeHolder = item->placeHolderItem;
3148 Q_ASSERT(placeHolder !=
nullptr);
3150 item->widgetItem =
new QDockWidgetItem(dockWidget);
3152 if (placeHolder->window) {
3153 const QRect r = constrainedRect(placeHolder->topLevelRect, dockWidget);
3154 dockWidget->d_func()->setWindowState(QDockWidgetPrivate::WindowStates(
3155 {QDockWidgetPrivate::WindowState::Floating,
3156 QDockWidgetPrivate::WindowState::Unplug}), r);
3158 dockWidget->setVisible(!placeHolder->hidden);
3160 item->placeHolderItem =
nullptr;
3166void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget,
3167 Qt::Orientation orientation)
3169 QLayoutItem *dockWidgetItem =
new QDockWidgetItem(dockWidget);
3170 QDockAreaLayoutInfo &info = docks[pos];
3171 if (orientation == info.o || info.item_list.size() <= 1) {
3174 info.o = orientation;
3176 QDockAreaLayoutItem new_item(dockWidgetItem);
3177 info.item_list.append(new_item);
3178#if QT_CONFIG(tabbar)
3179 if (info.tabbed && !new_item.skip()) {
3180 info.updateTabBar();
3181 info.setCurrentTabId(tabId(new_item));
3185#if QT_CONFIG(tabbar)
3186 int tbshape = info.tabBarShape;
3190 QDockAreaLayoutInfo new_info(&sep, pos, orientation, tbshape, mainWindow);
3191 new_info.item_list.append(QDockAreaLayoutItem(
new QDockAreaLayoutInfo(info)));
3192 new_info.item_list.append(QDockAreaLayoutItem(dockWidgetItem));
3196 removePlaceHolder(dockWidget->objectName());
3199#if QT_CONFIG(tabbar)
3200void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
3202 const QList<
int> path = indexOf(first);
3206 QDockAreaLayoutInfo *info =
this->info(path);
3207 Q_ASSERT(info !=
nullptr);
3208 info->tab(path.last(),
new QDockWidgetItem(second));
3210 removePlaceHolder(second->objectName());
3214void QDockAreaLayout::resizeDocks(
const QList<QDockWidget *> &docks,
3215 const QList<
int> &sizes, Qt::Orientation o)
3217 if (Q_UNLIKELY(docks.size() != sizes.size())) {
3218 qWarning(
"QMainWidget::resizeDocks: size of the lists are not the same");
3221 int count = docks.size();
3222 fallbackToSizeHints =
false;
3223 for (
int i = 0; i < count; ++i) {
3224 QList<
int> path = indexOf(docks[i]);
3225 if (Q_UNLIKELY(path.isEmpty())) {
3226 qWarning(
"QMainWidget::resizeDocks: one QDockWidget is not part of the layout");
3229 int size = sizes[i];
3230 if (Q_UNLIKELY(size <= 0)) {
3231 qWarning(
"QMainWidget::resizeDocks: all sizes need to be larger than 0");
3235 while (path.size() > 1) {
3236 QDockAreaLayoutInfo *info =
this->info(path);
3237#if QT_CONFIG(tabbar)
3238 if (!info->tabbed && info->o == o) {
3239 info->item_list[path.constLast()].size = size;
3241 for (
const QDockAreaLayoutItem &item : std::as_const(info->item_list)) {
3245 totalSize += item.size == -1 ? pick(o, item.sizeHint()) : item.size;
3254 const int dockNum = path.constFirst();
3255 Q_ASSERT(dockNum < QInternal::DockCount);
3256 QRect &r =
this->docks[dockNum].rect;
3263void QDockAreaLayout::splitDockWidget(QDockWidget *after,
3264 QDockWidget *dockWidget,
3265 Qt::Orientation orientation)
3267 const QList<
int> path = indexOf(after);
3271 QDockAreaLayoutInfo *info =
this->info(path);
3272 Q_ASSERT(info !=
nullptr);
3273 info->split(path.last(), orientation,
new QDockWidgetItem(dockWidget));
3275 removePlaceHolder(dockWidget->objectName());
3278void QDockAreaLayout::apply(
bool animate)
3280 QWidgetAnimator &widgetAnimator = qt_mainwindow_layout(mainWindow)->widgetAnimator;
3282 for (
int i = 0; i < QInternal::DockCount; ++i)
3283 docks[i].apply(animate);
3284 if (centralWidgetItem !=
nullptr && !centralWidgetItem->isEmpty()) {
3285 widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect,
3288#if QT_CONFIG(tabbar)
3290 updateSeparatorWidgets();
3294void QDockAreaLayout::paintSeparators(QPainter *p, QWidget *widget,
3295 const QRegion &clip,
3296 const QPoint &mouse)
const
3298 for (
int i = 0; i < QInternal::DockCount; ++i) {
3299 const QDockAreaLayoutInfo &dock = docks[i];
3302 QRect r = separatorRect(i);
3303 if (clip.contains(r) && !dock.hasFixedSize()) {
3304 Qt::Orientation opposite = dock.o == Qt::Horizontal
3305 ? Qt::Vertical : Qt::Horizontal;
3306 paintSep(p, widget, r, opposite, r.contains(mouse));
3308 if (clip.contains(dock.rect))
3309 dock.paintSeparators(p, widget, clip, mouse);
3313QRegion QDockAreaLayout::separatorRegion()
const
3317 for (
int i = 0; i < QInternal::DockCount; ++i) {
3318 const QDockAreaLayoutInfo &dock = docks[i];
3321 result |= separatorRect(i);
3322 result |= dock.separatorRegion();
3328int QDockAreaLayout::separatorMove(
const QList<
int> &separator,
const QPoint &origin,
3332 const auto dockPosition =
static_cast<QInternal::DockPosition>(separator.last());
3333 const bool isHorizontal =
3334 dockPosition == QInternal::LeftDock || dockPosition == QInternal::RightDock;
3335 const bool isLeftOrTop = dockPosition == QInternal::LeftDock || dockPosition == QInternal::TopDock;
3336 const bool separatorIsWithinDock = separator.size() > 1;
3338 if (separatorIsWithinDock) {
3342 QDockAreaLayoutInfo *info =
this->info(separator);
3343 delta = pick(info->o, dest - origin);
3345 delta = info->separatorMove(dockPosition, delta);
3346 info->apply(
false);
3356 QList<QLayoutStruct> list;
3359 getGrid(
nullptr, &list);
3361 getGrid(&list,
nullptr);
3363 const int sep_index = isLeftOrTop ? 0 : 1;
3364 const Qt::Orientation o = isHorizontal ? Qt::Horizontal : Qt::Vertical;
3366 delta = pick(o, dest - origin);
3367 delta = separatorMoveHelper(list, sep_index, delta, sep);
3369 fallbackToSizeHints =
false;
3372 setGrid(
nullptr, &list);
3374 setGrid(&list,
nullptr);
3381int QDockAreaLayoutInfo::separatorMove(
const QList<
int> &separator,
const QPoint &origin,
3385 int index = separator.last();
3386 QDockAreaLayoutInfo *info =
this->info(separator);
3387 delta = pick(info->o, dest - origin);
3389 delta = info->separatorMove(index, delta);
3390 info->apply(
false);
3394#if QT_CONFIG(tabbar)
3397void QDockAreaLayout::updateSeparatorWidgets()
const
3401 for (
int i = 0; i < QInternal::DockCount; ++i) {
3402 const QDockAreaLayoutInfo &dock = docks[i];
3407 if (j < separatorWidgets.size()) {
3408 sepWidget = separatorWidgets.at(j);
3410 qWarning(
"QDockAreaLayout::updateSeparatorWidgets: null separator widget");
3411 sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
3412 separatorWidgets[j] = sepWidget;
3415 sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
3416 separatorWidgets.append(sepWidget);
3420 Q_ASSERT(sepWidget);
3421 raiseSeparatorWidget(sepWidget);
3423 QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
3424 sepWidget->setGeometry(sepRect);
3425 sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
3428 for (
int i = j; i < separatorWidgets.size(); ++i)
3429 separatorWidgets.at(i)->hide();
3431 separatorWidgets.resize(j);
3435QLayoutItem *QDockAreaLayout::itemAt(
int *x,
int index)
const
3437 Q_ASSERT(x !=
nullptr);
3439 for (
int i = 0; i < QInternal::DockCount; ++i) {
3440 const QDockAreaLayoutInfo &dock = docks[i];
3441 if (QLayoutItem *ret = dock.itemAt(x, index))
3445 if (centralWidgetItem && (*x)++ == index)
3446 return centralWidgetItem;
3451QLayoutItem *QDockAreaLayout::takeAt(
int *x,
int index)
3453 Q_ASSERT(x !=
nullptr);
3455 for (
int i = 0; i < QInternal::DockCount; ++i) {
3456 QDockAreaLayoutInfo &dock = docks[i];
3457 if (QLayoutItem *ret = dock.takeAt(x, index))
3461 if (centralWidgetItem && (*x)++ == index) {
3462 QLayoutItem *ret = centralWidgetItem;
3463 centralWidgetItem =
nullptr;
3470void QDockAreaLayout::deleteAllLayoutItems()
3472 for (
int i = 0; i < QInternal::DockCount; ++i)
3473 docks[i].deleteAllLayoutItems();
3476#if QT_CONFIG(tabbar)
3477QSet<QTabBar*> QDockAreaLayout::usedTabBars()
const
3479 QSet<QTabBar*> result;
3480 for (
int i = 0; i < QInternal::DockCount; ++i) {
3481 const QDockAreaLayoutInfo &dock = docks[i];
3482 result += dock.usedTabBars();
3488QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets()
const
3490 QSet<QWidget*> result;
3491 const int numSeparators = separatorWidgets.size();
3492 result.reserve(numSeparators);
3493 for (
int i = 0; i < numSeparators; ++i)
3494 result << separatorWidgets.at(i);
3495 for (
int i = 0; i < QInternal::DockCount; ++i) {
3496 const QDockAreaLayoutInfo &dock = docks[i];
3497 result += dock.usedSeparatorWidgets();
3503QRect QDockAreaLayout::gapRect(
const QList<
int> &path)
const
3505 const QDockAreaLayoutInfo *info =
this->info(path);
3506 if (info ==
nullptr)
3508 int index = path.last();
3509 if (index < 0 || index >= info->item_list.size())
3511 return info->itemRect(index,
true);
3514void QDockAreaLayout::keepSize(QDockWidget *w)
3516 QList<
int> path = indexOf(w);
3519 QDockAreaLayoutItem &item =
this->item(path);
3520 if (item.size != -1)
3521 item.flags |= QDockAreaLayoutItem::KeepSize;
3524void QDockAreaLayout::styleChangedEvent()
3526 sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent,
nullptr, mainWindow);
static int grow(QLayoutStruct &ls, int delta)
static QRect dockedGeometry(QWidget *widget)
static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
static int realMinSize(const QDockAreaLayoutInfo &info)
static int qMax(int i1, int i2, int i3)
static int shrink(QLayoutStruct &ls, int delta)
static int separatorMoveHelper(QList< QLayoutStruct > &list, int index, int delta, int sep)
static QInternal::DockPosition dockPosHelper(const QRect &rect, const QPoint &_pos, Qt::Orientation o, bool nestingEnabled, QDockAreaLayoutInfo::TabMode tabMode)
static void paintSep(QPainter *p, QWidget *w, const QRect &r, Qt::Orientation o, bool mouse_over)
static int realMaxSize(const QDockAreaLayoutInfo &info)
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *window)