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#include "qsizepolicy.h"
41
42#include <qdatastream.h>
43#include <qdebug.h>
44#include <qvariant.h>
45
46QT_BEGIN_NAMESPACE
47
48/*!
49 \class QSizePolicy
50 \brief The QSizePolicy class is a layout attribute describing horizontal
51 and vertical resizing policy.
52
53 \ingroup geomanagement
54 \inmodule QtWidgets
55
56 The size policy of a widget is an expression of its willingness to
57 be resized in various ways, and affects how the widget is treated
58 by the \l{Layout Management}{layout engine}. Each widget returns a
59 QSizePolicy that describes the horizontal and vertical resizing
60 policy it prefers when being laid out. You can change this for
61 a specific widget by changing its QWidget::sizePolicy property.
62
63 QSizePolicy contains two independent QSizePolicy::Policy values
64 and two stretch factors; one describes the widgets's horizontal
65 size policy, and the other describes its vertical size policy. It
66 also contains a flag to indicate whether the height and width of
67 its preferred size are related.
68
69 The horizontal and vertical policies can be set in the
70 constructor, and altered using the setHorizontalPolicy() and
71 setVerticalPolicy() functions. The stretch factors can be set
72 using the setHorizontalStretch() and setVerticalStretch()
73 functions. The flag indicating whether the widget's
74 \l{QWidget::sizeHint()}{sizeHint()} is width-dependent (such as a
75 menu bar or a word-wrapping label) can be set using the
76 setHeightForWidth() function.
77
78 The current size policies and stretch factors be retrieved using
79 the horizontalPolicy(), verticalPolicy(), horizontalStretch() and
80 verticalStretch() functions. Alternatively, use the transpose()
81 function to swap the horizontal and vertical policies and
82 stretches. The hasHeightForWidth() function returns the current
83 status of the flag indicating the size hint dependencies.
84
85 Use the expandingDirections() function to determine whether the
86 associated widget can make use of more space than its
87 \l{QWidget::sizeHint()}{sizeHint()} function indicates, as well as
88 find out in which directions it can expand.
89
90 Finally, the QSizePolicy class provides operators comparing this
91 size policy to a given policy, as well as a QVariant operator
92 storing this QSizePolicy as a QVariant object.
93
94 \sa QSize, QWidget::sizeHint(), QWidget::sizePolicy,
95 QLayoutItem::sizeHint()
96*/
97
98/*!
99 \enum QSizePolicy::PolicyFlag
100
101 These flags are combined together to form the various \l{Policy}
102 values:
103
104 \value GrowFlag The widget can grow beyond its size hint if necessary.
105 \value ExpandFlag The widget should get as much space as possible.
106 \value ShrinkFlag The widget can shrink below its size hint if necessary.
107 \value IgnoreFlag The widget's size hint is ignored. The widget will get
108 as much space as possible.
109
110 \sa Policy
111*/
112
113/*!
114 \enum QSizePolicy::Policy
115
116 This enum describes the various per-dimension sizing types used
117 when constructing a QSizePolicy.
118
119 \value Fixed The QWidget::sizeHint() is the only acceptable
120 alternative, so the widget can never grow or shrink (e.g. the
121 vertical direction of a push button).
122
123 \value Minimum The sizeHint() is minimal, and sufficient. The
124 widget can be expanded, but there is no advantage to it being
125 larger (e.g. the horizontal direction of a push button).
126 It cannot be smaller than the size provided by sizeHint().
127
128 \value Maximum The sizeHint() is a maximum. The widget can be
129 shrunk any amount without detriment if other widgets need the
130 space (e.g. a separator line).
131 It cannot be larger than the size provided by sizeHint().
132
133 \value Preferred The sizeHint() is best, but the widget can be
134 shrunk and still be useful. The widget can be expanded, but there
135 is no advantage to it being larger than sizeHint() (the default
136 QWidget policy).
137
138 \value Expanding The sizeHint() is a sensible size, but the
139 widget can be shrunk and still be useful. The widget can make use
140 of extra space, so it should get as much space as possible (e.g.
141 the horizontal direction of a horizontal slider).
142
143 \value MinimumExpanding The sizeHint() is minimal, and sufficient.
144 The widget can make use of extra space, so it should get as much
145 space as possible (e.g. the horizontal direction of a horizontal
146 slider).
147
148 \value Ignored The sizeHint() is ignored. The widget will get as
149 much space as possible.
150
151 \sa PolicyFlag, setHorizontalPolicy(), setVerticalPolicy()
152*/
153
154/*!
155 \fn QSizePolicy::QSizePolicy()
156
157 Constructs a QSizePolicy object with \l Fixed as its horizontal
158 and vertical policies.
159
160 The policies can be altered using the setHorizontalPolicy() and
161 setVerticalPolicy() functions. Use the setHeightForWidth()
162 function if the preferred height of the widget is dependent on the
163 width of the widget (for example, a QLabel with line wrapping).
164
165 \sa setHorizontalStretch(), setVerticalStretch()
166*/
167
168/*!
169 \fn QSizePolicy::QSizePolicy(Policy horizontal, Policy vertical, ControlType type)
170 \since 4.3
171
172 Constructs a QSizePolicy object with the given \a horizontal and
173 \a vertical policies, and the specified control \a type.
174
175 Use setHeightForWidth() if the preferred height of the widget is
176 dependent on the width of the widget (for example, a QLabel with
177 line wrapping).
178
179 \sa setHorizontalStretch(), setVerticalStretch(), controlType()
180*/
181
182/*!
183 \fn QSizePolicy::Policy QSizePolicy::horizontalPolicy() const
184
185 Returns the horizontal component of the size policy.
186
187 \sa setHorizontalPolicy(), verticalPolicy(), horizontalStretch()
188*/
189
190/*!
191 \fn QSizePolicy::Policy QSizePolicy::verticalPolicy() const
192
193 Returns the vertical component of the size policy.
194
195 \sa setVerticalPolicy(), horizontalPolicy(), verticalStretch()
196*/
197
198/*!
199 \fn void QSizePolicy::setHorizontalPolicy(Policy policy)
200
201 Sets the horizontal component to the given \a policy.
202
203 \sa horizontalPolicy(), setVerticalPolicy(), setHorizontalStretch()
204*/
205
206/*!
207 \fn void QSizePolicy::setVerticalPolicy(Policy policy)
208
209 Sets the vertical component to the given \a policy.
210
211 \sa verticalPolicy(), setHorizontalPolicy(), setVerticalStretch()
212*/
213
214/*!
215 \fn Qt::Orientations QSizePolicy::expandingDirections() const
216
217 Returns whether a widget can make use of more space than the
218 QWidget::sizeHint() function indicates.
219
220 A value of Qt::Horizontal or Qt::Vertical means that the widget
221 can grow horizontally or vertically (i.e., the horizontal or
222 vertical policy is \l Expanding or \l MinimumExpanding), whereas
223 Qt::Horizontal | Qt::Vertical means that it can grow in both
224 dimensions.
225
226 \sa horizontalPolicy(), verticalPolicy()
227*/
228
229/*!
230 \since 4.3
231
232 Returns the control type associated with the widget for which
233 this size policy applies.
234*/
235QSizePolicy::ControlType QSizePolicy::controlType() const noexcept
236{
237 return QSizePolicy::ControlType(1 << bits.ctype);
238}
239
240
241/*!
242 \since 4.3
243
244 Sets the control type associated with the widget for which this
245 size policy applies to \a type.
246
247 The control type specifies the type of the widget for which this
248 size policy applies. It is used by some styles, notably
249 QMacStyle, to insert proper spacing between widgets. For example,
250 the \macos Aqua guidelines specify that push buttons should be
251 separated by 12 pixels, whereas vertically stacked radio buttons
252 only require 6 pixels.
253
254 \sa QStyle::layoutSpacing()
255*/
256void QSizePolicy::setControlType(ControlType type) noexcept
257{
258 bits.ctype = toControlTypeFieldValue(type);
259}
260
261/*!
262 \fn void QSizePolicy::setHeightForWidth(bool dependent)
263
264 Sets the flag determining whether the widget's preferred height
265 depends on its width, to \a dependent.
266
267 \sa hasHeightForWidth(), setWidthForHeight()
268*/
269
270/*!
271 \fn bool QSizePolicy::hasHeightForWidth() const
272
273 Returns \c true if the widget's preferred height depends on its
274 width; otherwise returns \c false.
275
276 \sa setHeightForWidth()
277*/
278
279/*!
280 \fn void QSizePolicy::setWidthForHeight(bool dependent)
281
282 Sets the flag determining whether the widget's width
283 depends on its height, to \a dependent.
284
285 This is only supported for QGraphicsLayout's subclasses.
286 It is not possible to have a layout with both height-for-width
287 and width-for-height constraints at the same time.
288
289 \sa hasWidthForHeight(), setHeightForWidth()
290*/
291
292/*!
293 \fn bool QSizePolicy::hasWidthForHeight() const
294
295 Returns \c true if the widget's width depends on its
296 height; otherwise returns \c false.
297
298 \sa setWidthForHeight()
299*/
300
301/*!
302 \fn bool QSizePolicy::operator==(const QSizePolicy &other) const
303
304 Returns \c true if this policy is equal to \a other; otherwise
305 returns \c false.
306
307 \sa operator!=()
308*/
309
310/*!
311 \fn bool QSizePolicy::operator!=(const QSizePolicy &other) const
312
313 Returns \c true if this policy is different from \a other; otherwise
314 returns \c false.
315
316 \sa operator==()
317*/
318
319/*!
320 \fn size_t qHash(QSizePolicy key, size_t seed = 0)
321 \since 5.6
322 \relates QSizePolicy
323
324 Returns the hash value for \a key, using
325 \a seed to seed the calculation.
326*/
327
328/*!
329 \fn int QSizePolicy::horizontalStretch() const
330
331 Returns the horizontal stretch factor of the size policy.
332
333 \sa setHorizontalStretch(), verticalStretch(), horizontalPolicy()
334*/
335
336/*!
337 \fn int QSizePolicy::verticalStretch() const
338
339 Returns the vertical stretch factor of the size policy.
340
341 \sa setVerticalStretch(), horizontalStretch(), verticalPolicy()
342*/
343
344/*!
345 \fn void QSizePolicy::setHorizontalStretch(int stretchFactor)
346
347 Sets the horizontal stretch factor of the size policy to the given \a
348 stretchFactor. \a stretchFactor must be in the range [0,255].
349
350 When two widgets are adjacent to each other in a horizontal layout,
351 setting the horizontal stretch factor of the widget on the left to 2
352 and the factor of widget on the right to 1 will ensure that the widget
353 on the left will always be twice the size of the one on the right.
354
355 \sa horizontalStretch(), setVerticalStretch(), setHorizontalPolicy()
356*/
357
358/*!
359 \fn void QSizePolicy::setVerticalStretch(int stretchFactor)
360
361 Sets the vertical stretch factor of the size policy to the given
362 \a stretchFactor. \a stretchFactor must be in the range [0,255].
363
364 When two widgets are adjacent to each other in a vertical layout,
365 setting the vertical stretch factor of the widget on the top to 2
366 and the factor of widget on the bottom to 1 will ensure that
367 the widget on the top will always be twice the size of the one
368 on the bottom.
369
370 \sa verticalStretch(), setHorizontalStretch(), setVerticalPolicy()
371*/
372
373/*!
374 \fn void QSizePolicy::transpose()
375
376 Swaps the horizontal and vertical policies and stretches.
377
378 \sa transposed()
379*/
380
381/*!
382 \fn QSizePolicy QSizePolicy::transposed() const
383 \since 5.9
384
385 Returns a size policy object with the horizontal and vertical
386 policies and stretches swapped.
387
388 \sa transpose()
389*/
390
391/*!
392 \fn void QSizePolicy::retainSizeWhenHidden() const
393 \since 5.2
394
395 Returns whether the layout should retain the widget's size when it is hidden.
396 This is \c false by default.
397
398 \sa setRetainSizeWhenHidden()
399*/
400
401/*!
402 \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize)
403 \since 5.2
404
405 Sets whether a layout should retain the widget's size when it is hidden.
406 If \a retainSize is \c true, the layout will not be changed by hiding the widget.
407
408 \sa retainSizeWhenHidden()
409*/
410
411/*!
412 \enum QSizePolicy::ControlType
413 \since 4.3
414
415 This enum specifies the different types of widgets in terms of
416 layout interaction:
417
418 \value DefaultType The default type, when none is specified.
419 \value ButtonBox A QDialogButtonBox instance.
420 \value CheckBox A QCheckBox instance.
421 \value ComboBox A QComboBox instance.
422 \value Frame A QFrame instance.
423 \value GroupBox A QGroupBox instance.
424 \value Label A QLabel instance.
425 \value Line A QFrame instance with QFrame::HLine or QFrame::VLine.
426 \value LineEdit A QLineEdit instance.
427 \value PushButton A QPushButton instance.
428 \value RadioButton A QRadioButton instance.
429 \value Slider A QAbstractSlider instance.
430 \value SpinBox A QAbstractSpinBox instance.
431 \value TabWidget A QTabWidget instance.
432 \value ToolButton A QToolButton instance.
433
434 \sa setControlType(), controlType()
435*/
436
437/*!
438 Returns a QVariant storing this QSizePolicy.
439*/
440QSizePolicy::operator QVariant() const
441{
442 return QVariant::fromValue(*this);
443}
444
445#ifndef QT_NO_DATASTREAM
446
447/*!
448 \relates QSizePolicy
449 \since 4.2
450
451 Writes the size \a policy to the data stream \a stream.
452
453 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
454*/
455QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy)
456{
457 // The order here is for historical reasons. (compatibility with Qt4)
458 quint32 data = (policy.bits.horPolicy | // [0, 3]
459 policy.bits.verPolicy << 4 | // [4, 7]
460 policy.bits.hfw << 8 | // [8]
461 policy.bits.ctype << 9 | // [9, 13]
462 policy.bits.wfh << 14 | // [14]
463 policy.bits.retainSizeWhenHidden << 15 | // [15]
464 policy.bits.verStretch << 16 | // [16, 23]
465 policy.bits.horStretch << 24); // [24, 31]
466 return stream << data;
467}
468
469#define VALUE_OF_BITS(data, bitstart, bitcount) ((data >> bitstart) & ((1 << bitcount) -1))
470
471/*!
472 \relates QSizePolicy
473 \since 4.2
474
475 Reads the size \a policy from the data stream \a stream.
476
477 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
478*/
479QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy)
480{
481 quint32 data;
482 stream >> data;
483 policy.bits.horPolicy = VALUE_OF_BITS(data, 0, 4);
484 policy.bits.verPolicy = VALUE_OF_BITS(data, 4, 4);
485 policy.bits.hfw = VALUE_OF_BITS(data, 8, 1);
486 policy.bits.ctype = VALUE_OF_BITS(data, 9, 5);
487 policy.bits.wfh = VALUE_OF_BITS(data, 14, 1);
488 policy.bits.retainSizeWhenHidden = VALUE_OF_BITS(data, 15, 1);
489 policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8);
490 policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8);
491 return stream;
492}
493#endif // QT_NO_DATASTREAM
494
495#ifndef QT_NO_DEBUG_STREAM
496QDebug operator<<(QDebug dbg, const QSizePolicy &p)
497{
498 QDebugStateSaver saver(dbg);
499 dbg.nospace() << "QSizePolicy(horizontalPolicy = " << p.horizontalPolicy()
500 << ", verticalPolicy = " << p.verticalPolicy() << ')';
501 return dbg;
502}
503#endif
504
505QT_END_NAMESPACE
506
507#include "moc_qsizepolicy.cpp"
508