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