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: QPlaceHolderItem()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