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

source code of qtbase/src/widgets/graphicsview/qgraphicslayoutitem.cpp