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
49class QVariant;
50class QSizePolicy;
51
52Q_DECL_CONST_FUNCTION inline size_t qHash(QSizePolicy key, size_t seed = 0) noexcept;
53
54class Q_WIDGETS_EXPORT QSizePolicy
55{
56 Q_GADGET
57
58public:
59 enum PolicyFlag {
60 GrowFlag = 1,
61 ExpandFlag = 2,
62 ShrinkFlag = 4,
63 IgnoreFlag = 8
64 };
65
66 enum Policy {
67 Fixed = 0,
68 Minimum = GrowFlag,
69 Maximum = ShrinkFlag,
70 Preferred = GrowFlag | ShrinkFlag,
71 MinimumExpanding = GrowFlag | ExpandFlag,
72 Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
73 Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
74 };
75 Q_ENUM(Policy)
76
77 enum ControlType {
78 DefaultType = 0x00000001,
79 ButtonBox = 0x00000002,
80 CheckBox = 0x00000004,
81 ComboBox = 0x00000008,
82 Frame = 0x00000010,
83 GroupBox = 0x00000020,
84 Label = 0x00000040,
85 Line = 0x00000080,
86 LineEdit = 0x00000100,
87 PushButton = 0x00000200,
88 RadioButton = 0x00000400,
89 Slider = 0x00000800,
90 SpinBox = 0x00001000,
91 TabWidget = 0x00002000,
92 ToolButton = 0x00004000
93 };
94 Q_DECLARE_FLAGS(ControlTypes, ControlType)
95 Q_FLAG(ControlTypes)
96
97 constexpr QSizePolicy() noexcept : data(0) { }
98
99 constexpr QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) noexcept
100 : bits{0, 0, quint32(horizontal), quint32(vertical),
101 type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0}
102 {}
103 constexpr Policy horizontalPolicy() const noexcept { return static_cast<Policy>(bits.horPolicy); }
104 constexpr Policy verticalPolicy() const noexcept { return static_cast<Policy>(bits.verPolicy); }
105 ControlType controlType() const noexcept;
106
107 constexpr void setHorizontalPolicy(Policy d) noexcept { bits.horPolicy = d; }
108 constexpr void setVerticalPolicy(Policy d) noexcept { bits.verPolicy = d; }
109 void setControlType(ControlType type) noexcept;
110
111 constexpr Qt::Orientations expandingDirections() const noexcept {
112 return ( (verticalPolicy() & int(ExpandFlag)) ? Qt::Vertical : Qt::Orientations() )
113 | ( (horizontalPolicy() & int(ExpandFlag)) ? Qt::Horizontal : Qt::Orientations() ) ;
114 }
115
116 constexpr void setHeightForWidth(bool b) noexcept { bits.hfw = b; }
117 constexpr bool hasHeightForWidth() const noexcept { return bits.hfw; }
118 constexpr void setWidthForHeight(bool b) noexcept { bits.wfh = b; }
119 constexpr bool hasWidthForHeight() const noexcept { return bits.wfh; }
120
121 constexpr bool operator==(const QSizePolicy& s) const noexcept { return data == s.data; }
122 constexpr bool operator!=(const QSizePolicy& s) const noexcept { return data != s.data; }
123
124 friend Q_DECL_CONST_FUNCTION size_t qHash(QSizePolicy key, size_t seed) noexcept { return qHash(key.data, seed); }
125
126 operator QVariant() const;
127
128 constexpr int horizontalStretch() const noexcept { return static_cast<int>(bits.horStretch); }
129 constexpr int verticalStretch() const noexcept { return static_cast<int>(bits.verStretch); }
130 constexpr void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
131 constexpr void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
132
133 constexpr bool retainSizeWhenHidden() const noexcept { return bits.retainSizeWhenHidden; }
134 constexpr void setRetainSizeWhenHidden(bool retainSize) noexcept { bits.retainSizeWhenHidden = retainSize; }
135
136 constexpr void transpose() noexcept { *this = transposed(); }
137 [[nodiscard]] constexpr QSizePolicy transposed() const noexcept
138 {
139 return QSizePolicy(bits.transposed());
140 }
141
142private:
143#ifndef QT_NO_DATASTREAM
144 friend Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
145 friend Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
146#endif
147 constexpr QSizePolicy(int i) noexcept : data(i) { }
148 struct Bits;
149 constexpr explicit QSizePolicy(Bits b) noexcept : bits(b) { }
150
151 static constexpr quint32 toControlTypeFieldValue(ControlType type) noexcept
152 {
153 /*
154 The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
155 etc. In memory, we pack it onto the available bits (CTSize) in
156 setControlType(), and unpack it here.
157
158 Example:
159
160 0x00000001 maps to 0
161 0x00000002 maps to 1
162 0x00000004 maps to 2
163 0x00000008 maps to 3
164 etc.
165 */
166
167 return qCountTrailingZeroBits(static_cast<quint32>(type));
168 }
169
170 struct Bits {
171 quint32 horStretch : 8;
172 quint32 verStretch : 8;
173 quint32 horPolicy : 4;
174 quint32 verPolicy : 4;
175 quint32 ctype : 5;
176 quint32 hfw : 1;
177 quint32 wfh : 1;
178 quint32 retainSizeWhenHidden : 1;
179
180 constexpr Bits transposed() const noexcept
181 {
182 return {verStretch, // \ swap
183 horStretch, // /
184 verPolicy, // \ swap
185 horPolicy, // /
186 ctype,
187 hfw, // \ don't swap (historic behavior)
188 wfh, // /
189 retainSizeWhenHidden};
190 }
191 };
192 union {
193 Bits bits;
194 quint32 data;
195 };
196};
197
198Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE);
199
200Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes)
201
202#ifndef QT_NO_DATASTREAM
203Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
204Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
205#endif
206
207#ifndef QT_NO_DEBUG_STREAM
208Q_WIDGETS_EXPORT QDebug operator<<(QDebug dbg, const QSizePolicy &);
209#endif
210
211QT_END_NAMESPACE
212
213#endif // QSIZEPOLICY_H
214