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, QInternal::CallMode callMode)
1924 const bool testing = callMode == QInternal::Testing;
1927 if (marker != TabMarker && marker != SequenceMarker)
1930#if QT_CONFIG(tabbar)
1931 tabbed = marker == TabMarker;
1939 stream >> orientation;
1940 o =
static_cast<Qt::Orientation>(orientation);
1945 for (
int i = 0; i < cnt; ++i) {
1947 stream >> nextMarker;
1948 if (nextMarker == WidgetMarker) {
1951 stream >> name >> flags;
1952 if (name.isEmpty()) {
1954 stream >> dummy >> dummy >> dummy >> dummy;
1958 QDockWidget *widget =
nullptr;
1959 for (
int j = 0; j < widgets.size(); ++j) {
1960 if (widgets.at(j)->objectName() == name) {
1961 widget = widgets.takeAt(j);
1966 if (widget ==
nullptr) {
1967 QPlaceHolderItem *placeHolder =
new QPlaceHolderItem;
1968 QDockAreaLayoutItem item(placeHolder);
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;
1982 placeHolder->objectName = std::move(name);
1984 item_list.append(item);
1986 QDockAreaLayoutItem item(
new QDockWidgetItem(widget));
1987 if (flags & StateFlagFloating) {
1988 bool drawer =
false;
1993 widget->setFloating(
true);
1997 stream >> x >> y >> w >> h;
2000 widget->setGeometry(QDockAreaLayout::constrainedRect(QRect(x, y, w, h), widget));
2003 widget->setVisible(flags & StateFlagVisible);
2004 item_list.append(item);
2008 stream >> item.pos >> item.size >> dummy >> dummy;
2010 item_list.append(item);
2011 widget->setFloating(
false);
2012 widget->setVisible(flags & StateFlagVisible);
2013 emit widget->dockLocationChanged(toDockWidgetArea(dockPos));
2018 delete item.widgetItem;
2019 item.widgetItem =
nullptr;
2022 }
else if (nextMarker == SequenceMarker) {
2024#if !QT_CONFIG(tabbar)
2025 const int tabBarShape = 0;
2027 QDockAreaLayoutItem item(
new QDockAreaLayoutInfo(sep, dockPos, o,
2028 tabBarShape, mainWindow));
2029 stream >> item.pos >> item.size >> dummy >> dummy;
2032 item_list.append(item);
2035 QDockAreaLayoutItem &lastItem = testing ? item : item_list.last();
2037 if (!lastItem.subinfo->restoreState(stream, widgets, callMode))
2045#if QT_CONFIG(tabbar)
2046 if (!testing && tabbed && index >= 0 && index < item_list.size()) {
2048 setCurrentTabId(tabId(item_list.at(index)));
2050 if (!testing && *sep == 1)
2051 updateSeparatorWidgets();
2057#if QT_CONFIG(tabbar)
2059static void raiseSeparatorWidget(QWidget *separatorWidget)
2061 Q_ASSERT(separatorWidget);
2063#if QT_CONFIG(toolbar)
2066 Q_ASSERT(separatorWidget->parent());
2067 const auto toolBars = separatorWidget->parent()->findChildren<QToolBar*>(Qt::FindDirectChildrenOnly);
2068 for (
auto *toolBar : toolBars) {
2069 if (
auto *toolBarLayout = qobject_cast<QToolBarLayout*>(toolBar->layout())) {
2070 if (toolBarLayout->expanded) {
2071 separatorWidget->stackUnder(toolBar);
2078 separatorWidget->raise();
2082void QDockAreaLayoutInfo::updateSeparatorWidgets()
const
2085 separatorWidgets.clear();
2090 for (
int i = 0; i < item_list.size(); ++i) {
2091 const QDockAreaLayoutItem &item = item_list.at(i);
2096 int next =
this->next(i);
2097 if ((item.flags & QDockAreaLayoutItem::GapItem)
2098 || (next != -1 && (item_list.at(next).flags & QDockAreaLayoutItem::GapItem)))
2102 item.subinfo->updateSeparatorWidgets();
2109 if (j < separatorWidgets.size()) {
2110 sepWidget = separatorWidgets.at(j);
2112 qWarning(
"QDockAreaLayoutInfo::updateSeparatorWidgets: null separator widget");
2113 sepWidget = mainWindowLayout()->getSeparatorWidget();
2114 separatorWidgets[j] = sepWidget;
2117 sepWidget = mainWindowLayout()->getSeparatorWidget();
2118 separatorWidgets.append(sepWidget);
2122 Q_ASSERT(sepWidget);
2123 raiseSeparatorWidget(sepWidget);
2125 QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
2126 sepWidget->setGeometry(sepRect);
2127 sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
2131 for (
int k = j; k < separatorWidgets.size(); ++k) {
2132 separatorWidgets[k]->hide();
2134 separatorWidgets.resize(j);
2138
2139
2140
2141
2142void QDockAreaLayoutInfo::reparentWidgets(QWidget *parent)
2145 tabBar->setParent(parent);
2147 for (
int i = 0; i < item_list.size(); ++i) {
2148 const QDockAreaLayoutItem &item = item_list.at(i);
2149 if (item.flags & QDockAreaLayoutItem::GapItem)
2152 item.subinfo->reparentWidgets(parent);
2153 if (item.widgetItem) {
2154 QWidget *w = item.widgetItem->widget();
2155 if (qobject_cast<QDockWidgetGroupWindow *>(w))
2157 if (w->parent() != parent) {
2158 bool hidden = w->isHidden();
2159 w->setParent(parent, w->windowFlags());
2168bool QDockAreaLayoutInfo::updateTabBar()
const
2173 QDockAreaLayoutInfo *that =
const_cast<QDockAreaLayoutInfo*>(
this);
2175 if (that->tabBar ==
nullptr) {
2176 that->tabBar = mainWindowLayout()->getTabBar();
2177 that->tabBar->setShape(
static_cast<QTabBar::Shape>(tabBarShape));
2178 that->tabBar->setDrawBase(
true);
2181 const QSignalBlocker blocker(tabBar);
2184 const quintptr oldCurrentId = currentTabId();
2187 for (
int i = 0; i < item_list.size(); ++i) {
2188 const QDockAreaLayoutItem &item = item_list.at(i);
2191 if (item.flags & QDockAreaLayoutItem::GapItem) {
2195 if (item.widgetItem ==
nullptr)
2198 QDockWidget *dw = qobject_cast<QDockWidget*>(item.widgetItem->widget());
2199 QString title = dw->d_func()->fixedWindowTitle;
2200 quintptr id = tabId(item);
2201 const QIcon windowIcon = dw->testAttribute(Qt::WA_SetWindowIcon) ? dw->windowIcon()
2203 if (tab_idx == tabBar->count()) {
2204 tabBar->insertTab(tab_idx, windowIcon, title);
2205#if QT_CONFIG(tooltip)
2206 tabBar->setTabToolTip(tab_idx, title);
2208 tabBar->setTabData(tab_idx, id);
2209 }
else if (qvariant_cast<quintptr>(tabBar->tabData(tab_idx)) != id) {
2210 if (tab_idx + 1 < tabBar->count()
2211 && qvariant_cast<quintptr>(tabBar->tabData(tab_idx + 1)) == id)
2212 tabBar->removeTab(tab_idx);
2214 tabBar->insertTab(tab_idx, windowIcon, title);
2215#if QT_CONFIG(tooltip)
2216 tabBar->setTabToolTip(tab_idx, title);
2218 tabBar->setTabData(tab_idx, id);
2222 if (title != tabBar->tabText(tab_idx)) {
2223 tabBar->setTabText(tab_idx, title);
2224#if QT_CONFIG(tooltip)
2225 tabBar->setTabToolTip(tab_idx, title);
2232 while (tab_idx < tabBar->count()) {
2233 tabBar->removeTab(tab_idx);
2236 if (oldCurrentId > 0 && currentTabId() != oldCurrentId)
2237 that->setCurrentTabId(oldCurrentId);
2239 if (QDockWidgetGroupWindow *dwgw = qobject_cast<QDockWidgetGroupWindow *>(tabBar->parent()))
2240 dwgw->adjustFlags();
2243 return ( (gap ? 1 : 0) + tabBar->count()) > 1;
2246void QDockAreaLayoutInfo::setTabBarShape(
int shape)
2248 if (shape == tabBarShape)
2250 tabBarShape = shape;
2251 if (tabBar !=
nullptr)
2252 tabBar->setShape(
static_cast<QTabBar::Shape>(shape));
2254 for (
int i = 0; i < item_list.size(); ++i) {
2255 QDockAreaLayoutItem &item = item_list[i];
2256 if (item.subinfo !=
nullptr)
2257 item.subinfo->setTabBarShape(shape);
2261QSize QDockAreaLayoutInfo::tabBarMinimumSize()
const
2263 if (!updateTabBar())
2266 return tabBar->minimumSizeHint();
2269QSize QDockAreaLayoutInfo::tabBarSizeHint()
const
2271 if (!updateTabBar())
2274 return tabBar->sizeHint();
2277QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars()
const
2279 QSet<QTabBar*> result;
2283 result.insert(tabBar);
2286 for (
int i = 0; i < item_list.size(); ++i) {
2287 const QDockAreaLayoutItem &item = item_list.at(i);
2288 if (item.subinfo !=
nullptr)
2289 result += item.subinfo->usedTabBars();
2297QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets()
const
2299 QSet<QWidget*> result;
2300 const int numSeparatorWidgets = separatorWidgets.size();
2301 result.reserve(numSeparatorWidgets);
2303 for (
int i = 0; i < numSeparatorWidgets; ++i)
2304 result << separatorWidgets.at(i);
2306 for (
int i = 0; i < item_list.size(); ++i) {
2307 const QDockAreaLayoutItem &item = item_list.at(i);
2308 if (item.subinfo !=
nullptr)
2309 result += item.subinfo->usedSeparatorWidgets();
2315QRect QDockAreaLayoutInfo::tabContentRect()
const
2320 QRect result = rect;
2321 QSize tbh = tabBarSizeHint();
2323 if (!tbh.isNull()) {
2324 switch (tabBarShape) {
2325 case QTabBar::RoundedNorth:
2326 case QTabBar::TriangularNorth:
2327 result.adjust(0, tbh.height(), 0, 0);
2329 case QTabBar::RoundedSouth:
2330 case QTabBar::TriangularSouth:
2331 result.adjust(0, 0, 0, -tbh.height());
2333 case QTabBar::RoundedEast:
2334 case QTabBar::TriangularEast:
2335 result.adjust(0, 0, -tbh.width(), 0);
2337 case QTabBar::RoundedWest:
2338 case QTabBar::TriangularWest:
2339 result.adjust(tbh.width(), 0, 0, 0);
2349int QDockAreaLayoutInfo::tabIndexToListIndex(
int tabIndex)
const
2351 Q_ASSERT(tabbed && tabBar);
2352 quintptr data = qvariant_cast<quintptr>(tabBar->tabData(tabIndex));
2353 for (
int i = 0; i < item_list.size(); ++i) {
2354 if (tabId(item_list.at(i)) == data)
2360void QDockAreaLayoutInfo::moveTab(
int from,
int to)
2362 item_list.move(tabIndexToListIndex(from), tabIndexToListIndex(to));
2367
2368
2370QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(
true)
2373 sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent,
nullptr, win);
2374#if QT_CONFIG(tabbar)
2375 const int tabShape = QTabBar::RoundedSouth;
2377 const int tabShape = 0;
2379 docks[QInternal::LeftDock]
2380 = QDockAreaLayoutInfo(&sep, QInternal::LeftDock, Qt::Vertical, tabShape, win);
2381 docks[QInternal::RightDock]
2382 = QDockAreaLayoutInfo(&sep, QInternal::RightDock, Qt::Vertical, tabShape, win);
2383 docks[QInternal::TopDock]
2384 = QDockAreaLayoutInfo(&sep, QInternal::TopDock, Qt::Horizontal, tabShape, win);
2385 docks[QInternal::BottomDock]
2386 = QDockAreaLayoutInfo(&sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win);
2387 centralWidgetItem =
nullptr;
2390 corners[Qt::TopLeftCorner] = Qt::TopDockWidgetArea;
2391 corners[Qt::TopRightCorner] = Qt::TopDockWidgetArea;
2392 corners[Qt::BottomLeftCorner] = Qt::BottomDockWidgetArea;
2393 corners[Qt::BottomRightCorner] = Qt::BottomDockWidgetArea;
2396bool QDockAreaLayout::isValid()
const
2398 return rect.isValid();
2401void QDockAreaLayout::saveState(QDataStream &stream)
const
2403 stream << (uchar) DockWidgetStateMarker;
2405 for (
int i = 0; i < QInternal::DockCount; ++i) {
2406 if (!docks[i].item_list.isEmpty())
2410 for (
int i = 0; i < QInternal::DockCount; ++i) {
2411 if (docks[i].item_list.isEmpty())
2413 stream << i << docks[i].rect.size();
2414 docks[i].saveState(stream);
2417 stream << centralWidgetRect.size();
2419 for (
int i = 0; i < 4; ++i)
2420 stream <<
static_cast<
int>(corners[i]);
2423bool QDockAreaLayout::restoreState(QDataStream &stream,
const QList<QDockWidget*> &_dockwidgets, QInternal::CallMode callMode)
2425 QList<QDockWidget*> dockwidgets = _dockwidgets;
2426 const bool testing = callMode == QInternal::Testing;
2429 for (
int i = 0; i < cnt; ++i) {
2435 docks[pos].rect = QRect(QPoint(0, 0), size);
2437 if (!docks[pos].restoreState(stream, dockwidgets, callMode)) {
2438 stream.setStatus(QDataStream::ReadCorruptData);
2445 centralWidgetRect = QRect(QPoint(0, 0), size);
2447 bool ok = stream.status() == QDataStream::Ok;
2451 for (
int i = 0; i < 4; ++i)
2452 stream >> cornerData[i];
2453 if (stream.status() == QDataStream::Ok) {
2454 for (
int i = 0; i < 4; ++i)
2455 corners[i] =
static_cast<Qt::DockWidgetArea>(cornerData[i]);
2459 fallbackToSizeHints =
false;
2465QList<
int> QDockAreaLayout::indexOfPlaceHolder(
const QString &objectName)
const
2467 for (
int i = 0; i < QInternal::DockCount; ++i) {
2468 QList<
int> result = docks[i].indexOfPlaceHolder(objectName);
2469 if (!result.isEmpty()) {
2474 return QList<
int>();
2477QList<
int> QDockAreaLayout::indexOf(
const QWidget *dockWidget)
const
2479 for (
int i = 0; i < QInternal::DockCount; ++i) {
2480 QList<
int> result = docks[i].indexOf(dockWidget);
2481 if (!result.isEmpty()) {
2486 return QList<
int>();
2489QList<
int> QDockAreaLayout::gapIndex(
const QPoint &pos,
bool disallowTabs)
const
2491 QMainWindow::DockOptions opts = mainWindow->dockOptions();
2492 bool nestingEnabled = opts & QMainWindow::AllowNestedDocks;
2493 QDockAreaLayoutInfo::TabMode tabMode = QDockAreaLayoutInfo::NoTabs;
2494#if QT_CONFIG(tabbar)
2495 if (!disallowTabs) {
2496 if (opts & QMainWindow::AllowTabbedDocks || opts & QMainWindow::VerticalTabs)
2497 tabMode = QDockAreaLayoutInfo::AllowTabs;
2498 if (opts & QMainWindow::ForceTabbedDocks)
2499 tabMode = QDockAreaLayoutInfo::ForceTabs;
2501 if (tabMode == QDockAreaLayoutInfo::ForceTabs)
2502 nestingEnabled =
false;
2507 for (
int i = 0; i < QInternal::DockCount; ++i) {
2508 const QDockAreaLayoutInfo &info = docks[i];
2510 if (!info.isEmpty() && info.rect.contains(pos)) {
2512 = docks[i].gapIndex(pos, nestingEnabled, tabMode);
2513 if (!result.isEmpty())
2519 for (
int i = 0; i < QInternal::DockCount; ++i) {
2520 const QDockAreaLayoutInfo &info = docks[i];
2522 if (info.isEmpty()) {
2523 const QRect r = gapRect(
static_cast<QInternal::DockPosition>(i));
2524 if (r.contains(pos)) {
2525 if (opts & QMainWindow::ForceTabbedDocks && !info.item_list.isEmpty()) {
2528 return QList<
int>() << i << -1 << 0;
2530 return QList<
int>() << i << 0;
2536 return QList<
int>();
2539QRect QDockAreaLayout::gapRect(QInternal::DockPosition dockPos)
const
2541 Q_ASSERT_X(mainWindow,
"QDockAreaLayout::gapRect",
"Called without valid mainWindow pointer.");
2544 const QSize gapSize = (mainWindow->size()/2).boundedTo(QSize(EmptyDropAreaSize, EmptyDropAreaSize));
2548 if (mainWindow->height() < (2 * sep)) {
2549 qCWarning(lcQpaDockWidgets,
2550 "QDockAreaLayout::gapRect: Main window height %i is too small. Docking will not be possible.",
2551 mainWindow->height());
2554 if (mainWindow->width() < (2 * sep)) {
2555 qCWarning(lcQpaDockWidgets,
2556 "QDockAreaLayout::gapRect: Main window width %i is too small. Docking will not be possible.",
2557 mainWindow->width());
2562 case QInternal::LeftDock:
2563 return QRect(rect.left(), rect.top(), gapSize.width(), rect.height());
2564 case QInternal::RightDock:
2565 return QRect(rect.right() - gapSize.width(), rect.top(), gapSize.width(), rect.height());
2566 case QInternal::TopDock:
2567 return QRect(rect.left(), rect.top(), rect.width(), gapSize.height());
2568 case QInternal::BottomDock:
2569 return QRect(rect.left(), rect.bottom() - gapSize.height(), rect.width(), gapSize.height());
2570 case QInternal::DockCount:
2576QList<
int> QDockAreaLayout::findSeparator(
const QPoint &pos)
const
2579 for (
int i = 0; i < QInternal::DockCount; ++i) {
2580 const QDockAreaLayoutInfo &info = docks[i];
2583 QRect rect = separatorRect(i);
2584 if (!rect.isNull() && sep == 1)
2585 rect.adjust(-2, -2, 2, 2);
2586 if (rect.contains(pos) && !info.hasFixedSize()) {
2589 }
else if (info.rect.contains(pos)) {
2590 result = docks[i].findSeparator(pos);
2591 if (!result.isEmpty()) {
2601QDockAreaLayoutInfo *QDockAreaLayout::info(QWidget *widget)
2603 for (
int i = 0; i < QInternal::DockCount; ++i) {
2604 if (QDockAreaLayoutInfo *result = docks[i].info(widget))
2611QDockAreaLayoutInfo *QDockAreaLayout::info(
const QList<
int> &path)
2613 Q_ASSERT(!path.isEmpty());
2614 const int index = path.first();
2615 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2617 if (path.size() == 1)
2618 return &docks[index];
2620 return docks[index].info(path.mid(1));
2623const QDockAreaLayoutInfo *QDockAreaLayout::info(
const QList<
int> &path)
const
2625 return const_cast<QDockAreaLayout*>(
this)->info(path);
2628QDockAreaLayoutItem &QDockAreaLayout::item(
const QList<
int> &path)
2630 Q_ASSERT(!path.isEmpty());
2631 const int index = path.first();
2632 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2633 return docks[index].item(path.mid(1));
2636QRect QDockAreaLayout::itemRect(
const QList<
int> &path)
const
2638 Q_ASSERT(!path.isEmpty());
2639 const int index = path.first();
2640 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2641 return docks[index].itemRect(path.mid(1));
2644QRect QDockAreaLayout::separatorRect(
int index)
const
2646 const QDockAreaLayoutInfo &dock = docks[index];
2649 QRect r = dock.rect;
2651 case QInternal::LeftDock:
2652 return QRect(r.right() + 1, r.top(), sep, r.height());
2653 case QInternal::RightDock:
2654 return QRect(r.left() - sep, r.top(), sep, r.height());
2655 case QInternal::TopDock:
2656 return QRect(r.left(), r.bottom() + 1, r.width(), sep);
2657 case QInternal::BottomDock:
2658 return QRect(r.left(), r.top() - sep, r.width(), sep);
2665QRect QDockAreaLayout::separatorRect(
const QList<
int> &path)
const
2667 Q_ASSERT(!path.isEmpty());
2669 const int index = path.first();
2670 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2672 if (path.size() == 1)
2673 return separatorRect(index);
2675 return docks[index].separatorRect(path.mid(1));
2678bool QDockAreaLayout::insertGap(
const QList<
int> &path, QLayoutItem *dockWidgetItem)
2680 Q_ASSERT(!path.isEmpty());
2681 const int index = path.first();
2682 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2683 return docks[index].insertGap(path.mid(1), dockWidgetItem);
2686QLayoutItem *QDockAreaLayout::plug(
const QList<
int> &path)
2688#if QT_CONFIG(tabbar)
2689 Q_ASSERT(!path.isEmpty());
2690 const int index = path.first();
2691 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2692 QLayoutItem *item = docks[index].plug(path.mid(1));
2693 docks[index].reparentWidgets(mainWindow);
2700QLayoutItem *QDockAreaLayout::unplug(
const QList<
int> &path)
2702 Q_ASSERT(!path.isEmpty());
2703 const int index = path.first();
2704 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2705 return docks[index].unplug(path.mid(1));
2708void QDockAreaLayout::remove(
const QList<
int> &path)
2710 Q_ASSERT(!path.isEmpty());
2711 const int index = path.first();
2712 Q_ASSERT(index >= 0 && index < QInternal::DockCount);
2713 docks[index].remove(path.mid(1));
2716void QDockAreaLayout::removePlaceHolder(
const QString &name)
2718 QList<
int> index = indexOfPlaceHolder(name);
2719 if (!index.isEmpty())
2722 mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly);
2723 for (QDockWidgetGroupWindow *dwgw : groups) {
2724 index = dwgw->layoutInfo()->indexOfPlaceHolder(name);
2725 if (!index.isEmpty()) {
2726 dwgw->layoutInfo()->remove(index);
2727 dwgw->destroyOrHideIfEmpty();
2732static inline int qMax(
int i1,
int i2,
int i3) {
return qMax(i1, qMax(i2, i3)); }
2734void QDockAreaLayout::getGrid(QList<QLayoutStruct> *_ver_struct_list,
2735 QList<QLayoutStruct> *_hor_struct_list)
2737 QSize center_hint(0, 0);
2738 QSize center_min(0, 0);
2739 QSize center_max(0, 0);
2740 const bool have_central = centralWidgetItem !=
nullptr && !centralWidgetItem->isEmpty();
2742 center_hint = centralWidgetRect.size();
2743 if (!center_hint.isValid())
2744 center_hint = centralWidgetItem->sizeHint();
2745 center_min = centralWidgetItem->minimumSize();
2746 center_max = centralWidgetItem->maximumSize();
2749 QRect center_rect = rect;
2750 if (!docks[QInternal::LeftDock].isEmpty())
2751 center_rect.setLeft(rect.left() + docks[QInternal::LeftDock].rect.width() + sep);
2752 if (!docks[QInternal::TopDock].isEmpty())
2753 center_rect.setTop(rect.top() + docks[QInternal::TopDock].rect.height() + sep);
2754 if (!docks[QInternal::RightDock].isEmpty())
2755 center_rect.setRight(rect.right() - docks[QInternal::RightDock].rect.width() - sep);
2756 if (!docks[QInternal::BottomDock].isEmpty())
2757 center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep);
2759 QSize left_hint = docks[QInternal::LeftDock].size();
2760 if (left_hint.isNull() || fallbackToSizeHints)
2761 left_hint = docks[QInternal::LeftDock].sizeHint();
2762 QSize left_min = docks[QInternal::LeftDock].minimumSize();
2763 QSize left_max = docks[QInternal::LeftDock].maximumSize();
2764 left_hint = left_hint.boundedTo(left_max).expandedTo(left_min);
2766 QSize right_hint = docks[QInternal::RightDock].size();
2767 if (right_hint.isNull() || fallbackToSizeHints)
2768 right_hint = docks[QInternal::RightDock].sizeHint();
2769 QSize right_min = docks[QInternal::RightDock].minimumSize();
2770 QSize right_max = docks[QInternal::RightDock].maximumSize();
2771 right_hint = right_hint.boundedTo(right_max).expandedTo(right_min);
2773 QSize top_hint = docks[QInternal::TopDock].size();
2774 if (top_hint.isNull() || fallbackToSizeHints)
2775 top_hint = docks[QInternal::TopDock].sizeHint();
2776 QSize top_min = docks[QInternal::TopDock].minimumSize();
2777 QSize top_max = docks[QInternal::TopDock].maximumSize();
2778 top_hint = top_hint.boundedTo(top_max).expandedTo(top_min);
2780 QSize bottom_hint = docks[QInternal::BottomDock].size();
2781 if (bottom_hint.isNull() || fallbackToSizeHints)
2782 bottom_hint = docks[QInternal::BottomDock].sizeHint();
2783 QSize bottom_min = docks[QInternal::BottomDock].minimumSize();
2784 QSize bottom_max = docks[QInternal::BottomDock].maximumSize();
2785 bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min);
2787 if (_ver_struct_list !=
nullptr) {
2788 QList<QLayoutStruct> &ver_struct_list = *_ver_struct_list;
2789 ver_struct_list.resize(3);
2792 ver_struct_list[0].init();
2793 ver_struct_list[0].stretch = 0;
2794 ver_struct_list[0].sizeHint = top_hint.height();
2795 ver_struct_list[0].minimumSize = top_min.height();
2796 ver_struct_list[0].maximumSize = top_max.height();
2797 ver_struct_list[0].expansive =
false;
2798 ver_struct_list[0].empty = docks[QInternal::TopDock].isEmpty();
2799 ver_struct_list[0].pos = docks[QInternal::TopDock].rect.top();
2800 ver_struct_list[0].size = docks[QInternal::TopDock].rect.height();
2803 ver_struct_list[1].init();
2804 ver_struct_list[1].stretch = center_hint.height();
2806 bool tl_significant = corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
2807 || docks[QInternal::TopDock].isEmpty();
2808 bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
2809 || docks[QInternal::BottomDock].isEmpty();
2810 bool tr_significant = corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
2811 || docks[QInternal::TopDock].isEmpty();
2812 bool br_significant = corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
2813 || docks[QInternal::BottomDock].isEmpty();
2815 int left = (tl_significant && bl_significant) ? left_hint.height() : 0;
2816 int right = (tr_significant && br_significant) ? right_hint.height() : 0;
2817 ver_struct_list[1].sizeHint = qMax(left, center_hint.height(), right);
2819 left = (tl_significant && bl_significant) ? left_min.height() : 0;
2820 right = (tr_significant && br_significant) ? right_min.height() : 0;
2821 ver_struct_list[1].minimumSize = qMax(left, center_min.height(), right);
2822 ver_struct_list[1].maximumSize = center_max.height();
2823 ver_struct_list[1].expansive = have_central;
2824 ver_struct_list[1].empty = docks[QInternal::LeftDock].isEmpty()
2826 && docks[QInternal::RightDock].isEmpty();
2827 ver_struct_list[1].pos = center_rect.top();
2828 ver_struct_list[1].size = center_rect.height();
2831 ver_struct_list[2].init();
2832 ver_struct_list[2].stretch = 0;
2833 ver_struct_list[2].sizeHint = bottom_hint.height();
2834 ver_struct_list[2].minimumSize = bottom_min.height();
2835 ver_struct_list[2].maximumSize = bottom_max.height();
2836 ver_struct_list[2].expansive =
false;
2837 ver_struct_list[2].empty = docks[QInternal::BottomDock].isEmpty();
2838 ver_struct_list[2].pos = docks[QInternal::BottomDock].rect.top();
2839 ver_struct_list[2].size = docks[QInternal::BottomDock].rect.height();
2841 for (
int i = 0; i < 3; ++i) {
2842 ver_struct_list[i].sizeHint
2843 = qMax(ver_struct_list[i].sizeHint, ver_struct_list[i].minimumSize);
2845 if (have_central && ver_struct_list[0].empty && ver_struct_list[2].empty)
2846 ver_struct_list[1].maximumSize = QWIDGETSIZE_MAX;
2849 if (_hor_struct_list !=
nullptr) {
2850 QList<QLayoutStruct> &hor_struct_list = *_hor_struct_list;
2851 hor_struct_list.resize(3);
2854 hor_struct_list[0].init();
2855 hor_struct_list[0].stretch = 0;
2856 hor_struct_list[0].sizeHint = left_hint.width();
2857 hor_struct_list[0].minimumSize = left_min.width();
2858 hor_struct_list[0].maximumSize = left_max.width();
2859 hor_struct_list[0].expansive =
false;
2860 hor_struct_list[0].empty = docks[QInternal::LeftDock].isEmpty();
2861 hor_struct_list[0].pos = docks[QInternal::LeftDock].rect.left();
2862 hor_struct_list[0].size = docks[QInternal::LeftDock].rect.width();
2865 hor_struct_list[1].init();
2866 hor_struct_list[1].stretch = center_hint.width();
2868 bool tl_significant = corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
2869 || docks[QInternal::LeftDock].isEmpty();
2870 bool tr_significant = corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
2871 || docks[QInternal::RightDock].isEmpty();
2872 bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
2873 || docks[QInternal::LeftDock].isEmpty();
2874 bool br_significant = corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
2875 || docks[QInternal::RightDock].isEmpty();
2877 int top = (tl_significant && tr_significant) ? top_hint.width() : 0;
2878 int bottom = (bl_significant && br_significant) ? bottom_hint.width() : 0;
2879 hor_struct_list[1].sizeHint = qMax(top, center_hint.width(), bottom);
2881 top = (tl_significant && tr_significant) ? top_min.width() : 0;
2882 bottom = (bl_significant && br_significant) ? bottom_min.width() : 0;
2883 hor_struct_list[1].minimumSize = qMax(top, center_min.width(), bottom);
2885 hor_struct_list[1].maximumSize = center_max.width();
2886 hor_struct_list[1].expansive = have_central;
2887 hor_struct_list[1].empty = !have_central;
2888 hor_struct_list[1].pos = center_rect.left();
2889 hor_struct_list[1].size = center_rect.width();
2892 hor_struct_list[2].init();
2893 hor_struct_list[2].stretch = 0;
2894 hor_struct_list[2].sizeHint = right_hint.width();
2895 hor_struct_list[2].minimumSize = right_min.width();
2896 hor_struct_list[2].maximumSize = right_max.width();
2897 hor_struct_list[2].expansive =
false;
2898 hor_struct_list[2].empty = docks[QInternal::RightDock].isEmpty();
2899 hor_struct_list[2].pos = docks[QInternal::RightDock].rect.left();
2900 hor_struct_list[2].size = docks[QInternal::RightDock].rect.width();
2902 for (
int i = 0; i < 3; ++i) {
2903 hor_struct_list[i].sizeHint
2904 = qMax(hor_struct_list[i].sizeHint, hor_struct_list[i].minimumSize);
2906 if (have_central && hor_struct_list[0].empty && hor_struct_list[2].empty)
2907 hor_struct_list[1].maximumSize = QWIDGETSIZE_MAX;
2912void QDockAreaLayout::setGrid(QList<QLayoutStruct> *ver_struct_list,
2913 QList<QLayoutStruct> *hor_struct_list)
2918 if (!docks[QInternal::TopDock].isEmpty()) {
2919 QRect r = docks[QInternal::TopDock].rect;
2920 if (hor_struct_list !=
nullptr) {
2921 r.setLeft(corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
2922 || docks[QInternal::LeftDock].isEmpty()
2923 ? rect.left() : hor_struct_list->at(1).pos);
2924 r.setRight(corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
2925 || docks[QInternal::RightDock].isEmpty()
2926 ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
2928 if (ver_struct_list !=
nullptr) {
2929 r.setTop(rect.top());
2930 r.setBottom(ver_struct_list->at(1).pos - sep - 1);
2932 docks[QInternal::TopDock].rect = r;
2933 docks[QInternal::TopDock].fitItems();
2938 if (!docks[QInternal::BottomDock].isEmpty()) {
2939 QRect r = docks[QInternal::BottomDock].rect;
2940 if (hor_struct_list !=
nullptr) {
2941 r.setLeft(corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
2942 || docks[QInternal::LeftDock].isEmpty()
2943 ? rect.left() : hor_struct_list->at(1).pos);
2944 r.setRight(corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
2945 || docks[QInternal::RightDock].isEmpty()
2946 ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
2948 if (ver_struct_list !=
nullptr) {
2949 r.setTop(ver_struct_list->at(2).pos);
2950 r.setBottom(rect.bottom());
2952 docks[QInternal::BottomDock].rect = r;
2953 docks[QInternal::BottomDock].fitItems();
2958 if (!docks[QInternal::LeftDock].isEmpty()) {
2959 QRect r = docks[QInternal::LeftDock].rect;
2960 if (hor_struct_list !=
nullptr) {
2961 r.setLeft(rect.left());
2962 r.setRight(hor_struct_list->at(1).pos - sep - 1);
2964 if (ver_struct_list !=
nullptr) {
2965 r.setTop(corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
2966 || docks[QInternal::TopDock].isEmpty()
2967 ? rect.top() : ver_struct_list->at(1).pos);
2968 r.setBottom(corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
2969 || docks[QInternal::BottomDock].isEmpty()
2970 ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
2972 docks[QInternal::LeftDock].rect = r;
2973 docks[QInternal::LeftDock].fitItems();
2978 if (!docks[QInternal::RightDock].isEmpty()) {
2979 QRect r = docks[QInternal::RightDock].rect;
2980 if (hor_struct_list !=
nullptr) {
2981 r.setLeft(hor_struct_list->at(2).pos);
2982 r.setRight(rect.right());
2984 if (ver_struct_list !=
nullptr) {
2985 r.setTop(corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
2986 || docks[QInternal::TopDock].isEmpty()
2987 ? rect.top() : ver_struct_list->at(1).pos);
2988 r.setBottom(corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
2989 || docks[QInternal::BottomDock].isEmpty()
2990 ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
2992 docks[QInternal::RightDock].rect = r;
2993 docks[QInternal::RightDock].fitItems();
2998 if (hor_struct_list !=
nullptr) {
2999 centralWidgetRect.setLeft(hor_struct_list->at(1).pos);
3000 centralWidgetRect.setWidth(hor_struct_list->at(1).size);
3002 if (ver_struct_list !=
nullptr) {
3003 centralWidgetRect.setTop(ver_struct_list->at(1).pos);
3004 centralWidgetRect.setHeight(ver_struct_list->at(1).size);
3008void QDockAreaLayout::fitLayout()
3010 QList<QLayoutStruct> ver_struct_list(3);
3011 QList<QLayoutStruct> hor_struct_list(3);
3012 getGrid(&ver_struct_list, &hor_struct_list);
3014 qGeomCalc(ver_struct_list, 0, 3, rect.top(), rect.height(), sep);
3015 qGeomCalc(hor_struct_list, 0, 3, rect.left(), rect.width(), sep);
3017 setGrid(&ver_struct_list, &hor_struct_list);
3020void QDockAreaLayout::clear()
3022 for (
int i = 0; i < QInternal::DockCount; ++i)
3026 centralWidgetRect = QRect();
3029template<
typename SizePMF,
typename CenterPMF>
3030QSize QDockAreaLayout::size_helper(SizePMF sizeFn, CenterPMF centerFn)
const
3037 if (centralWidgetItem !=
nullptr) {
3038 left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep;
3039 right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep;
3040 top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep;
3041 bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
3044 const QSize left = (docks[QInternal::LeftDock].*sizeFn)() + QSize(left_sep, 0);
3045 const QSize right = (docks[QInternal::RightDock].*sizeFn)() + QSize(right_sep, 0);
3046 const QSize top = (docks[QInternal::TopDock].*sizeFn)() + QSize(0, top_sep);
3047 const QSize bottom = (docks[QInternal::BottomDock].*sizeFn)() + QSize(0, bottom_sep);
3048 const QSize center = centralWidgetItem ==
nullptr
3049 ? QSize(0, 0) : (centralWidgetItem->*centerFn)();
3051 int row1 = top.width();
3052 int row2 = left.width() + center.width() + right.width();
3053 int row3 = bottom.width();
3054 int col1 = left.height();
3055 int col2 = top.height() + center.height() + bottom.height();
3056 int col3 = right.height();
3058 if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea)
3059 row1 += left.width();
3061 col1 += top.height();
3063 if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea)
3064 row1 += right.width();
3066 col3 += top.height();
3068 if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea)
3069 row3 += left.width();
3071 col1 += bottom.height();
3073 if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea)
3074 row3 += right.width();
3076 col3 += bottom.height();
3078 return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
3081QSize QDockAreaLayout::sizeHint()
const
3083 return size_helper(&QDockAreaLayoutInfo::sizeHint, &QLayoutItem::sizeHint);
3086QSize QDockAreaLayout::minimumSize()
const
3088 return size_helper(&QDockAreaLayoutInfo::minimumSize, &QLayoutItem::minimumSize);
3092
3093
3094
3095
3096QSize QDockAreaLayout::minimumStableSize()
const
3098 return size_helper(&QDockAreaLayoutInfo::size, &QLayoutItem::minimumSize);
3102
3103
3104
3105
3106
3107QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget)
3109 QScreen *screen =
nullptr;
3110 if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1)
3111 screen = QGuiApplication::screenAt(rect.topLeft());
3113 screen = widget->screen();
3115 const QRect screenRect = screen->geometry();
3116 if (screenRect.isValid()) {
3117 rect.setWidth(qMin(rect.width(), screenRect.width()));
3118 rect.setHeight(qMin(rect.height(), screenRect.height()));
3119 rect.moveLeft(qMax(rect.left(), screenRect.left()));
3120 rect.moveTop(qMax(rect.top(), screenRect.top()));
3121 rect.moveRight(qMin(rect.right(), screenRect.right()));
3122 rect.moveBottom(qMin(rect.bottom(), screenRect.bottom()));
3128bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
3130 QDockAreaLayoutItem *item =
nullptr;
3132 mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly);
3133 for (QDockWidgetGroupWindow *dwgw : groups) {
3134 QList<
int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName());
3135 if (!index.isEmpty()) {
3136 dockWidget->setParent(dwgw);
3137 item =
const_cast<QDockAreaLayoutItem *>(&dwgw->layoutInfo()->item(index));
3142 QList<
int> index = indexOfPlaceHolder(dockWidget->objectName());
3143 if (index.isEmpty())
3145 item =
const_cast<QDockAreaLayoutItem *>(&
this->item(index));
3148 QPlaceHolderItem *placeHolder = item->placeHolderItem;
3149 Q_ASSERT(placeHolder !=
nullptr);
3151 item->widgetItem =
new QDockWidgetItem(dockWidget);
3153 if (placeHolder->window) {
3154 const QRect r = constrainedRect(placeHolder->topLevelRect, dockWidget);
3155 dockWidget->d_func()->setWindowState(QDockWidgetPrivate::WindowStates(
3156 {QDockWidgetPrivate::WindowState::Floating,
3157 QDockWidgetPrivate::WindowState::Unplug}), r);
3159 dockWidget->setVisible(!placeHolder->hidden);
3161 item->placeHolderItem =
nullptr;
3167void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget,
3168 Qt::Orientation orientation)
3170 QLayoutItem *dockWidgetItem =
new QDockWidgetItem(dockWidget);
3171 QDockAreaLayoutInfo &info = docks[pos];
3172 if (orientation == info.o || info.item_list.size() <= 1) {
3175 info.o = orientation;
3177 QDockAreaLayoutItem new_item(dockWidgetItem);
3178 info.item_list.append(new_item);
3179#if QT_CONFIG(tabbar)
3180 if (info.tabbed && !new_item.skip()) {
3181 info.updateTabBar();
3182 info.setCurrentTabId(tabId(new_item));
3186#if QT_CONFIG(tabbar)
3187 int tbshape = info.tabBarShape;
3191 QDockAreaLayoutInfo new_info(&sep, pos, orientation, tbshape, mainWindow);
3192 new_info.item_list.append(QDockAreaLayoutItem(
new QDockAreaLayoutInfo(info)));
3193 new_info.item_list.append(QDockAreaLayoutItem(dockWidgetItem));
3197 removePlaceHolder(dockWidget->objectName());
3200#if QT_CONFIG(tabbar)
3201void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
3203 const QList<
int> path = indexOf(first);
3207 QDockAreaLayoutInfo *info =
this->info(path);
3208 Q_ASSERT(info !=
nullptr);
3209 info->tab(path.last(),
new QDockWidgetItem(second));
3211 removePlaceHolder(second->objectName());
3215void QDockAreaLayout::resizeDocks(
const QList<QDockWidget *> &docks,
3216 const QList<
int> &sizes, Qt::Orientation o)
3218 if (Q_UNLIKELY(docks.size() != sizes.size())) {
3219 qWarning(
"QMainWidget::resizeDocks: size of the lists are not the same");
3222 int count = docks.size();
3223 fallbackToSizeHints =
false;
3224 for (
int i = 0; i < count; ++i) {
3225 QList<
int> path = indexOf(docks[i]);
3226 if (Q_UNLIKELY(path.isEmpty())) {
3227 qWarning(
"QMainWidget::resizeDocks: one QDockWidget is not part of the layout");
3230 int size = sizes[i];
3231 if (Q_UNLIKELY(size <= 0)) {
3232 qWarning(
"QMainWidget::resizeDocks: all sizes need to be larger than 0");
3236 while (path.size() > 1) {
3237 QDockAreaLayoutInfo *info =
this->info(path);
3238#if QT_CONFIG(tabbar)
3239 if (!info->tabbed && info->o == o) {
3240 info->item_list[path.constLast()].size = size;
3242 for (
const QDockAreaLayoutItem &item : std::as_const(info->item_list)) {
3246 totalSize += item.size == -1 ? pick(o, item.sizeHint()) : item.size;
3255 const int dockNum = path.constFirst();
3256 Q_ASSERT(dockNum < QInternal::DockCount);
3257 QRect &r =
this->docks[dockNum].rect;
3264void QDockAreaLayout::splitDockWidget(QDockWidget *after,
3265 QDockWidget *dockWidget,
3266 Qt::Orientation orientation)
3268 const QList<
int> path = indexOf(after);
3272 QDockAreaLayoutInfo *info =
this->info(path);
3273 Q_ASSERT(info !=
nullptr);
3274 info->split(path.last(), orientation,
new QDockWidgetItem(dockWidget));
3276 removePlaceHolder(dockWidget->objectName());
3279void QDockAreaLayout::apply(
bool animate)
3281 QWidgetAnimator &widgetAnimator = qt_mainwindow_layout(mainWindow)->widgetAnimator;
3283 for (
int i = 0; i < QInternal::DockCount; ++i)
3284 docks[i].apply(animate);
3285 if (centralWidgetItem !=
nullptr && !centralWidgetItem->isEmpty()) {
3286 widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect,
3289#if QT_CONFIG(tabbar)
3291 updateSeparatorWidgets();
3295void QDockAreaLayout::paintSeparators(QPainter *p, QWidget *widget,
3296 const QRegion &clip,
3297 const QPoint &mouse)
const
3299 for (
int i = 0; i < QInternal::DockCount; ++i) {
3300 const QDockAreaLayoutInfo &dock = docks[i];
3303 QRect r = separatorRect(i);
3304 if (clip.contains(r) && !dock.hasFixedSize()) {
3305 Qt::Orientation opposite = dock.o == Qt::Horizontal
3306 ? Qt::Vertical : Qt::Horizontal;
3307 paintSep(p, widget, r, opposite, r.contains(mouse));
3309 if (clip.contains(dock.rect))
3310 dock.paintSeparators(p, widget, clip, mouse);
3314QRegion QDockAreaLayout::separatorRegion()
const
3318 for (
int i = 0; i < QInternal::DockCount; ++i) {
3319 const QDockAreaLayoutInfo &dock = docks[i];
3322 result |= separatorRect(i);
3323 result |= dock.separatorRegion();
3329int QDockAreaLayout::separatorMove(
const QList<
int> &separator,
const QPoint &origin,
3333 const auto dockPosition =
static_cast<QInternal::DockPosition>(separator.last());
3334 const bool isHorizontal =
3335 dockPosition == QInternal::LeftDock || dockPosition == QInternal::RightDock;
3336 const bool isLeftOrTop = dockPosition == QInternal::LeftDock || dockPosition == QInternal::TopDock;
3337 const bool separatorIsWithinDock = separator.size() > 1;
3339 if (separatorIsWithinDock) {
3343 QDockAreaLayoutInfo *info =
this->info(separator);
3344 delta = pick(info->o, dest - origin);
3346 delta = info->separatorMove(dockPosition, delta);
3347 info->apply(
false);
3357 QList<QLayoutStruct> list;
3360 getGrid(
nullptr, &list);
3362 getGrid(&list,
nullptr);
3364 const int sep_index = isLeftOrTop ? 0 : 1;
3365 const Qt::Orientation o = isHorizontal ? Qt::Horizontal : Qt::Vertical;
3367 delta = pick(o, dest - origin);
3368 delta = separatorMoveHelper(list, sep_index, delta, sep);
3370 fallbackToSizeHints =
false;
3373 setGrid(
nullptr, &list);
3375 setGrid(&list,
nullptr);
3382int QDockAreaLayoutInfo::separatorMove(
const QList<
int> &separator,
const QPoint &origin,
3386 int index = separator.last();
3387 QDockAreaLayoutInfo *info =
this->info(separator);
3388 delta = pick(info->o, dest - origin);
3390 delta = info->separatorMove(index, delta);
3391 info->apply(
false);
3395#if QT_CONFIG(tabbar)
3398void QDockAreaLayout::updateSeparatorWidgets()
const
3402 for (
int i = 0; i < QInternal::DockCount; ++i) {
3403 const QDockAreaLayoutInfo &dock = docks[i];
3408 if (j < separatorWidgets.size()) {
3409 sepWidget = separatorWidgets.at(j);
3411 qWarning(
"QDockAreaLayout::updateSeparatorWidgets: null separator widget");
3412 sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
3413 separatorWidgets[j] = sepWidget;
3416 sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
3417 separatorWidgets.append(sepWidget);
3421 Q_ASSERT(sepWidget);
3422 raiseSeparatorWidget(sepWidget);
3424 QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
3425 sepWidget->setGeometry(sepRect);
3426 sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
3429 for (
int i = j; i < separatorWidgets.size(); ++i)
3430 separatorWidgets.at(i)->hide();
3432 separatorWidgets.resize(j);
3436QLayoutItem *QDockAreaLayout::itemAt(
int *x,
int index)
const
3438 Q_ASSERT(x !=
nullptr);
3440 for (
int i = 0; i < QInternal::DockCount; ++i) {
3441 const QDockAreaLayoutInfo &dock = docks[i];
3442 if (QLayoutItem *ret = dock.itemAt(x, index))
3446 if (centralWidgetItem && (*x)++ == index)
3447 return centralWidgetItem;
3452QLayoutItem *QDockAreaLayout::takeAt(
int *x,
int index)
3454 Q_ASSERT(x !=
nullptr);
3456 for (
int i = 0; i < QInternal::DockCount; ++i) {
3457 QDockAreaLayoutInfo &dock = docks[i];
3458 if (QLayoutItem *ret = dock.takeAt(x, index))
3462 if (centralWidgetItem && (*x)++ == index) {
3463 QLayoutItem *ret = centralWidgetItem;
3464 centralWidgetItem =
nullptr;
3471void QDockAreaLayout::deleteAllLayoutItems()
3473 for (
int i = 0; i < QInternal::DockCount; ++i)
3474 docks[i].deleteAllLayoutItems();
3477#if QT_CONFIG(tabbar)
3478QSet<QTabBar*> QDockAreaLayout::usedTabBars()
const
3480 QSet<QTabBar*> result;
3481 for (
int i = 0; i < QInternal::DockCount; ++i) {
3482 const QDockAreaLayoutInfo &dock = docks[i];
3483 result += dock.usedTabBars();
3489QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets()
const
3491 QSet<QWidget*> result;
3492 const int numSeparators = separatorWidgets.size();
3493 result.reserve(numSeparators);
3494 for (
int i = 0; i < numSeparators; ++i)
3495 result << separatorWidgets.at(i);
3496 for (
int i = 0; i < QInternal::DockCount; ++i) {
3497 const QDockAreaLayoutInfo &dock = docks[i];
3498 result += dock.usedSeparatorWidgets();
3504QRect QDockAreaLayout::gapRect(
const QList<
int> &path)
const
3506 const QDockAreaLayoutInfo *info =
this->info(path);
3507 if (info ==
nullptr)
3509 int index = path.last();
3510 if (index < 0 || index >= info->item_list.size())
3512 return info->itemRect(index,
true);
3515void QDockAreaLayout::keepSize(QDockWidget *w)
3517 QList<
int> path = indexOf(w);
3520 QDockAreaLayoutItem &item =
this->item(path);
3521 if (item.size != -1)
3522 item.flags |= QDockAreaLayoutItem::KeepSize;
3525void QDockAreaLayout::styleChangedEvent()
3527 sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent,
nullptr, mainWindow);
Combined button and popup list for selecting options.
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)