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
qgraphicslayoutitem.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 "qglobal.h"
6
11#include "qwidget.h"
14
15#include <QtDebug>
16
18
19/*
20 COMBINE_SIZE() is identical to combineSize(), except that it
21 doesn't evaluate 'size' unless necessary.
22*/
23#define COMBINE_SIZE(result, size)
24 do {
25 if ((result).width() < 0 || (result).height() < 0)
26 combineSize((result), (size));
27 } while (false)
28
29static void combineSize(QSizeF &result, const QSizeF &size)
30{
31 if (result.width() < 0)
32 result.setWidth(size.width());
33 if (result.height() < 0)
34 result.setHeight(size.height());
35}
36
37static void boundSize(QSizeF &result, const QSizeF &size)
38{
39 if (size.width() >= 0 && size.width() < result.width())
40 result.setWidth(size.width());
41 if (size.height() >= 0 && size.height() < result.height())
42 result.setHeight(size.height());
43}
44
45static void expandSize(QSizeF &result, const QSizeF &size)
46{
47 if (size.width() >= 0 && size.width() > result.width())
48 result.setWidth(size.width());
49 if (size.height() >= 0 && size.height() > result.height())
50 result.setHeight(size.height());
51}
52
53static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent)
54{
55 if (minimum >= 0 && maximum >= 0 && minimum > maximum)
56 minimum = maximum;
57
58 if (preferred >= 0) {
59 if (minimum >= 0 && preferred < minimum) {
60 preferred = minimum;
61 } else if (maximum >= 0 && preferred > maximum) {
62 preferred = maximum;
63 }
64 }
65
66 if (minimum >= 0 && descent > minimum)
67 descent = minimum;
68}
69
70/*!
71 \internal
72*/
73QGraphicsLayoutItemPrivate::QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *par, bool layout)
74 : parent(par), userSizeHints(nullptr), isLayout(layout), ownedByLayout(false), graphicsItem(nullptr)
75{
76}
77
78/*!
79 \internal
80*/
81QGraphicsLayoutItemPrivate::~QGraphicsLayoutItemPrivate()
82{
83 // Remove any lazily allocated data
84 delete[] userSizeHints;
85}
86
87/*!
88 \internal
89*/
90void QGraphicsLayoutItemPrivate::init()
91{
92 sizeHintCacheDirty = true;
93 sizeHintWithConstraintCacheDirty = true;
94}
95
96/*!
97 \internal
98*/
99QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint) const
100{
101 Q_Q(const QGraphicsLayoutItem);
102 QSizeF *sizeHintCache;
103 const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0;
104 if (hasConstraint) {
105 if (!sizeHintWithConstraintCacheDirty && constraint == cachedConstraint)
106 return cachedSizeHintsWithConstraints;
107 sizeHintCache = cachedSizeHintsWithConstraints;
108 } else {
109 if (!sizeHintCacheDirty)
110 return cachedSizeHints;
111 sizeHintCache = cachedSizeHints;
112 }
113
114 for (int i = 0; i < Qt::NSizeHints; ++i) {
115 sizeHintCache[i] = constraint;
116 if (userSizeHints)
117 combineSize(sizeHintCache[i], userSizeHints[i]);
118 }
119
120 QSizeF &minS = sizeHintCache[Qt::MinimumSize];
121 QSizeF &prefS = sizeHintCache[Qt::PreferredSize];
122 QSizeF &maxS = sizeHintCache[Qt::MaximumSize];
123 QSizeF &descentS = sizeHintCache[Qt::MinimumDescent];
124
125 normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
126 normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
127
128 // if the minimum, preferred and maximum sizes contradict each other
129 // (e.g. the minimum is larger than the maximum) we give priority to
130 // the maximum size, then the minimum size and finally the preferred size
131 COMBINE_SIZE(maxS, q->sizeHint(Qt::MaximumSize, maxS));
132 combineSize(maxS, QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
133 expandSize(maxS, prefS);
134 expandSize(maxS, minS);
135 boundSize(maxS, QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
136
137 COMBINE_SIZE(minS, q->sizeHint(Qt::MinimumSize, minS));
138 expandSize(minS, QSizeF(0, 0));
139 boundSize(minS, prefS);
140 boundSize(minS, maxS);
141
142 COMBINE_SIZE(prefS, q->sizeHint(Qt::PreferredSize, prefS));
143 expandSize(prefS, minS);
144 boundSize(prefS, maxS);
145
146 // Not supported yet
147 // COMBINE_SIZE(descentS, q->sizeHint(Qt::MinimumDescent, constraint));
148
149 if (hasConstraint) {
150 cachedConstraint = constraint;
151 sizeHintWithConstraintCacheDirty = false;
152 } else {
153 sizeHintCacheDirty = false;
154 }
155 return sizeHintCache;
156}
157
158
159/*!
160 \internal
161
162 Returns the parent item of this layout, or \nullptr if this layout is
163 not installed on any widget.
164
165 If this is the item that the layout is installed on, it will return "itself".
166
167 If the layout is a sub-layout, this function returns the parent
168 widget of the parent layout.
169
170 Note that it will traverse up the layout item hierarchy instead of just calling
171 QGraphicsItem::parentItem(). This is on purpose.
172
173 \sa parent()
174*/
175QGraphicsItem *QGraphicsLayoutItemPrivate::parentItem() const
176{
177 Q_Q(const QGraphicsLayoutItem);
178
179 const QGraphicsLayoutItem *parent = q;
180 while (parent && parent->isLayout()) {
181 parent = parent->parentLayoutItem();
182 }
183 return parent ? parent->graphicsItem() : nullptr;
184}
185
186/*!
187 \internal
188
189 Ensures that userSizeHints is allocated.
190 This function must be called before any dereferencing.
191*/
192void QGraphicsLayoutItemPrivate::ensureUserSizeHints()
193{
194 if (!userSizeHints)
195 userSizeHints = new QSizeF[Qt::NSizeHints];
196}
197
198/*!
199 \internal
200
201 Sets the user size hint \a which to \a size. Use an invalid size to unset the size hint.
202 */
203void QGraphicsLayoutItemPrivate::setSize(Qt::SizeHint which, const QSizeF &size)
204{
205 Q_Q(QGraphicsLayoutItem);
206
207 if (userSizeHints) {
208 if (size == userSizeHints[which])
209 return;
210 } else if (size.width() < 0 && size.height() < 0) {
211 return;
212 }
213
214 ensureUserSizeHints();
215 userSizeHints[which] = size;
216 q->updateGeometry();
217}
218
219/*!
220 \internal
221
222 Sets the width of the user size hint \a which to \a width.
223 */
224void QGraphicsLayoutItemPrivate::setSizeComponent(
225 Qt::SizeHint which, SizeComponent component, qreal value)
226{
227 Q_Q(QGraphicsLayoutItem);
228 ensureUserSizeHints();
229 qreal &userValue = (component == Width)
230 ? userSizeHints[which].rwidth()
231 : userSizeHints[which].rheight();
232 if (value == userValue)
233 return;
234 userValue = value;
235 q->updateGeometry();
236}
237
238
239bool QGraphicsLayoutItemPrivate::hasHeightForWidth() const
240{
241 Q_Q(const QGraphicsLayoutItem);
242 if (isLayout) {
243 const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
244 for (int i = l->count() - 1; i >= 0; --i) {
245 if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasHeightForWidth())
246 return true;
247 }
248 } else if (QGraphicsItem *item = q->graphicsItem()) {
249 if (item->isWidget()) {
250 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
251 if (w->layout()) {
252 return QGraphicsLayoutItemPrivate::get(w->layout())->hasHeightForWidth();
253 }
254 }
255 }
256 return q->sizePolicy().hasHeightForWidth();
257}
258
259bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const
260{
261 Q_Q(const QGraphicsLayoutItem);
262 if (isLayout) {
263 const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
264 for (int i = l->count() - 1; i >= 0; --i) {
265 if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasWidthForHeight())
266 return true;
267 }
268 } else if (QGraphicsItem *item = q->graphicsItem()) {
269 if (item->isWidget()) {
270 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
271 if (w->layout()) {
272 return QGraphicsLayoutItemPrivate::get(w->layout())->hasWidthForHeight();
273 }
274 }
275 }
276 return q->sizePolicy().hasWidthForHeight();
277}
278
279/*!
280 \class QGraphicsLayoutItem
281 \brief The QGraphicsLayoutItem class can be inherited to allow your custom
282 items to be managed by layouts.
283 \since 4.4
284 \ingroup graphicsview-api
285 \inmodule QtWidgets
286
287 QGraphicsLayoutItem is an abstract class that defines a set of virtual
288 functions describing sizes, size policies, and size hints for any object
289 arranged by QGraphicsLayout. The API contains functions relevant
290 for both the item itself and for the user of the item as most of
291 QGraphicsLayoutItem's functions are also part of the subclass' public API.
292
293 In most cases, existing layout-aware classes such as QGraphicsWidget and
294 QGraphicsLayout already provide the functionality you require. However,
295 subclassing these classes will enable you to create both graphical
296 elements that work well with layouts (QGraphicsWidget) or custom layouts
297 (QGraphicsLayout).
298
299 \section1 Subclassing QGraphicsLayoutItem
300
301 If you create a subclass of QGraphicsLayoutItem and reimplement its
302 virtual functions, you will enable the layout to resize and position your
303 item along with other QGraphicsLayoutItems including QGraphicsWidget
304 and QGraphicsLayout.
305
306 You can start by reimplementing important functions: the protected
307 sizeHint() function, as well as the public setGeometry()
308 function. If you want your items to be aware of immediate geometry
309 changes, you can also reimplement updateGeometry().
310
311 The geometry, size hint, and size policy affect the item's size and
312 position. Calling setGeometry() will always resize and reposition the item
313 immediately. Normally, this function is called by QGraphicsLayout after
314 the layout has been activated, but it can also be called by the item's user
315 at any time.
316
317 The sizeHint() function returns the item' minimum, preferred and maximum
318 size hints. You can override these properties by calling setMinimumSize(),
319 setPreferredSize() or setMaximumSize(). You can also use functions such as
320 setMinimumWidth() or setMaximumHeight() to set only the width or height
321 component if desired.
322
323 The effectiveSizeHint() function, on the other hand, returns a size hint
324 for any given Qt::SizeHint, and guarantees that the returned size is bound
325 to the minimum and maximum sizes and size hints. You can set the item's
326 vertical and horizontal size policy by calling setSizePolicy(). The
327 sizePolicy property is used by the layout system to describe how this item
328 prefers to grow or shrink.
329
330 \section1 Nesting QGraphicsLayoutItems
331
332 QGraphicsLayoutItems can be nested within other QGraphicsLayoutItems,
333 similar to layouts that can contain sublayouts. This is done either by
334 passing a QGraphicsLayoutItem pointer to QGraphicsLayoutItem's
335 protected constructor, or by calling setParentLayoutItem(). The
336 parentLayoutItem() function returns a pointer to the item's layoutItem
337 parent. If the item's parent is \nullptr or if the parent does not inherit
338 from QGraphicsItem, the parentLayoutItem() function then returns \nullptr.
339 isLayout() returns \c true if the QGraphicsLayoutItem subclass is itself a
340 layout, or false otherwise.
341
342 Qt uses QGraphicsLayoutItem to provide layout functionality in the
343 \l{Graphics View Framework}, but in the future its use may spread
344 throughout Qt itself.
345
346 \sa QGraphicsWidget, QGraphicsLayout, QGraphicsLinearLayout,
347 QGraphicsGridLayout
348*/
349
350/*!
351 Constructs the QGraphicsLayoutItem object. \a parent becomes the object's
352 parent. If \a isLayout is true the item is a layout, otherwise
353 \a isLayout is false.
354*/
355QGraphicsLayoutItem::QGraphicsLayoutItem(QGraphicsLayoutItem *parent, bool isLayout)
356 : d_ptr(new QGraphicsLayoutItemPrivate(parent, isLayout))
357{
358 Q_D(QGraphicsLayoutItem);
359 d->init();
360 d->sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
361 d->q_ptr = this;
362}
363
364/*!
365 \internal
366*/
367QGraphicsLayoutItem::QGraphicsLayoutItem(QGraphicsLayoutItemPrivate &dd)
368 : d_ptr(&dd)
369{
370 Q_D(QGraphicsLayoutItem);
371 d->init();
372 d->q_ptr = this;
373}
374
375/*!
376 Destroys the QGraphicsLayoutItem object.
377*/
378QGraphicsLayoutItem::~QGraphicsLayoutItem()
379{
380 QGraphicsLayoutItem *parentLI = parentLayoutItem();
381 if (parentLI && parentLI->isLayout()) {
382 QGraphicsLayout *lay = static_cast<QGraphicsLayout*>(parentLI);
383 // this is not optimal
384 for (int i = lay->count() - 1; i >= 0; --i) {
385 if (lay->itemAt(i) == this) {
386 lay->removeAt(i);
387 break;
388 }
389 }
390 }
391}
392
393/*!
394 \fn virtual QSizeF QGraphicsLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const = 0;
395
396 This pure virtual function returns the size hint for \a which of the
397 QGraphicsLayoutItem, using the width or height of \a constraint to
398 constrain the output.
399
400 Reimplement this function in a subclass of QGraphicsLayoutItem to
401 provide the necessary size hints for your items.
402
403 \sa effectiveSizeHint()
404*/
405
406/*!
407 Sets the size policy to \a policy. The size policy describes how the item
408 should grow horizontally and vertically when arranged in a layout.
409
410 QGraphicsLayoutItem's default size policy is (QSizePolicy::Fixed,
411 QSizePolicy::Fixed, QSizePolicy::DefaultType), but it is common for
412 subclasses to change the default. For example, QGraphicsWidget defaults
413 to (QSizePolicy::Preferred, QSizePolicy::Preferred,
414 QSizePolicy::DefaultType).
415
416 \sa sizePolicy(), QWidget::sizePolicy()
417*/
418void QGraphicsLayoutItem::setSizePolicy(const QSizePolicy &policy)
419{
420 Q_D(QGraphicsLayoutItem);
421 if (d->sizePolicy == policy)
422 return;
423 d->sizePolicy = policy;
424 updateGeometry();
425}
426
427/*!
428 \overload
429
430 This function is equivalent to calling
431 setSizePolicy(QSizePolicy(\a hPolicy, \a vPolicy, \a controlType)).
432
433 \sa sizePolicy(), QWidget::sizePolicy()
434*/
435void QGraphicsLayoutItem::setSizePolicy(QSizePolicy::Policy hPolicy,
436 QSizePolicy::Policy vPolicy,
437 QSizePolicy::ControlType controlType)
438{
439 setSizePolicy(QSizePolicy(hPolicy, vPolicy, controlType));
440}
441
442/*!
443 Returns the current size policy.
444
445 \sa setSizePolicy(), QWidget::sizePolicy()
446*/
447QSizePolicy QGraphicsLayoutItem::sizePolicy() const
448{
449 Q_D(const QGraphicsLayoutItem);
450 return d->sizePolicy;
451}
452
453/*!
454 Sets the minimum size to \a size. This property overrides sizeHint() for
455 Qt::MinimumSize and ensures that effectiveSizeHint() will never return
456 a size smaller than \a size. In order to unset the minimum size, use an
457 invalid size.
458
459 \sa minimumSize(), maximumSize(), preferredSize(), Qt::MinimumSize,
460 sizeHint(), setMinimumWidth(), setMinimumHeight()
461*/
462void QGraphicsLayoutItem::setMinimumSize(const QSizeF &size)
463{
464 d_ptr->setSize(Qt::MinimumSize, size);
465}
466
467/*!
468 \fn QGraphicsLayoutItem::setMinimumSize(qreal w, qreal h)
469
470 This convenience function is equivalent to calling
471 setMinimumSize(QSizeF(\a w, \a h)).
472
473 \sa minimumSize(), setMaximumSize(), setPreferredSize(), sizeHint()
474*/
475
476/*!
477 Returns the minimum size.
478
479 \sa setMinimumSize(), preferredSize(), maximumSize(), Qt::MinimumSize,
480 sizeHint()
481*/
482QSizeF QGraphicsLayoutItem::minimumSize() const
483{
484 return effectiveSizeHint(Qt::MinimumSize);
485}
486
487/*!
488 Sets the minimum width to \a width.
489
490 \sa minimumWidth(), setMinimumSize(), minimumSize()
491*/
492void QGraphicsLayoutItem::setMinimumWidth(qreal width)
493{
494 d_ptr->setSizeComponent(Qt::MinimumSize, d_ptr->Width, width);
495}
496
497/*!
498 Sets the minimum height to \a height.
499
500 \sa minimumHeight(), setMinimumSize(), minimumSize()
501*/
502void QGraphicsLayoutItem::setMinimumHeight(qreal height)
503{
504 d_ptr->setSizeComponent(Qt::MinimumSize, d_ptr->Height, height);
505}
506
507
508/*!
509 Sets the preferred size to \a size. This property overrides sizeHint() for
510 Qt::PreferredSize and provides the default value for effectiveSizeHint().
511 In order to unset the preferred size, use an invalid size.
512
513 \sa preferredSize(), minimumSize(), maximumSize(), Qt::PreferredSize,
514 sizeHint()
515*/
516void QGraphicsLayoutItem::setPreferredSize(const QSizeF &size)
517{
518 d_ptr->setSize(Qt::PreferredSize, size);
519}
520
521/*!
522 \fn QGraphicsLayoutItem::setPreferredSize(qreal w, qreal h)
523
524 This convenience function is equivalent to calling
525 setPreferredSize(QSizeF(\a w, \a h)).
526
527 \sa preferredSize(), setMaximumSize(), setMinimumSize(), sizeHint()
528*/
529
530/*!
531 Returns the preferred size.
532
533 \sa setPreferredSize(), minimumSize(), maximumSize(), Qt::PreferredSize,
534 sizeHint()
535*/
536QSizeF QGraphicsLayoutItem::preferredSize() const
537{
538 return effectiveSizeHint(Qt::PreferredSize);
539}
540
541/*!
542 Sets the preferred height to \a height.
543
544 \sa preferredWidth(), setPreferredSize(), preferredSize()
545*/
546void QGraphicsLayoutItem::setPreferredHeight(qreal height)
547{
548 d_ptr->setSizeComponent(Qt::PreferredSize, d_ptr->Height, height);
549}
550
551/*!
552 Sets the preferred width to \a width.
553
554 \sa preferredHeight(), setPreferredSize(), preferredSize()
555*/
556void QGraphicsLayoutItem::setPreferredWidth(qreal width)
557{
558 d_ptr->setSizeComponent(Qt::PreferredSize, d_ptr->Width, width);
559}
560
561/*!
562 Sets the maximum size to \a size. This property overrides sizeHint() for
563 Qt::MaximumSize and ensures that effectiveSizeHint() will never return a
564 size larger than \a size. In order to unset the maximum size, use an
565 invalid size.
566
567 \sa maximumSize(), minimumSize(), preferredSize(), Qt::MaximumSize,
568 sizeHint()
569*/
570void QGraphicsLayoutItem::setMaximumSize(const QSizeF &size)
571{
572 d_ptr->setSize(Qt::MaximumSize, size);
573}
574
575/*!
576 \fn QGraphicsLayoutItem::setMaximumSize(qreal w, qreal h)
577
578 This convenience function is equivalent to calling
579 setMaximumSize(QSizeF(\a w, \a h)).
580
581 \sa maximumSize(), setMinimumSize(), setPreferredSize(), sizeHint()
582*/
583
584/*!
585 Returns the maximum size.
586
587 \sa setMaximumSize(), minimumSize(), preferredSize(), Qt::MaximumSize,
588 sizeHint()
589*/
590QSizeF QGraphicsLayoutItem::maximumSize() const
591{
592 return effectiveSizeHint(Qt::MaximumSize);
593}
594
595/*!
596 Sets the maximum width to \a width.
597
598 \sa maximumWidth(), setMaximumSize(), maximumSize()
599*/
600void QGraphicsLayoutItem::setMaximumWidth(qreal width)
601{
602 d_ptr->setSizeComponent(Qt::MaximumSize, d_ptr->Width, width);
603}
604
605/*!
606 Sets the maximum height to \a height.
607
608 \sa maximumHeight(), setMaximumSize(), maximumSize()
609*/
610void QGraphicsLayoutItem::setMaximumHeight(qreal height)
611{
612 d_ptr->setSizeComponent(Qt::MaximumSize, d_ptr->Height, height);
613}
614
615/*!
616 \fn qreal QGraphicsLayoutItem::minimumWidth() const
617
618 Returns the minimum width.
619
620 \sa setMinimumWidth(), setMinimumSize(), minimumSize()
621*/
622
623/*!
624 \fn qreal QGraphicsLayoutItem::minimumHeight() const
625
626 Returns the minimum height.
627
628 \sa setMinimumHeight(), setMinimumSize(), minimumSize()
629*/
630
631/*!
632 \fn qreal QGraphicsLayoutItem::preferredWidth() const
633
634 Returns the preferred width.
635
636 \sa setPreferredWidth(), setPreferredSize(), preferredSize()
637*/
638
639/*!
640 \fn qreal QGraphicsLayoutItem::preferredHeight() const
641
642 Returns the preferred height.
643
644 \sa setPreferredHeight(), setPreferredSize(), preferredSize()
645*/
646
647/*!
648 \fn qreal QGraphicsLayoutItem::maximumWidth() const
649
650 Returns the maximum width.
651
652 \sa setMaximumWidth(), setMaximumSize(), maximumSize()
653*/
654
655/*!
656 \fn qreal QGraphicsLayoutItem::maximumHeight() const
657
658 Returns the maximum height.
659
660 \sa setMaximumHeight(), setMaximumSize(), maximumSize()
661*/
662
663/*!
664 \fn virtual void QGraphicsLayoutItem::setGeometry(const QRectF &rect)
665
666 This virtual function sets the geometry of the QGraphicsLayoutItem to
667 \a rect, which is in parent coordinates (e.g., the top-left corner of \a rect
668 is equivalent to the item's position in parent coordinates).
669
670 You must reimplement this function in a subclass of QGraphicsLayoutItem to
671 receive geometry updates. The layout will call this function when it does a
672 rearrangement.
673
674 If \a rect is outside of the bounds of minimumSize and maximumSize, it
675 will be adjusted to its closest size so that it is within the legal
676 bounds.
677
678 \sa geometry()
679*/
680void QGraphicsLayoutItem::setGeometry(const QRectF &rect)
681{
682 Q_D(QGraphicsLayoutItem);
683 QSizeF effectiveSize = rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
684 .boundedTo(effectiveSizeHint(Qt::MaximumSize));
685 d->geom = QRectF(rect.topLeft(), effectiveSize);
686}
687
688/*!
689 \fn QRectF QGraphicsLayoutItem::geometry() const
690
691 Returns the item's geometry (e.g., position and size) as a
692 QRectF. This function is equivalent to QRectF(pos(), size()).
693
694 \sa setGeometry()
695*/
696QRectF QGraphicsLayoutItem::geometry() const
697{
698 Q_D(const QGraphicsLayoutItem);
699 return d->geom;
700}
701
702/*!
703 This virtual function provides the \a left, \a top, \a right and \a bottom
704 contents margins for this QGraphicsLayoutItem. The default implementation
705 assumes all contents margins are 0. The parameters point to values stored
706 in qreals. If any of the pointers is \nullptr, that value will not be updated.
707
708 \sa QGraphicsWidget::setContentsMargins()
709*/
710void QGraphicsLayoutItem::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
711{
712 if (left)
713 *left = 0;
714 if (top)
715 *top = 0;
716 if (right)
717 *right = 0;
718 if (bottom)
719 *bottom = 0;
720}
721
722/*!
723 Returns the contents rect in local coordinates.
724
725 The contents rect defines the subrectangle used by an associated layout
726 when arranging subitems. This function is a convenience function that
727 adjusts the item's geometry() by its contents margins. Note that
728 getContentsMargins() is a virtual function that you can reimplement to
729 return the item's contents margins.
730
731 \sa getContentsMargins(), geometry()
732*/
733QRectF QGraphicsLayoutItem::contentsRect() const
734{
735 qreal left, top, right, bottom;
736 getContentsMargins(&left, &top, &right, &bottom);
737 return QRectF(QPointF(), geometry().size()).adjusted(+left, +top, -right, -bottom);
738}
739
740/*!
741 Returns the effective size hint for this QGraphicsLayoutItem.
742
743 \a which is the size hint in question.
744 \a constraint is an optional argument that defines a special constrain
745 when calculating the effective size hint. By default, \a constraint is
746 QSizeF(-1, -1), which means there is no constraint to the size hint.
747
748 If you want to specify the widget's size hint for a given width or height,
749 you can provide the fixed dimension in \a constraint. This is useful for
750 widgets that can grow only either vertically or horizontally, and need to
751 set either their width or their height to a special value.
752
753 For example, a text paragraph item fit into a column width of 200 may
754 grow vertically. You can pass QSizeF(200, -1) as a constraint to get a
755 suitable minimum, preferred and maximum height).
756
757 You can adjust the effective size hint by reimplementing sizeHint()
758 in a QGraphicsLayoutItem subclass, or by calling one of the following
759 functions: setMinimumSize(), setPreferredSize, or setMaximumSize()
760 (or a combination of both).
761
762 This function caches each of the size hints and guarantees that
763 sizeHint() will be called only once for each value of \a which - unless
764 \a constraint is not specified and updateGeometry() has been called.
765
766 \sa sizeHint()
767*/
768QSizeF QGraphicsLayoutItem::effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint) const
769{
770 Q_D(const QGraphicsLayoutItem);
771
772 if (!d->userSizeHints && constraint.isValid())
773 return constraint;
774
775 // ### should respect size policy???
776 return d_ptr->effectiveSizeHints(constraint)[which];
777}
778
779/*!
780 This virtual function discards any cached size hint information. You
781 should always call this function if you change the return value of the
782 sizeHint() function. Subclasses must always call the base implementation
783 when reimplementing this function.
784
785 \sa effectiveSizeHint()
786*/
787void QGraphicsLayoutItem::updateGeometry()
788{
789 Q_D(QGraphicsLayoutItem);
790 d->sizeHintCacheDirty = true;
791 d->sizeHintWithConstraintCacheDirty = true;
792}
793
794/*!
795 \since 6.0
796
797 Returns \c true if this item is empty, i.e whether it has no content and
798 should not occupy any space.
799
800 The default implementation returns \c true true if the item has been hidden,
801 unless its \l{sizePolicy()}{size policy} has retainSizeWhenHidden set to \c true
802
803 \sa sizePolicy()
804*/
805bool QGraphicsLayoutItem::isEmpty() const
806{
807 bool isHidden = false;
808 if (QGraphicsItem *item = graphicsItem())
809 isHidden = QGraphicsItemPrivate::get(item)->explicitlyHidden;
810
811 return isHidden && !sizePolicy().retainSizeWhenHidden();
812}
813
814/*!
815 Returns the parent of this QGraphicsLayoutItem, or \nullptr if there is
816 no parent, or if the parent does not inherit from QGraphicsLayoutItem
817 (QGraphicsLayoutItem is often used through multiple inheritance with
818 QObject-derived classes).
819
820 \sa setParentLayoutItem()
821*/
822QGraphicsLayoutItem *QGraphicsLayoutItem::parentLayoutItem() const
823{
824 return d_func()->parent;
825}
826
827/*!
828 Sets the parent of this QGraphicsLayoutItem to \a parent.
829
830 \sa parentLayoutItem()
831*/
832void QGraphicsLayoutItem::setParentLayoutItem(QGraphicsLayoutItem *parent)
833{
834 d_func()->parent = parent;
835}
836
837/*!
838 Returns \c true if this QGraphicsLayoutItem is a layout (e.g., is inherited
839 by an object that arranges other QGraphicsLayoutItem objects); otherwise
840 returns \c false.
841
842 \sa QGraphicsLayout
843*/
844bool QGraphicsLayoutItem::isLayout() const
845{
846 return d_func()->isLayout;
847}
848
849/*!
850 \since 4.6
851
852 Returns whether a layout should delete this item in its destructor.
853 If its true, then the layout will delete it. If its false, then it is
854 assumed that another object has the ownership of it, and the layout won't
855 delete this item.
856
857 If the item inherits both QGraphicsItem and QGraphicsLayoutItem (such
858 as QGraphicsWidget does) the item is really part of two ownership
859 hierarchies. This property informs what the layout should do with its
860 child items when it is destructed. In the case of QGraphicsWidget, it
861 is preferred that when the layout is deleted it won't delete its children
862 (since they are also part of the graphics item hierarchy).
863
864 By default this value is initialized to false in QGraphicsLayoutItem,
865 but it is overridden by QGraphicsLayout to return true. This is because
866 QGraphicsLayout is not normally part of the QGraphicsItem hierarchy, so the
867 parent layout should delete it.
868 Subclasses might override this default behaviour by calling
869 setOwnedByLayout(true).
870
871 \sa setOwnedByLayout()
872*/
873bool QGraphicsLayoutItem::ownedByLayout() const
874{
875 return d_func()->ownedByLayout;
876}
877/*!
878 \since 4.6
879
880 Sets whether a layout should delete this item in its destructor or not.
881 \a ownership must be true to in order for the layout to delete it.
882 \sa ownedByLayout()
883*/
884void QGraphicsLayoutItem::setOwnedByLayout(bool ownership)
885{
886 d_func()->ownedByLayout = ownership;
887}
888
889/*!
890 * Returns the QGraphicsItem that this layout item represents.
891 * For QGraphicsWidget it will return itself. For custom items it can return an
892 * aggregated value.
893 *
894 * \sa setGraphicsItem()
895 */
896QGraphicsItem *QGraphicsLayoutItem::graphicsItem() const
897{
898 return d_func()->graphicsItem;
899}
900
901/*!
902 * If the QGraphicsLayoutItem represents a QGraphicsItem, and it wants to take
903 * advantage of the automatic reparenting capabilities of QGraphicsLayout it
904 * should set this value.
905 * Note that if you delete \a item and not delete the layout item, you are
906 * responsible of calling setGraphicsItem(\nullptr) in order to avoid having a
907 * dangling pointer.
908 *
909 * \sa graphicsItem()
910 */
911void QGraphicsLayoutItem::setGraphicsItem(QGraphicsItem *item)
912{
913 d_func()->graphicsItem = item;
914}
915
916QT_END_NAMESPACE
#define COMBINE_SIZE(result, size)
static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent)
static void boundSize(QSizeF &result, const QSizeF &size)
static void combineSize(QSizeF &result, const QSizeF &size)
static void expandSize(QSizeF &result, const QSizeF &size)
#define QWIDGETSIZE_MAX
Definition qwidget.h:922