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