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 
47 QT_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 
65 class QVariant;
66 class QSizePolicy;
67 
68 Q_DECL_CONST_FUNCTION inline uint qHash(QSizePolicy key, uint seed = 0) noexcept;
69 
70 class Q_WIDGETS_EXPORT QSizePolicy
71 {
72     Q_GADGET
73 
74 public:
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     };
Q_DECLARE_FLAGS(ControlTypes,ControlType)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
horizontalPolicy()128     QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const noexcept { return static_cast<Policy>(bits.horPolicy); }
verticalPolicy()129     QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const noexcept { return static_cast<Policy>(bits.verPolicy); }
130     ControlType controlType() const noexcept;
131 
setHorizontalPolicy(Policy d)132     Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) noexcept { bits.horPolicy = d; }
setVerticalPolicy(Policy d)133     Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) noexcept { bits.verPolicy = d; }
134     void setControlType(ControlType type) noexcept;
135 
expandingDirections()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 
setHeightForWidth(bool b)141     Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) noexcept { bits.hfw = b;  }
hasHeightForWidth()142     QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const noexcept { return bits.hfw; }
setWidthForHeight(bool b)143     Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) noexcept { bits.wfh = b;  }
hasWidthForHeight()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 
qHash(QSizePolicy key,uint seed)149     friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) noexcept { return qHash(key.data, seed); }
150 
151     operator QVariant() const;
152 
horizontalStretch()153     QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const noexcept { return static_cast<int>(bits.horStretch); }
verticalStretch()154     QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const noexcept { return static_cast<int>(bits.verStretch); }
setHorizontalStretch(int stretchFactor)155     Q_DECL_RELAXED_CONSTEXPR void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
setVerticalStretch(int stretchFactor)156     Q_DECL_RELAXED_CONSTEXPR void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
157 
retainSizeWhenHidden()158     QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const noexcept { return bits.retainSizeWhenHidden; }
setRetainSizeWhenHidden(bool retainSize)159     Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) noexcept { bits.retainSizeWhenHidden = retainSize; }
160 
transpose()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
transposed()166     QSizePolicy transposed() const noexcept
167     {
168         return QSizePolicy(bits.transposed());
169     }
170 
171 private:
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
QSizePolicy(int i)176     QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) noexcept : data(i) { }
177     struct Bits;
QSizePolicy(Bits b)178     QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) noexcept : bits(b) { }
179 
toControlTypeFieldValue(ControlType type)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
transposedBits210         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:
229 Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE);
230 #else
231 Q_DECLARE_TYPEINFO(QSizePolicy, Q_RELOCATABLE_TYPE);
232 #endif
233 
234 Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes)
235 
236 #ifndef QT_NO_DATASTREAM
237 Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
238 Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
239 #endif
240 
241 #ifndef QT_NO_DEBUG_STREAM
242 Q_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 
249 QT_END_NAMESPACE
250 
251 #endif // QSIZEPOLICY_H
252