1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QDOCKAREALAYOUT_P_H
5#define QDOCKAREALAYOUT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtWidgets/private/qtwidgetsglobal_p.h>
19#include "QtWidgets/qlayout.h"
20#include "QtCore/qlist.h"
21#include "QtCore/qpair.h"
22#include "QtCore/qrect.h"
23
24QT_REQUIRE_CONFIG(dockwidget);
25
26QT_BEGIN_NAMESPACE
27
28class QLayoutItem;
29class QWidget;
30class QLayoutItem;
31class QDockAreaLayoutInfo;
32class QPlaceHolderItem;
33class QDockWidget;
34class QMainWindow;
35class QWidgetAnimator;
36class QMainWindowLayout;
37struct QLayoutStruct;
38class QTabBar;
39
40// The classes in this file represent the tree structure that represents all the docks
41// Also see the wiki internal documentation
42// At the root of the tree is: QDockAreaLayout, which handles all 4 sides, so there is only one.
43// For each side it has one QDockAreaLayoutInfo child. (See QDockAreaLayout::docks.)
44// The QDockAreaLayoutInfo have QDockAreaLayoutItems as children (See QDockAreaLayoutInfo::item_list),
45// which then has one QDockAreaLayoutInfo as a child. (QDockAreaLayoutItem::subInfo) or
46// a widgetItem if this is a node of the tree (QDockAreaLayoutItem::widgetItem)
47//
48// A path indetifies uniquely one object in this tree, the first number being the side and all the following
49// indexes into the QDockAreaLayoutInfo::item_list.
50
51struct Q_AUTOTEST_EXPORT QDockAreaLayoutItem
52{
53 enum ItemFlags { NoFlags = 0, GapItem = 1, KeepSize = 2 };
54
55 explicit QDockAreaLayoutItem(QLayoutItem *_widgetItem = nullptr);
56 explicit QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo);
57 explicit QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem);
58 QDockAreaLayoutItem(const QDockAreaLayoutItem &other);
59 ~QDockAreaLayoutItem();
60
61 QDockAreaLayoutItem &operator = (const QDockAreaLayoutItem &other);
62
63 bool skip() const;
64 QSize minimumSize() const;
65 QSize maximumSize() const;
66 QSize sizeHint() const;
67 bool expansive(Qt::Orientation o) const;
68 bool hasFixedSize(Qt::Orientation o) const;
69
70 QLayoutItem *widgetItem;
71 QDockAreaLayoutInfo *subinfo;
72 QPlaceHolderItem *placeHolderItem;
73 int pos;
74 int size;
75 uint flags;
76#ifndef QT_NO_DEBUG_STREAM
77 friend Q_AUTOTEST_EXPORT QDebug operator<<(QDebug dbg, const QDockAreaLayoutItem &item);
78#endif
79};
80
81class Q_AUTOTEST_EXPORT QPlaceHolderItem
82{
83public:
84 QPlaceHolderItem() : hidden(false), window(false) {}
85 explicit QPlaceHolderItem(QWidget *w);
86
87 QString objectName;
88 bool hidden, window;
89 QRect topLevelRect;
90};
91
92class Q_AUTOTEST_EXPORT QDockAreaLayoutInfo
93{
94public:
95 QDockAreaLayoutInfo();
96 QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos, Qt::Orientation _o,
97 int tbhape, QMainWindow *window);
98
99 QSize minimumSize() const;
100 QSize maximumSize() const;
101 QSize sizeHint() const;
102 QSize size() const;
103
104 bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
105 QLayoutItem *plug(const QList<int> &path);
106 QLayoutItem *unplug(const QList<int> &path);
107 enum TabMode { NoTabs, AllowTabs, ForceTabs };
108 QList<int> gapIndex(const QPoint &pos, bool nestingEnabled,
109 TabMode tabMode) const;
110 void remove(const QList<int> &path);
111 void unnest(int index);
112 void split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem);
113#if QT_CONFIG(tabbar)
114 void tab(int index, QLayoutItem *dockWidgetItem);
115#endif
116 QDockAreaLayoutItem &item(const QList<int> &path);
117 QDockAreaLayoutInfo *info(const QList<int> &path);
118 QDockAreaLayoutInfo *info(QWidget *widget);
119
120 enum { // sentinel values used to validate state data
121 SequenceMarker = 0xfc,
122 TabMarker = 0xfa,
123 WidgetMarker = 0xfb
124 };
125 void saveState(QDataStream &stream) const;
126 bool restoreState(QDataStream &stream, QList<QDockWidget*> &widgets, bool testing);
127
128 void fitItems();
129 bool expansive(Qt::Orientation o) const;
130 int changeSize(int index, int size, bool below);
131 QRect itemRect(int index, bool isGap = false) const;
132 QRect itemRect(const QList<int> &path) const;
133 QRect separatorRect(int index) const;
134 QRect separatorRect(const QList<int> &path) const;
135
136 void clear();
137 bool isEmpty() const;
138 bool hasGapItem(const QList<int> &path) const;
139 bool onlyHasPlaceholders() const;
140 bool hasFixedSize() const;
141 QList<int> findSeparator(const QPoint &pos) const;
142 int next(int idx) const;
143 int prev(int idx) const;
144
145 QList<int> indexOf(QWidget *widget) const;
146 QList<int> indexOfPlaceHolder(const QString &objectName) const;
147
148 QDockWidget *apply(bool animate);
149
150 void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
151 const QPoint &mouse) const;
152 QRegion separatorRegion() const;
153 int separatorMove(int index, int delta);
154 int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
155
156 QLayoutItem *itemAt(int *x, int index) const;
157 QLayoutItem *takeAt(int *x, int index);
158 void deleteAllLayoutItems();
159
160 QMainWindowLayout *mainWindowLayout() const;
161
162 const int *sep;
163 mutable QList<QWidget *> separatorWidgets;
164 QInternal::DockPosition dockPos;
165 Qt::Orientation o;
166 QRect rect;
167 QMainWindow *mainWindow;
168 QList<QDockAreaLayoutItem> item_list;
169#if QT_CONFIG(tabbar)
170 void updateSeparatorWidgets() const;
171 QSet<QWidget*> usedSeparatorWidgets() const;
172
173 quintptr currentTabId() const;
174 void setCurrentTab(QWidget *widget);
175 void setCurrentTabId(quintptr id);
176 QRect tabContentRect() const;
177 bool tabbed;
178 QTabBar *tabBar;
179 int tabBarShape;
180
181 void reparentWidgets(QWidget *p);
182 bool updateTabBar() const;
183 void setTabBarShape(int shape);
184 QSize tabBarMinimumSize() const;
185 QSize tabBarSizeHint() const;
186
187 QSet<QTabBar*> usedTabBars() const;
188
189 int tabIndexToListIndex(int) const;
190 void moveTab(int from, int to);
191#endif // QT_CONFIG(tabbar)
192};
193
194class Q_AUTOTEST_EXPORT QDockAreaLayout
195{
196public:
197 enum { EmptyDropAreaSize = 80 }; // when a dock area is empty, how "wide" is it?
198
199 Qt::DockWidgetArea corners[4]; // use a Qt::Corner for indexing
200 QRect rect;
201 QLayoutItem *centralWidgetItem;
202 QMainWindow *mainWindow;
203 QRect centralWidgetRect;
204 QDockAreaLayout(QMainWindow *win);
205 QDockAreaLayoutInfo docks[4];
206 int sep; // margin between a dock widget and its frame
207 bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the separator is moved by user)
208 mutable QList<QWidget *> separatorWidgets;
209
210 bool isValid() const;
211
212 enum { DockWidgetStateMarker = 0xfd, FloatingDockWidgetTabMarker = 0xf9 };
213 static QRect constrainedRect(QRect rect, QWidget *widget);
214 void saveState(QDataStream &stream) const;
215 bool restoreState(QDataStream &stream, const QList<QDockWidget*> &widgets, bool testing = false);
216
217 QList<int> indexOfPlaceHolder(const QString &objectName) const;
218 QList<int> indexOf(QWidget *dockWidget) const;
219 QList<int> gapIndex(const QPoint &pos, bool disallowTabs) const;
220 QList<int> findSeparator(const QPoint &pos) const;
221
222 QDockAreaLayoutItem &item(const QList<int> &path);
223 QDockAreaLayoutInfo *info(const QList<int> &path);
224 const QDockAreaLayoutInfo *info(const QList<int> &path) const;
225 QDockAreaLayoutInfo *info(QWidget *widget);
226 QRect itemRect(const QList<int> &path) const;
227 QRect separatorRect(int index) const;
228 QRect separatorRect(const QList<int> &path) const;
229
230 bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
231 QLayoutItem *plug(const QList<int> &path);
232 QLayoutItem *unplug(const QList<int> &path);
233 void remove(const QList<int> &path);
234 void removePlaceHolder(const QString &name);
235
236 void fitLayout();
237
238 void clear();
239
240 QSize sizeHint() const;
241 QSize minimumSize() const;
242 QSize minimumStableSize() const;
243 template<typename SizePMF, typename CenterPMF>
244 QSize size_helper(SizePMF sizeFn, CenterPMF centerFn) const;
245
246 void addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget, Qt::Orientation orientation);
247 bool restoreDockWidget(QDockWidget *dockWidget);
248 void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget,
249 Qt::Orientation orientation);
250#if QT_CONFIG(tabbar)
251 void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
252#endif
253 void resizeDocks(const QList<QDockWidget *> &docks, const QList<int> &sizes, Qt::Orientation o);
254
255 void apply(bool animate);
256
257 void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
258 const QPoint &mouse) const;
259 QRegion separatorRegion() const;
260 int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
261#if QT_CONFIG(tabbar)
262 void updateSeparatorWidgets() const;
263#endif // QT_CONFIG(tabbar)
264
265 QLayoutItem *itemAt(int *x, int index) const;
266 QLayoutItem *takeAt(int *x, int index);
267 void deleteAllLayoutItems();
268
269 void getGrid(QList<QLayoutStruct> *ver_struct_list, QList<QLayoutStruct> *hor_struct_list);
270 void setGrid(QList<QLayoutStruct> *ver_struct_list, QList<QLayoutStruct> *hor_struct_list);
271
272 QRect gapRect(const QList<int> &path) const;
273 QRect gapRect(QInternal::DockPosition dockPos) const;
274
275 void keepSize(QDockWidget *w);
276#if QT_CONFIG(tabbar)
277 QSet<QTabBar*> usedTabBars() const;
278 QSet<QWidget*> usedSeparatorWidgets() const;
279#endif // QT_CONFIG(tabbar)
280 void styleChangedEvent();
281};
282
283QT_END_NAMESPACE
284
285#endif // QDOCKAREALAYOUT_P_H
286

source code of qtbase/src/widgets/widgets/qdockarealayout_p.h