Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qlayoutitem.cpp
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
4
5#include "qlayout.h"
6
7#include "qapplication.h"
9#include "qevent.h"
10#include "qstyle.h"
11#include "qvariant.h"
12#include "qwidget_p.h"
13
15
16inline static QRect fromLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
17{
18 return rect.adjusted(priv->leftLayoutItemMargin, priv->topLayoutItemMargin,
19 -priv->rightLayoutItemMargin, -priv->bottomLayoutItemMargin);
20}
21
22inline static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
23{
24 return fromLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
25}
26
27inline static QRect toLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
28{
29 return rect.adjusted(-priv->leftLayoutItemMargin, -priv->topLayoutItemMargin,
30 priv->rightLayoutItemMargin, priv->bottomLayoutItemMargin);
31}
32
33inline static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
34{
35 return toLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
36}
37
38/*!
39 \class QLayoutItem
40 \brief The QLayoutItem class provides an abstract item that a
41 QLayout manipulates.
42
43 \ingroup geomanagement
44 \inmodule QtWidgets
45
46 This is used by custom layouts.
48 Pure virtual functions are provided to return information about
49 the layout, including, sizeHint(), minimumSize(), maximumSize()
50 and expandingDirections().
51
52 The layout's geometry can be set and retrieved with setGeometry()
53 and geometry(), and its alignment with setAlignment() and
54 alignment().
55
56 isEmpty() returns whether the layout item is empty. If the
57 concrete item is a QWidget, it can be retrieved using widget().
58 Similarly for layout() and spacerItem().
59
60 Some layouts have width and height interdependencies. These can
61 be expressed using hasHeightForWidth(), heightForWidth(), and
62 minimumHeightForWidth(). For more explanation see the \e{Qt
63 Quarterly} article
64 \l{http://doc.qt.io/archives/qq/qq04-height-for-width.html}{Trading
65 Height for Width}.
66
67 \sa QLayout
68*/
69
70/*!
71 \class QSpacerItem
72 \ingroup geomanagement
73 \brief The QSpacerItem class provides blank space in a layout.
74
75 \inmodule QtWidgets
76
77 Normally, you don't need to use this class directly. Qt's
78 built-in layout managers provide the following functions for
79 manipulating empty space in layouts:
80
81 \table
82 \header \li Class
83 \li Functions
84 \row \li QHBoxLayout
85 \li \l{QBoxLayout::addSpacing()}{addSpacing()},
86 \l{QBoxLayout::addStretch()}{addStretch()},
87 \l{QBoxLayout::insertSpacing()}{insertSpacing()},
88 \l{QBoxLayout::insertStretch()}{insertStretch()}
89 \row \li QGridLayout
90 \li \l{QGridLayout::setRowMinimumHeight()}{setRowMinimumHeight()},
91 \l{QGridLayout::setRowStretch()}{setRowStretch()},
92 \l{QGridLayout::setColumnMinimumWidth()}{setColumnMinimumWidth()},
93 \l{QGridLayout::setColumnStretch()}{setColumnStretch()}
94 \endtable
95
96 \sa QLayout, QWidgetItem, QLayoutItem::spacerItem()
97*/
98
99/*!
100 \class QWidgetItem
101 \ingroup geomanagement
102 \brief The QWidgetItem class is a layout item that represents a widget.
103
104 \inmodule QtWidgets
105
106 Normally, you don't need to use this class directly. Qt's
107 built-in layout managers provide the following functions for
108 manipulating widgets in layouts:
109
110 \table
111 \header \li Class
112 \li Functions
113 \row \li QBoxLayout
114 \li \l{QBoxLayout::addWidget()}{addWidget()},
115 \l{QBoxLayout::insertWidget()}{insertWidget()},
116 \l{QBoxLayout::setStretchFactor()}{setStretchFactor()}
117 \row \li QGridLayout
118 \li \l{QGridLayout::addWidget()}{addWidget()}
119 \row \li QStackedLayout
120 \li \l{QStackedLayout::addWidget()}{addWidget()},
121 \l{QStackedLayout::insertWidget()}{insertWidget()},
122 \l{QStackedLayout::currentWidget()}{currentWidget()},
123 \l{QStackedLayout::setCurrentWidget()}{setCurrentWidget()},
124 \l{QStackedLayout::widget()}{widget()}
125 \endtable
126
127 \sa QLayout, QSpacerItem, QLayoutItem::widget()
128*/
129
130/*!
131 \fn QLayoutItem::QLayoutItem(Qt::Alignment alignment)
132
133 Constructs a layout item with an \a alignment.
134 Not all subclasses support alignment.
135*/
136
137/*!
138 \fn Qt::Alignment QLayoutItem::alignment() const
139
140 Returns the alignment of this item.
141*/
142
143/*!
144 Sets the alignment of this item to \a alignment.
145
146 \b{Note:} Item alignment is only supported by QLayoutItem subclasses
147 where it would have a visual effect. Except for QSpacerItem, which provides
148 blank space for layouts, all public Qt classes that inherit QLayoutItem
149 support item alignment.
150*/
151void QLayoutItem::setAlignment(Qt::Alignment alignment)
152{
153 align = alignment;
154}
155
156/*!
157 \fn QSize QLayoutItem::maximumSize() const
158
159 Implemented in subclasses to return the maximum size of this item.
160*/
161
162/*!
163 \fn QSize QLayoutItem::minimumSize() const
164
165 Implemented in subclasses to return the minimum size of this item.
166*/
167
168/*!
169 \fn QSize QLayoutItem::sizeHint() const
170
171 Implemented in subclasses to return the preferred size of this item.
172*/
173
174/*!
175 \fn Qt::Orientations QLayoutItem::expandingDirections() const
176
177 Returns whether this layout item can make use of more space than
178 sizeHint(). A value of Qt::Vertical or Qt::Horizontal means that
179 it wants to grow in only one dimension, whereas Qt::Vertical |
180 Qt::Horizontal means that it wants to grow in both dimensions.
181*/
182
183/*!
184 \fn void QLayoutItem::setGeometry(const QRect &r)
185
186 Implemented in subclasses to set this item's geometry to \a r.
187
188 \sa geometry()
189*/
190
191/*!
192 \fn QRect QLayoutItem::geometry() const
193
194 Returns the rectangle covered by this layout item.
195
196 \sa setGeometry()
197*/
198
199/*!
200 \fn virtual bool QLayoutItem::isEmpty() const
201
202 Implemented in subclasses to return whether this item is empty,
203 i.e. whether it contains any widgets.
204*/
205
206/*!
207 \fn QSpacerItem::QSpacerItem(int w, int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy)
208
209 Constructs a spacer item with preferred width \a w, preferred
210 height \a h, horizontal size policy \a hPolicy and vertical size
211 policy \a vPolicy.
212
213 The default values provide a gap that is able to stretch if
214 nothing else wants the space.
215*/
216
217/*!
218 Destructor.
219*/
220QSpacerItem::~QSpacerItem() {}
221
222/*!
223 Changes this spacer item to have preferred width \a w, preferred
224 height \a h, horizontal size policy \a hPolicy and vertical size
225 policy \a vPolicy.
226
227 The default values provide a gap that is able to stretch if
228 nothing else wants the space.
229
230 Note that if changeSize() is called after the spacer item has been added
231 to a layout, it is necessary to invalidate the layout in order for the
232 spacer item's new size to take effect.
233
234 \sa QSpacerItem::invalidate()
235*/
236void QSpacerItem::changeSize(int w, int h, QSizePolicy::Policy hPolicy,
237 QSizePolicy::Policy vPolicy)
238{
239 width = w;
240 height = h;
241 sizeP = QSizePolicy(hPolicy, vPolicy);
242}
243
244/*!
245 \fn QWidgetItem::QWidgetItem(QWidget *widget)
246
247 Creates an item containing the given \a widget.
248*/
249
250/*!
251 Destructor.
252*/
253QWidgetItem::~QWidgetItem() = default;
254
255/*!
256 Destroys the QLayoutItem.
257*/
258QLayoutItem::~QLayoutItem() = default;
259
260/*!
261 Invalidates any cached information in this layout item.
262*/
263void QLayoutItem::invalidate()
264{
265}
266
267/*!
268 If this item is a QLayout, it is returned as a QLayout; otherwise
269 \nullptr is returned. This function provides type-safe casting.
270
271 \sa spacerItem(), widget()
272*/
273QLayout *QLayoutItem::layout()
274{
275 return nullptr;
276}
277
278/*!
279 If this item is a QSpacerItem, it is returned as a QSpacerItem;
280 otherwise \nullptr is returned. This function provides type-safe casting.
281
282 \sa layout(), widget()
283*/
284QSpacerItem *QLayoutItem::spacerItem()
285{
286 return nullptr;
287}
288
289/*!
290 \reimp
291*/
292QLayout * QLayout::layout()
293{
294 return this;
295}
296
297/*!
298 Returns a pointer to this object.
299*/
300QSpacerItem * QSpacerItem::spacerItem()
301{
302 return this;
303}
304
305/*!
306 \fn QSizePolicy QSpacerItem::sizePolicy() const
307 \since 5.5
308
309 Returns the size policy of this item.
310*/
311
312/*!
313 If this item manages a QWidget, returns that widget. Otherwise,
314 \nullptr is returned.
315
316 \note While the functions layout() and spacerItem() perform casts, this
317 function returns another object: QLayout and QSpacerItem inherit QLayoutItem,
318 while QWidget does not.
319
320 \sa layout(), spacerItem()
321*/
322QWidget *QLayoutItem::widget() const
323{
324 return nullptr;
325}
326
327/*!
328 Returns the widget managed by this item.
329*/
330QWidget *QWidgetItem::widget() const
331{
332 return wid;
333}
334
335/*!
336 Returns \c true if this layout's preferred height depends on its
337 width; otherwise returns \c false. The default implementation returns
338 false.
339
340 Reimplement this function in layout managers that support height
341 for width.
342
343 \sa heightForWidth(), QWidget::heightForWidth()
344*/
345bool QLayoutItem::hasHeightForWidth() const
346{
347 return false;
348}
349
350/*!
351 Returns the minimum height this widget needs for the given width,
352 \a w. The default implementation simply returns heightForWidth(\a
353 w).
354*/
355int QLayoutItem::minimumHeightForWidth(int w) const
356{
357 return heightForWidth(w);
358}
359
360
361/*!
362 Returns the preferred height for this layout item, given the
363 width, which is not used in this default implementation.
364
365 The default implementation returns -1, indicating that the
366 preferred height is independent of the width of the item. Using
367 the function hasHeightForWidth() will typically be much faster
368 than calling this function and testing for -1.
369
370 Reimplement this function in layout managers that support height
371 for width. A typical implementation will look like this:
372 \snippet code/src_gui_kernel_qlayoutitem.cpp 0
373
374 Caching is strongly recommended; without it layout will take
375 exponential time.
376
377 \sa hasHeightForWidth()
378*/
379int QLayoutItem::heightForWidth(int /* w */) const
380{
381 return -1;
382}
383
384/*!
385 Returns the control type(s) for the layout item. For a
386 QWidgetItem, the control type comes from the widget's size
387 policy; for a QLayoutItem, the control types is derived from the
388 layout's contents.
389
390 \sa QSizePolicy::controlType()
391*/
392QSizePolicy::ControlTypes QLayoutItem::controlTypes() const
393{
394 return QSizePolicy::DefaultType;
395}
396
397/*!
398 \reimp
399*/
400void QSpacerItem::setGeometry(const QRect &r)
401{
402 rect = r;
403}
404
405/*!
406 \reimp
407*/
408void QWidgetItem::setGeometry(const QRect &rect)
409{
410 if (isEmpty())
411 return;
412
413 QRect r = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
414 ? fromLayoutItemRect(wid->d_func(), rect)
415 : rect;
416 const QSize widgetRectSurplus = r.size() - rect.size();
417
418 /*
419 For historical reasons, this code is done using widget rect
420 coordinates, not layout item rect coordinates. However,
421 QWidgetItem's sizeHint(), maximumSize(), and heightForWidth()
422 all work in terms of layout item rect coordinates, so we have to
423 add or subtract widgetRectSurplus here and there. The code could
424 be much simpler if we did everything using layout item rect
425 coordinates and did the conversion right before the call to
426 QWidget::setGeometry().
427 */
428
429 QSize s = r.size().boundedTo(maximumSize() + widgetRectSurplus);
430 int x = r.x();
431 int y = r.y();
432 if (align & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask)) {
433 QSize pref(sizeHint());
434 QSizePolicy sp = wid->sizePolicy();
435 if (sp.horizontalPolicy() == QSizePolicy::Ignored)
436 pref.setWidth(wid->sizeHint().expandedTo(wid->minimumSize()).width());
437 if (sp.verticalPolicy() == QSizePolicy::Ignored)
438 pref.setHeight(wid->sizeHint().expandedTo(wid->minimumSize()).height());
439 pref += widgetRectSurplus;
440 if (align & Qt::AlignHorizontal_Mask)
441 s.setWidth(qMin(s.width(), pref.width()));
442 if (align & Qt::AlignVertical_Mask) {
443 if (hasHeightForWidth())
444 s.setHeight(qMin(s.height(),
445 heightForWidth(s.width() - widgetRectSurplus.width())
446 + widgetRectSurplus.height()));
447 else
448 s.setHeight(qMin(s.height(), pref.height()));
449 }
450 }
451 Qt::Alignment alignHoriz = QStyle::visualAlignment(wid->layoutDirection(), align);
452 if (alignHoriz & Qt::AlignRight)
453 x = x + (r.width() - s.width());
454 else if (!(alignHoriz & Qt::AlignLeft))
455 x = x + (r.width() - s.width()) / 2;
456
457 if (align & Qt::AlignBottom)
458 y = y + (r.height() - s.height());
459 else if (!(align & Qt::AlignTop))
460 y = y + (r.height() - s.height()) / 2;
461
462 wid->setGeometry(x, y, s.width(), s.height());
463}
464
465/*!
466 \reimp
467*/
468QRect QSpacerItem::geometry() const
469{
470 return rect;
471}
472
473/*!
474 \reimp
475*/
476QRect QWidgetItem::geometry() const
477{
478 return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
479 ? toLayoutItemRect(wid->d_func(), wid->geometry())
480 : wid->geometry();
481}
482
483
484/*!
485 \reimp
486*/
487bool QWidgetItem::hasHeightForWidth() const
488{
489 if (isEmpty())
490 return false;
491 return wid->hasHeightForWidth();
492}
493
494/*!
495 \reimp
496*/
497int QWidgetItem::heightForWidth(int w) const
498{
499 if (isEmpty())
500 return -1;
501
502 w = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
503 ? fromLayoutItemSize(wid->d_func(), QSize(w, 0)).width()
504 : w;
505
506 int hfw;
507 if (wid->layout())
508 hfw = wid->layout()->totalHeightForWidth(w);
509 else
510 hfw = wid->heightForWidth(w);
511
512 if (hfw > wid->maximumHeight())
513 hfw = wid->maximumHeight();
514 if (hfw < wid->minimumHeight())
515 hfw = wid->minimumHeight();
516
517 hfw = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
518 ? toLayoutItemSize(wid->d_func(), QSize(0, hfw)).height()
519 : hfw;
520
521 if (hfw < 0)
522 hfw = 0;
523 return hfw;
524}
525
526int QWidgetItem::minimumHeightForWidth(int w) const
527{
528 if (isEmpty())
529 return -1;
530
531 w = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
532 ? fromLayoutItemSize(wid->d_func(), QSize(w, 0)).width()
533 : w;
534
535 int hfw;
536 if (wid->layout())
537 hfw = wid->layout()->totalMinimumHeightForWidth(w);
538 else
539 hfw = wid->heightForWidth(w); // QWidget doesn't have minimumHeightForWidth()
540
541 if (hfw > wid->maximumHeight())
542 hfw = wid->maximumHeight();
543 if (hfw < wid->minimumHeight())
544 hfw = wid->minimumHeight();
545
546 hfw = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
547 ? toLayoutItemSize(wid->d_func(), QSize(0, hfw)).height()
548 : hfw;
549
550 if (hfw < 0)
551 hfw = 0;
552 return hfw;
553
554}
555
556/*!
557 \reimp
558*/
559Qt::Orientations QSpacerItem::expandingDirections() const
560{
561 return sizeP.expandingDirections();
562}
563
564/*!
565 \reimp
566*/
567Qt::Orientations QWidgetItem::expandingDirections() const
568{
569 if (isEmpty())
570 return {};
571
572 Qt::Orientations e = wid->sizePolicy().expandingDirections();
573 /*
574 If the layout is expanding, we make the widget expanding, even if
575 its own size policy isn't expanding.
576 */
577 if (wid->layout()) {
578 if (wid->sizePolicy().horizontalPolicy() & QSizePolicy::GrowFlag
579 && (wid->layout()->expandingDirections() & Qt::Horizontal))
580 e |= Qt::Horizontal;
581 if (wid->sizePolicy().verticalPolicy() & QSizePolicy::GrowFlag
582 && (wid->layout()->expandingDirections() & Qt::Vertical))
583 e |= Qt::Vertical;
584 }
585
586 if (align & Qt::AlignHorizontal_Mask)
587 e &= ~Qt::Horizontal;
588 if (align & Qt::AlignVertical_Mask)
589 e &= ~Qt::Vertical;
590 return e;
591}
592
593/*!
594 \reimp
595*/
596QSize QSpacerItem::minimumSize() const
597{
598 return QSize(sizeP.horizontalPolicy() & QSizePolicy::ShrinkFlag ? 0 : width,
599 sizeP.verticalPolicy() & QSizePolicy::ShrinkFlag ? 0 : height);
600}
601
602/*!
603 \reimp
604*/
605QSize QWidgetItem::minimumSize() const
606{
607 if (isEmpty())
608 return QSize(0, 0);
609 return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
610 ? toLayoutItemSize(wid->d_func(), qSmartMinSize(this))
611 : qSmartMinSize(this);
612}
613
614/*!
615 \reimp
616*/
617QSize QSpacerItem::maximumSize() const
618{
619 return QSize(sizeP.horizontalPolicy() & QSizePolicy::GrowFlag ? QLAYOUTSIZE_MAX : width,
620 sizeP.verticalPolicy() & QSizePolicy::GrowFlag ? QLAYOUTSIZE_MAX : height);
621}
622
623/*!
624 \reimp
625*/
626QSize QWidgetItem::maximumSize() const
627{
628 if (isEmpty()) {
629 return QSize(0, 0);
630 } else {
631 return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
632 ? toLayoutItemSize(wid->d_func(), qSmartMaxSize(this, align))
633 : qSmartMaxSize(this, align);
634 }
635}
636
637/*!
638 \reimp
639*/
640QSize QSpacerItem::sizeHint() const
641{
642 return QSize(width, height);
643}
644
645/*!
646 \reimp
647*/
648QSize QWidgetItem::sizeHint() const
649{
650 QSize s(0, 0);
651 if (!isEmpty()) {
652 s = wid->sizeHint().expandedTo(wid->minimumSizeHint());
653 s = s.boundedTo(wid->maximumSize())
654 .expandedTo(wid->minimumSize());
655 s = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
656 ? toLayoutItemSize(wid->d_func(), s)
657 : s;
658
659 if (wid->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored)
660 s.setWidth(0);
661 if (wid->sizePolicy().verticalPolicy() == QSizePolicy::Ignored)
662 s.setHeight(0);
663 }
664 return s;
665}
666
667/*!
668 Returns \c true.
669*/
670bool QSpacerItem::isEmpty() const
671{
672 return true;
673}
674
675/*!
676 Returns \c true if the widget is hidden; otherwise returns \c false.
677
678 \sa QWidget::isHidden()
679*/
680bool QWidgetItem::isEmpty() const
681{
682 return (wid->isHidden() && !wid->sizePolicy().retainSizeWhenHidden()) || wid->isWindow();
683}
684
685/*!
686 Returns the control type associated with the widget for which
687 this size policy applies.
688
689 \sa QSizePolicy::controlType()
690 */
691QSizePolicy::ControlTypes QWidgetItem::controlTypes() const
692{
693 return wid->sizePolicy().controlType();
694}
695
696/*!
697 \class QWidgetItemV2
698 \internal
699*/
700
701inline bool QWidgetItemV2::useSizeCache() const
702{
703 return wid->d_func()->widgetItem == this;
704}
705
706void QWidgetItemV2::updateCacheIfNecessary() const
707{
708 if (q_cachedMinimumSize.width() != Dirty)
709 return;
710
711 const QSize sizeHint(wid->sizeHint());
712 const QSize minimumSizeHint(wid->minimumSizeHint());
713 const QSize minimumSize(wid->minimumSize());
714 const QSize maximumSize(wid->maximumSize());
715 const QSizePolicy sizePolicy(wid->sizePolicy());
716 const QSize expandedSizeHint(sizeHint.expandedTo(minimumSizeHint));
717
718 const QSize smartMinSize(qSmartMinSize(sizeHint, minimumSizeHint, minimumSize, maximumSize, sizePolicy));
719 const QSize smartMaxSize(qSmartMaxSize(expandedSizeHint, minimumSize, maximumSize, sizePolicy, align));
720
721 const bool useLayoutItemRect = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect);
722
723 q_cachedMinimumSize = useLayoutItemRect
724 ? toLayoutItemSize(wid->d_func(), smartMinSize)
725 : smartMinSize;
726
727 q_cachedSizeHint = expandedSizeHint;
728 q_cachedSizeHint = q_cachedSizeHint.boundedTo(maximumSize)
729 .expandedTo(minimumSize);
730 q_cachedSizeHint = useLayoutItemRect
731 ? toLayoutItemSize(wid->d_func(), q_cachedSizeHint)
732 : q_cachedSizeHint;
733
734 if (wid->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored)
735 q_cachedSizeHint.setWidth(0);
736 if (wid->sizePolicy().verticalPolicy() == QSizePolicy::Ignored)
737 q_cachedSizeHint.setHeight(0);
738
739 q_cachedMaximumSize = useLayoutItemRect
740 ? toLayoutItemSize(wid->d_func(), smartMaxSize)
741 : smartMaxSize;
742}
743
744QWidgetItemV2::QWidgetItemV2(QWidget *widget)
745 : QWidgetItem(widget),
746 q_cachedMinimumSize(Dirty, Dirty),
747 q_cachedSizeHint(Dirty, Dirty),
748 q_cachedMaximumSize(Dirty, Dirty),
749 q_firstCachedHfw(0),
750 q_hfwCacheSize(0),
751 d(nullptr)
752{
753 QWidgetPrivate *wd = wid->d_func();
754 if (!wd->widgetItem)
755 wd->widgetItem = this;
756}
757
758QWidgetItemV2::~QWidgetItemV2()
759{
760 if (wid) {
761 auto *wd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(wid));
762 if (wd->widgetItem == this)
763 wd->widgetItem = nullptr;
764 }
765}
766
767QSize QWidgetItemV2::sizeHint() const
768{
769 if (isEmpty())
770 return QSize(0, 0);
771
772 if (useSizeCache()) {
773 updateCacheIfNecessary();
774 return q_cachedSizeHint;
775 } else {
776 return QWidgetItem::sizeHint();
777 }
778}
779
780QSize QWidgetItemV2::minimumSize() const
781{
782 if (isEmpty())
783 return QSize(0, 0);
784
785 if (useSizeCache()) {
786 updateCacheIfNecessary();
787 return q_cachedMinimumSize;
788 } else {
789 return QWidgetItem::minimumSize();
790 }
791}
792
793QSize QWidgetItemV2::maximumSize() const
794{
795 if (isEmpty())
796 return QSize(0, 0);
797
798 if (useSizeCache()) {
799 updateCacheIfNecessary();
800 return q_cachedMaximumSize;
801 } else {
802 return QWidgetItem::maximumSize();
803 }
804}
805
806/*
807 The height-for-width cache is organized as a circular buffer. The entries
808
809 q_hfwCachedHfws[q_firstCachedHfw],
810 ...,
811 q_hfwCachedHfws[(q_firstCachedHfw + q_hfwCacheSize - 1) % HfwCacheMaxSize]
812
813 contain the last cached values. When the cache is full, the first entry to
814 be erased is the entry before q_hfwCachedHfws[q_firstCachedHfw]. When
815 values are looked up, we try to move q_firstCachedHfw to point to that new
816 entry (unless the cache is not full, in which case it would leave the cache
817 in a broken state), so that the most recently used entry is also the last
818 to be erased.
819*/
820
821int QWidgetItemV2::heightForWidth(int width) const
822{
823 if (isEmpty())
824 return -1;
825
826 for (int i = 0; i < q_hfwCacheSize; ++i) {
827 int offset = q_firstCachedHfw + i;
828 const QSize &size = q_cachedHfws[offset % HfwCacheMaxSize];
829 if (size.width() == width) {
830 if (q_hfwCacheSize == HfwCacheMaxSize)
831 q_firstCachedHfw = offset % HfwCacheMaxSize;
832 return size.height();
833 }
834 }
835
836 if (q_hfwCacheSize < HfwCacheMaxSize)
837 ++q_hfwCacheSize;
838 q_firstCachedHfw = (q_firstCachedHfw + HfwCacheMaxSize - 1) % HfwCacheMaxSize;
839
840 int height = QWidgetItem::heightForWidth(width);
841 q_cachedHfws[q_firstCachedHfw] = QSize(width, height);
842 return height;
843}
844
845QT_END_NAMESPACE
Combined button and popup list for selecting options.
static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
static QT_BEGIN_NAMESPACE QRect fromLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
static QRect toLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size)