1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | // |
5 | // W A R N I N G |
6 | // ------------- |
7 | // |
8 | // This file is not part of the Qt API. It exists for the convenience |
9 | // of Qt Designer. This header |
10 | // file may change from version to version without notice, or even be removed. |
11 | // |
12 | // We mean it. |
13 | // |
14 | |
15 | #ifndef QLAYOUT_WIDGET_H |
16 | #define QLAYOUT_WIDGET_H |
17 | |
18 | #include "shared_global_p.h" |
19 | |
20 | #include <QtDesigner/layoutdecoration.h> |
21 | |
22 | #include <QtCore/qpointer.h> |
23 | #include <QtCore/qvariant.h> |
24 | #include <QtWidgets/qwidget.h> |
25 | #include <QtWidgets/qlayout.h> |
26 | |
27 | QT_BEGIN_NAMESPACE |
28 | |
29 | class QDesignerFormWindowInterface; |
30 | class QDesignerFormEditorInterface; |
31 | class QGridLayout; |
32 | class QFormLayout; |
33 | |
34 | namespace qdesigner_internal { |
35 | // ---- LayoutProperties: Helper struct that stores all layout-relevant properties |
36 | // with functions to retrieve and apply to property sheets. Can be used to store the state |
37 | // for undo commands and while rebuilding layouts. |
38 | struct QDESIGNER_SHARED_EXPORT LayoutProperties |
39 | { |
40 | LayoutProperties(); |
41 | void clear(); |
42 | |
43 | enum Margins { LeftMargin, TopMargin, RightMargin, BottomMargin, MarginCount }; |
44 | enum Spacings { Spacing, HorizSpacing, VertSpacing, SpacingsCount }; |
45 | |
46 | enum PropertyMask { |
47 | ObjectNameProperty = 0x1, |
48 | LeftMarginProperty = 0x2, TopMarginProperty = 0x4, RightMarginProperty = 0x8, BottomMarginProperty = 0x10, |
49 | SpacingProperty = 0x20, HorizSpacingProperty = 0x40, VertSpacingProperty = 0x80, |
50 | SizeConstraintProperty = 0x100, |
51 | FieldGrowthPolicyProperty = 0x200, RowWrapPolicyProperty = 0x400, LabelAlignmentProperty = 0x0800, FormAlignmentProperty = 0x1000, |
52 | BoxStretchProperty = 0x2000, GridRowStretchProperty = 0x4000, GridColumnStretchProperty = 0x8000, |
53 | GridRowMinimumHeightProperty = 0x10000, GridColumnMinimumWidthProperty = 0x20000, |
54 | AllProperties = 0xFFFF}; |
55 | |
56 | // return a PropertyMask of visible properties |
57 | static int visibleProperties(const QLayout *layout); |
58 | |
59 | // Retrieve from /apply to sheet: A property mask is returned indicating the properties found in the sheet |
60 | int fromPropertySheet(const QDesignerFormEditorInterface *core, QLayout *l, int mask = AllProperties); |
61 | int toPropertySheet(const QDesignerFormEditorInterface *core, QLayout *l, int mask = AllProperties, bool applyChanged = true) const; |
62 | |
63 | int m_margins[MarginCount]; |
64 | bool m_marginsChanged[MarginCount]; |
65 | |
66 | int m_spacings[SpacingsCount]; |
67 | bool m_spacingsChanged[SpacingsCount]; |
68 | |
69 | QVariant m_objectName; // receives a PropertySheetStringValue |
70 | bool m_objectNameChanged; |
71 | QVariant m_sizeConstraint; |
72 | bool m_sizeConstraintChanged; |
73 | |
74 | bool m_fieldGrowthPolicyChanged; |
75 | QVariant m_fieldGrowthPolicy; |
76 | bool m_rowWrapPolicyChanged; |
77 | QVariant m_rowWrapPolicy; |
78 | bool m_labelAlignmentChanged; |
79 | QVariant m_labelAlignment; |
80 | bool m_formAlignmentChanged; |
81 | QVariant m_formAlignment; |
82 | |
83 | bool m_boxStretchChanged; |
84 | QVariant m_boxStretch; |
85 | |
86 | bool m_gridRowStretchChanged; |
87 | QVariant m_gridRowStretch; |
88 | |
89 | bool m_gridColumnStretchChanged; |
90 | QVariant m_gridColumnStretch; |
91 | |
92 | bool m_gridRowMinimumHeightChanged; |
93 | QVariant m_gridRowMinimumHeight; |
94 | |
95 | bool m_gridColumnMinimumWidthChanged; |
96 | QVariant m_gridColumnMinimumWidth; |
97 | }; |
98 | |
99 | // -- LayoutHelper: For use with the 'insert widget'/'delete widget' command, |
100 | // able to store and restore states. |
101 | // This could become part of 'QDesignerLayoutDecorationExtensionV2', |
102 | // but to keep any existing old extensions working, it is provided as |
103 | // separate class with a factory function. |
104 | class LayoutHelper { |
105 | protected: |
106 | LayoutHelper(); |
107 | |
108 | public: |
109 | Q_DISABLE_COPY(LayoutHelper) |
110 | |
111 | virtual ~LayoutHelper(); |
112 | |
113 | static LayoutHelper *createLayoutHelper(int type); |
114 | |
115 | static int indexOf(const QLayout *lt, const QWidget *widget); |
116 | |
117 | // Return area of an item (x == columns) |
118 | QRect itemInfo(QLayout *lt, const QWidget *widget) const; |
119 | |
120 | virtual QRect itemInfo(QLayout *lt, int index) const = 0; |
121 | virtual void insertWidget(QLayout *lt, const QRect &info, QWidget *w) = 0; |
122 | virtual void removeWidget(QLayout *lt, QWidget *widget) = 0; |
123 | // Since 4.5: The 'morphing' feature requires an API for replacing widgets on layouts. |
124 | virtual void replaceWidget(QLayout *lt, QWidget *before, QWidget *after) = 0; |
125 | |
126 | // Simplify a grid, remove empty columns, rows within the rectangle |
127 | // The DeleteWidget command restricts the area to be simplified. |
128 | virtual bool canSimplify(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout, const QRect &restrictionArea) const = 0; |
129 | virtual void simplify(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout, const QRect &restrictionArea) = 0; |
130 | |
131 | // Push and pop a state. Can be used for implementing undo for |
132 | // simplify/row, column insertion commands, provided that |
133 | // the widgets remain the same. |
134 | virtual void pushState(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout) = 0; |
135 | virtual void popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout) = 0; |
136 | }; |
137 | |
138 | // Base class for layout decoration extensions. |
139 | class QDESIGNER_SHARED_EXPORT QLayoutSupport: public QObject, public QDesignerLayoutDecorationExtension |
140 | { |
141 | Q_OBJECT |
142 | Q_INTERFACES(QDesignerLayoutDecorationExtension) |
143 | |
144 | protected: |
145 | QLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, LayoutHelper *helper, QObject *parent = nullptr); |
146 | |
147 | public: |
148 | ~QLayoutSupport() override; |
149 | |
150 | inline QDesignerFormWindowInterface *formWindow() const { return m_formWindow; } |
151 | |
152 | // DecorationExtension V2 |
153 | LayoutHelper* helper() const { return m_helper; } |
154 | |
155 | // DecorationExtension |
156 | int currentIndex() const override { return m_currentIndex; } |
157 | |
158 | InsertMode currentInsertMode() const override { return m_currentInsertMode; } |
159 | |
160 | std::pair<int, int> currentCell() const override { return m_currentCell; } |
161 | |
162 | int findItemAt(const QPoint &pos) const override; |
163 | int indexOf(QWidget *widget) const override; |
164 | int indexOf(QLayoutItem *item) const override; |
165 | |
166 | void adjustIndicator(const QPoint &pos, int index) override; |
167 | |
168 | QWidgetList widgets(QLayout *layout) const override; |
169 | |
170 | // Pad empty cells with dummy spacers. Called by layouting commands. |
171 | static void createEmptyCells(QGridLayout *gridLayout); |
172 | // remove dummy spacers in the area. Returns false if there are non-empty items in the way |
173 | static bool removeEmptyCells(QGridLayout *gridLayout, const QRect &area); |
174 | static void createEmptyCells(QFormLayout *formLayout); // ditto. |
175 | static bool removeEmptyCells(QFormLayout *formLayout, const QRect &area); |
176 | |
177 | // grid helpers: find item index |
178 | static int findItemAt(QGridLayout *, int row, int column); |
179 | using QDesignerLayoutDecorationExtension::findItemAt; |
180 | // grid helpers: Quick check whether simplify should be enabled for grids. May return false positives. |
181 | static bool canSimplifyQuickCheck(const QGridLayout *); |
182 | static bool canSimplifyQuickCheck(const QFormLayout *fl); |
183 | // Factory function, create layout support according to layout type of widget |
184 | static QLayoutSupport *createLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent = nullptr); |
185 | |
186 | protected: |
187 | // figure out insertion position and mode from indicator on empty cell if supported |
188 | virtual void setCurrentCellFromIndicatorOnEmptyCell(int index) = 0; |
189 | // figure out insertion position and mode from indicator |
190 | virtual void setCurrentCellFromIndicator(Qt::Orientation indicatorOrientation, int index, int increment) = 0; |
191 | |
192 | // Overwrite to return the extended geometry of an item, that is, |
193 | // if it is a border item, include the widget border for the indicator to work correctly |
194 | virtual QRect extendedGeometry(int index) const = 0; |
195 | virtual bool supportsIndicatorOrientation(Qt::Orientation indicatorOrientation) const = 0; |
196 | |
197 | QRect itemInfo(int index) const override; |
198 | QLayout *layout() const; |
199 | QGridLayout *gridLayout() const; |
200 | QWidget *widget() const { return m_widget; } |
201 | |
202 | void setInsertMode(InsertMode im); |
203 | void setCurrentCell(const std::pair<int, int> &cell); |
204 | |
205 | private: |
206 | enum Indicator { LeftIndicator, TopIndicator, RightIndicator, BottomIndicator, NumIndicators }; |
207 | |
208 | void hideIndicator(Indicator i); |
209 | void showIndicator(Indicator i, const QRect &geometry, const QPalette &); |
210 | |
211 | QDesignerFormWindowInterface *m_formWindow; |
212 | LayoutHelper* m_helper; |
213 | |
214 | QPointer<QWidget> m_widget; |
215 | QPointer<QWidget> m_indicators[NumIndicators]; |
216 | int m_currentIndex; |
217 | InsertMode m_currentInsertMode; |
218 | std::pair<int, int> m_currentCell; |
219 | }; |
220 | } // namespace qdesigner_internal |
221 | |
222 | // Red layout widget. |
223 | class QDESIGNER_SHARED_EXPORT QLayoutWidget: public QWidget |
224 | { |
225 | Q_OBJECT |
226 | public: |
227 | explicit QLayoutWidget(QDesignerFormWindowInterface *formWindow, QWidget *parent = nullptr); |
228 | |
229 | int layoutLeftMargin() const; |
230 | void setLayoutLeftMargin(int layoutMargin); |
231 | |
232 | int layoutTopMargin() const; |
233 | void setLayoutTopMargin(int layoutMargin); |
234 | |
235 | int layoutRightMargin() const; |
236 | void setLayoutRightMargin(int layoutMargin); |
237 | |
238 | int layoutBottomMargin() const; |
239 | void setLayoutBottomMargin(int layoutMargin); |
240 | |
241 | inline QDesignerFormWindowInterface *formWindow() const { return m_formWindow; } |
242 | |
243 | protected: |
244 | bool event(QEvent *e) override; |
245 | void paintEvent(QPaintEvent *e) override; |
246 | |
247 | private: |
248 | QDesignerFormWindowInterface *m_formWindow; |
249 | int m_leftMargin; |
250 | int m_topMargin; |
251 | int m_rightMargin; |
252 | int m_bottomMargin; |
253 | }; |
254 | |
255 | QT_END_NAMESPACE |
256 | |
257 | #endif // QDESIGNER_WIDGET_H |
258 | |