| 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 | */ |
| 235 | 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 | */ |
| 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 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 | */ |
| 440 | QSizePolicy::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 | */ |
| 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 | */ |
| 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 |
| 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 | |