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 QMDIAREA_P_H
5#define QMDIAREA_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 "qmdiarea.h"
20#include "qmdisubwindow.h"
21
22QT_REQUIRE_CONFIG(mdiarea);
23
24#include <QBasicTimer>
25#include <QList>
26#include <QRect>
27#include <QPoint>
28#include <QtWidgets/qapplication.h>
29#include <private/qmdisubwindow_p.h>
30#include <private/qabstractscrollarea_p.h>
31
32#include <QtCore/qpointer.h>
33
34QT_BEGIN_NAMESPACE
35
36namespace QMdi {
37class Rearranger
38{
39public:
40 enum Type {
41 RegularTiler,
42 SimpleCascader,
43 IconTiler
44 };
45
46 // Rearranges widgets relative to domain.
47 virtual void rearrange(QList<QWidget *> &widgets, const QRect &domain) const = 0;
48 virtual Type type() const = 0;
49 virtual ~Rearranger() {}
50};
51
52class RegularTiler : public Rearranger
53{
54 // Rearranges widgets according to a regular tiling pattern
55 // covering the entire domain.
56 // Both positions and sizes may change.
57 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
58 Type type() const override { return Rearranger::RegularTiler; }
59};
60
61class SimpleCascader : public Rearranger
62{
63 // Rearranges widgets according to a simple, regular cascading pattern.
64 // Widgets are resized to minimumSize.
65 // Both positions and sizes may change.
66 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
67 Type type() const override { return Rearranger::SimpleCascader; }
68};
69
70class IconTiler : public Rearranger
71{
72 // Rearranges icons (assumed to be the same size) according to a regular
73 // tiling pattern filling up the domain from the bottom.
74 // Only positions may change.
75 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override;
76 Type type() const override { return Rearranger::IconTiler; }
77};
78
79class Placer
80{
81public:
82 // Places the rectangle defined by 'size' relative to 'rects' and 'domain'.
83 // Returns the position of the resulting rectangle.
84 virtual QPoint place(const QSize &size, const QList<QRect> &rects,
85 const QRect &domain) const = 0;
86 virtual ~Placer() {}
87};
88
89class MinOverlapPlacer : public Placer
90{
91 QPoint place(const QSize &size, const QList<QRect> &rects, const QRect &domain) const override;
92 static int accumulatedOverlap(const QRect &source, const QList<QRect> &rects);
93 static QRect findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects);
94 static QList<QRect> getCandidatePlacements(const QSize &size, const QList<QRect> &rects,
95 const QRect &domain);
96 static QPoint findBestPlacement(const QRect &domain, const QList<QRect> &rects,
97 QList<QRect> &source);
98 static QList<QRect> findNonInsiders(const QRect &domain, QList<QRect> &source);
99 static QList<QRect> findMaxOverlappers(const QRect &domain, const QList<QRect> &source);
100};
101} // namespace QMdi
102
103class QMdiAreaTabBar;
104class QMdiAreaPrivate : public QAbstractScrollAreaPrivate
105{
106 Q_DECLARE_PUBLIC(QMdiArea)
107public:
108 QMdiAreaPrivate();
109
110 // Variables.
111 QMdi::Rearranger *cascader;
112 QMdi::Rearranger *regularTiler;
113 QMdi::Rearranger *iconTiler;
114 QMdi::Placer *placer;
115#if QT_CONFIG(rubberband)
116 QRubberBand *rubberBand;
117#endif
118 QMdiAreaTabBar *tabBar;
119 QList<QMdi::Rearranger *> pendingRearrangements;
120 QList<QPointer<QMdiSubWindow>> pendingPlacements;
121 QList<QPointer<QMdiSubWindow>> childWindows;
122 QList<int> indicesToActivatedChildren;
123 QPointer<QMdiSubWindow> active;
124 QPointer<QMdiSubWindow> aboutToBecomeActive;
125 QBrush background;
126 QMdiArea::WindowOrder activationOrder;
127 QMdiArea::AreaOptions options;
128 QMdiArea::ViewMode viewMode;
129#if QT_CONFIG(tabbar)
130 bool documentMode;
131 bool tabsClosable;
132 bool tabsMovable;
133#endif
134#if QT_CONFIG(tabwidget)
135 QTabWidget::TabShape tabShape;
136 QTabWidget::TabPosition tabPosition;
137#endif
138 bool ignoreGeometryChange;
139 bool ignoreWindowStateChange;
140 bool isActivated;
141 bool isSubWindowsTiled;
142 bool showActiveWindowMaximized;
143 bool tileCalledFromResizeEvent;
144 bool updatesDisabledByUs;
145 bool inViewModeChange;
146 int indexToNextWindow;
147 int indexToPreviousWindow;
148 int indexToHighlighted;
149 int indexToLastActiveTab;
150 QBasicTimer resizeTimer;
151 QBasicTimer tabToPreviousTimer;
152
153 // Slots.
154 void _q_deactivateAllWindows(QMdiSubWindow *aboutToActivate = nullptr);
155 void _q_processWindowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState);
156 void _q_currentTabChanged(int index);
157 void _q_closeTab(int index);
158 void _q_moveTab(int from, int to);
159
160 // Functions.
161 void appendChild(QMdiSubWindow *child);
162 void place(QMdi::Placer *placer, QMdiSubWindow *child);
163 void rearrange(QMdi::Rearranger *rearranger);
164 void arrangeMinimizedSubWindows();
165 void activateWindow(QMdiSubWindow *child);
166 void activateCurrentWindow();
167 void activateHighlightedWindow();
168 void emitWindowActivated(QMdiSubWindow *child);
169 void resetActiveWindow(QMdiSubWindow *child = nullptr);
170 void updateActiveWindow(int removedIndex, bool activeRemoved);
171 void updateScrollBars();
172 void internalRaise(QMdiSubWindow *child) const;
173 bool scrollBarsEnabled() const;
174 bool lastWindowAboutToBeDestroyed() const;
175 void setChildActivationEnabled(bool enable = true, bool onlyNextActivationEvent = false) const;
176 QRect resizeToMinimumTileSize(const QSize &minSubWindowSize, int subWindowCount);
177 void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) override; // reimp
178 QMdiSubWindow *nextVisibleSubWindow(int increaseFactor, QMdiArea::WindowOrder,
179 int removed = -1, int fromIndex = -1) const;
180 void highlightNextSubWindow(int increaseFactor);
181 QList<QMdiSubWindow *> subWindowList(QMdiArea::WindowOrder, bool reversed = false) const;
182 void disconnectSubWindow(QObject *subWindow);
183 void setViewMode(QMdiArea::ViewMode mode);
184#if QT_CONFIG(tabbar)
185 void updateTabBarGeometry();
186 void refreshTabBar();
187#endif
188
189 inline void startResizeTimer()
190 {
191 Q_Q(QMdiArea);
192
193 using namespace std::chrono_literals;
194 resizeTimer.start(duration: 200ms, obj: q);
195 }
196
197 inline void startTabToPreviousTimer()
198 {
199 Q_Q(QMdiArea);
200
201 using namespace std::chrono_literals;
202 tabToPreviousTimer.start(duration: QApplication::keyboardInputInterval() * 1ms, obj: q);
203 }
204
205 inline bool windowStaysOnTop(QMdiSubWindow *subWindow) const
206 {
207 if (!subWindow)
208 return false;
209 return subWindow->windowFlags() & Qt::WindowStaysOnTopHint;
210 }
211
212 inline bool isExplicitlyDeactivated(QMdiSubWindow *subWindow) const
213 {
214 if (!subWindow)
215 return true;
216 return subWindow->d_func()->isExplicitlyDeactivated;
217 }
218
219 inline void setActive(QMdiSubWindow *subWindow, bool active = true, bool changeFocus = true) const
220 {
221 if (subWindow)
222 subWindow->d_func()->setActive(activate: active, changeFocus);
223 }
224
225#if QT_CONFIG(rubberband)
226 void showRubberBandFor(QMdiSubWindow *subWindow);
227
228 inline void hideRubberBand()
229 {
230 if (rubberBand && rubberBand->isVisible())
231 rubberBand->hide();
232 indexToHighlighted = -1;
233 }
234#endif // QT_CONFIG(rubberband)
235};
236
237QT_END_NAMESPACE
238
239#endif // QMDIAREA_P_H
240

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