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 QSIZEPOLICY_H
41#define QSIZEPOLICY_H
42
43#include <QtWidgets/qtwidgetsglobal.h>
44#include <QtCore/qobject.h>
45#include <QtCore/qalgorithms.h>
46
47QT_BEGIN_NAMESPACE
48
49// gcc < 4.8.0 has problems with init'ing variant members in constexpr ctors
50// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54922
51#if !defined(Q_CC_GNU) || defined(Q_CC_INTEL) || defined(Q_CC_CLANG) || Q_CC_GNU >= 408
52# define QT_SIZEPOLICY_CONSTEXPR Q_DECL_CONSTEXPR
53# if defined(Q_COMPILER_UNIFORM_INIT)
54# define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT Q_DECL_CONSTEXPR
55# endif // uniform-init
56#endif
57
58#ifndef QT_SIZEPOLICY_CONSTEXPR
59# define QT_SIZEPOLICY_CONSTEXPR
60#endif
61#ifndef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
62# define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
63#endif
64
65class QVariant;
66class QSizePolicy;
67
68Q_DECL_CONST_FUNCTION inline uint qHash(QSizePolicy key, uint seed = 0) noexcept;
69
70class Q_WIDGETS_EXPORT QSizePolicy
71{
72 Q_GADGET
73
74public:
75 enum PolicyFlag {
76 GrowFlag = 1,
77 ExpandFlag = 2,
78 ShrinkFlag = 4,
79 IgnoreFlag = 8
80 };
81
82 enum Policy {
83 Fixed = 0,
84 Minimum = GrowFlag,
85 Maximum = ShrinkFlag,
86 Preferred = GrowFlag | ShrinkFlag,
87 MinimumExpanding = GrowFlag | ExpandFlag,
88 Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
89 Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
90 };
91 Q_ENUM(Policy)
92
93 enum ControlType {
94 DefaultType = 0x00000001,
95 ButtonBox = 0x00000002,
96 CheckBox = 0x00000004,
97 ComboBox = 0x00000008,
98 Frame = 0x00000010,
99 GroupBox = 0x00000020,
100 Label = 0x00000040,
101 Line = 0x00000080,
102 LineEdit = 0x00000100,
103 PushButton = 0x00000200,
104 RadioButton = 0x00000400,
105 Slider = 0x00000800,
106 SpinBox = 0x00001000,
107 TabWidget = 0x00002000,
108 ToolButton = 0x00004000
109 };
110 Q_DECLARE_FLAGS(ControlTypes, ControlType)
111 Q_FLAG(ControlTypes)
112
113 QT_SIZEPOLICY_CONSTEXPR QSizePolicy() noexcept : data(0) { }
114
115#if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_QDOC)
116 QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) noexcept
117 : bits{0, 0, quint32(horizontal), quint32(vertical),
118 type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0}
119 {}
120#else
121 QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) noexcept
122 : data(0) {
123 bits.horPolicy = horizontal;
124 bits.verPolicy = vertical;
125 setControlType(type);
126 }
127#endif // uniform-init
128 QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const noexcept { return static_cast<Policy>(bits.horPolicy); }
129 QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const noexcept { return static_cast<Policy>(bits.verPolicy); }
130 ControlType controlType() const noexcept;
131
132 Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) noexcept { bits.horPolicy = d; }
133 Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) noexcept { bits.verPolicy = d; }
134 void setControlType(ControlType type) noexcept;
135
136 QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const noexcept {
137 return ( (verticalPolicy() & ExpandFlag) ? Qt::Vertical : Qt::Orientations() )
138 | ( (horizontalPolicy() & ExpandFlag) ? Qt::Horizontal : Qt::Orientations() ) ;
139 }
140
141 Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) noexcept { bits.hfw = b; }
142 QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const noexcept { return bits.hfw; }
143 Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) noexcept { bits.wfh = b; }
144 QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const noexcept { return bits.wfh; }
145
146 QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const noexcept { return data == s.data; }
147 QT_SIZEPOLICY_CONSTEXPR bool operator!=(const QSizePolicy& s) const noexcept { return data != s.data; }
148
149 friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) noexcept { return qHash(key.data, seed); }
150
151 operator QVariant() const;
152
153 QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const noexcept { return static_cast<int>(bits.horStretch); }
154 QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const noexcept { return static_cast<int>(bits.verStretch); }
155 Q_DECL_RELAXED_CONSTEXPR void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
156 Q_DECL_RELAXED_CONSTEXPR void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
157
158 QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const noexcept { return bits.retainSizeWhenHidden; }
159 Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) noexcept { bits.retainSizeWhenHidden = retainSize; }
160
161 Q_DECL_RELAXED_CONSTEXPR void transpose() noexcept { *this = transposed(); }
162 Q_REQUIRED_RESULT
163#ifndef Q_QDOC
164 QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
165#endif
166 QSizePolicy transposed() const noexcept
167 {
168 return QSizePolicy(bits.transposed());
169 }
170
171private:
172#ifndef QT_NO_DATASTREAM
173 friend Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
174 friend Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
175#endif
176 QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) noexcept : data(i) { }
177 struct Bits;
178 QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) noexcept : bits(b) { }
179
180 static Q_DECL_RELAXED_CONSTEXPR quint32 toControlTypeFieldValue(ControlType type) noexcept
181 {
182 /*
183 The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
184 etc. In memory, we pack it onto the available bits (CTSize) in
185 setControlType(), and unpack it here.
186
187 Example:
188
189 0x00000001 maps to 0
190 0x00000002 maps to 1
191 0x00000004 maps to 2
192 0x00000008 maps to 3
193 etc.
194 */
195
196 return qCountTrailingZeroBits(static_cast<quint32>(type));
197 }
198
199 struct Bits {
200 quint32 horStretch : 8;
201 quint32 verStretch : 8;
202 quint32 horPolicy : 4;
203 quint32 verPolicy : 4;
204 quint32 ctype : 5;
205 quint32 hfw : 1;
206 quint32 wfh : 1;
207 quint32 retainSizeWhenHidden : 1;
208
209 QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
210 Bits transposed() const noexcept
211 {
212 return {verStretch, // \ swap
213 horStretch, // /
214 verPolicy, // \ swap
215 horPolicy, // /
216 ctype,
217 hfw, // \ don't swap (historic behavior)
218 wfh, // /
219 retainSizeWhenHidden};
220 }
221 };
222 union {
223 Bits bits;
224 quint32 data;
225 };
226};
227#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
228// Can't add in Qt 5, as QList<QSizePolicy> would be BiC:
229Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE);
230#else
231Q_DECLARE_TYPEINFO(QSizePolicy, Q_RELOCATABLE_TYPE);
232#endif
233
234Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes)
235
236#ifndef QT_NO_DATASTREAM
237Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
238Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
239#endif
240
241#ifndef QT_NO_DEBUG_STREAM
242Q_WIDGETS_EXPORT QDebug operator<<(QDebug dbg, const QSizePolicy &);
243#endif
244
245
246#undef QT_SIZEPOLICY_CONSTEXPR
247#undef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
248
249QT_END_NAMESPACE
250
251#endif // QSIZEPOLICY_H
252