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 
46 QT_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 */
controlType() const235 QSizePolicy::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 */
setControlType(ControlType type)256 void 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 uint qHash(QSizePolicy key, uint 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 */
operator QVariant() const440 QSizePolicy::operator QVariant() const
441 {
442     return QVariant(QMetaType::QSizePolicy, 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 */
operator <<(QDataStream & stream,const QSizePolicy & policy)455 QDataStream &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 */
operator >>(QDataStream & stream,QSizePolicy & policy)479 QDataStream &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
operator <<(QDebug dbg,const QSizePolicy & p)496 QDebug 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 
505 QT_END_NAMESPACE
506 
507 #include "moc_qsizepolicy.cpp"
508