QtBase  v6.3.1
qgraphicslayoutitem.cpp
Go to the documentation of this file.
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 #include "qgraphicsitem_p.h"
49 
50 #include <QtDebug>
51 
53 
54 /*
55  COMBINE_SIZE() is identical to combineSize(), except that it
56  doesn't evaluate 'size' unless necessary.
57 */
58 #define COMBINE_SIZE(result, size) \
59  do { \
60  if ((result).width() < 0 || (result).height() < 0) \
61  combineSize((result), (size)); \
62  } while (false)
63 
64 static void combineSize(QSizeF &result, const QSizeF &size)
65 {
66  if (result.width() < 0)
67  result.setWidth(size.width());
68  if (result.height() < 0)
69  result.setHeight(size.height());
70 }
71 
72 static void boundSize(QSizeF &result, const QSizeF &size)
73 {
74  if (size.width() >= 0 && size.width() < result.width())
75  result.setWidth(size.width());
76  if (size.height() >= 0 && size.height() < result.height())
77  result.setHeight(size.height());
78 }
79 
80 static void expandSize(QSizeF &result, const QSizeF &size)
81 {
82  if (size.width() >= 0 && size.width() > result.width())
83  result.setWidth(size.width());
84  if (size.height() >= 0 && size.height() > result.height())
85  result.setHeight(size.height());
86 }
87 
88 static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent)
89 {
90  if (minimum >= 0 && maximum >= 0 && minimum > maximum)
91  minimum = maximum;
92 
93  if (preferred >= 0) {
94  if (minimum >= 0 && preferred < minimum) {
95  preferred = minimum;
96  } else if (maximum >= 0 && preferred > maximum) {
97  preferred = maximum;
98  }
99  }
100 
101  if (minimum >= 0 && descent > minimum)
102  descent = minimum;
103 }
104 
109  : parent(par), userSizeHints(nullptr), isLayout(layout), ownedByLayout(false), graphicsItem(nullptr)
110 {
111 }
112 
117 {
118  // Remove any lazily allocated data
119  delete[] userSizeHints;
120 }
121 
126 {
127  sizeHintCacheDirty = true;
129 }
130 
135 {
136  Q_Q(const QGraphicsLayoutItem);
137  QSizeF *sizeHintCache;
138  const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0;
139  if (hasConstraint) {
142  sizeHintCache = cachedSizeHintsWithConstraints;
143  } else {
144  if (!sizeHintCacheDirty)
145  return cachedSizeHints;
146  sizeHintCache = cachedSizeHints;
147  }
148 
149  for (int i = 0; i < Qt::NSizeHints; ++i) {
150  sizeHintCache[i] = constraint;
151  if (userSizeHints)
152  combineSize(sizeHintCache[i], userSizeHints[i]);
153  }
154 
155  QSizeF &minS = sizeHintCache[Qt::MinimumSize];
156  QSizeF &prefS = sizeHintCache[Qt::PreferredSize];
157  QSizeF &maxS = sizeHintCache[Qt::MaximumSize];
158  QSizeF &descentS = sizeHintCache[Qt::MinimumDescent];
159 
160  normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
161  normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
162 
163  // if the minimum, preferred and maximum sizes contradict each other
164  // (e.g. the minimum is larger than the maximum) we give priority to
165  // the maximum size, then the minimum size and finally the preferred size
166  COMBINE_SIZE(maxS, q->sizeHint(Qt::MaximumSize, maxS));
167  combineSize(maxS, QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
168  expandSize(maxS, prefS);
169  expandSize(maxS, minS);
170  boundSize(maxS, QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
171 
172  COMBINE_SIZE(minS, q->sizeHint(Qt::MinimumSize, minS));
173  expandSize(minS, QSizeF(0, 0));
174  boundSize(minS, prefS);
175  boundSize(minS, maxS);
176 
177  COMBINE_SIZE(prefS, q->sizeHint(Qt::PreferredSize, prefS));
178  expandSize(prefS, minS);
179  boundSize(prefS, maxS);
180 
181  // Not supported yet
182  // COMBINE_SIZE(descentS, q->sizeHint(Qt::MinimumDescent, constraint));
183 
184  if (hasConstraint) {
185  cachedConstraint = constraint;
187  } else {
188  sizeHintCacheDirty = false;
189  }
190  return sizeHintCache;
191 }
192 
193 
211 {
212  Q_Q(const QGraphicsLayoutItem);
213 
214  const QGraphicsLayoutItem *parent = q;
215  while (parent && parent->isLayout()) {
217  }
218  return parent ? parent->graphicsItem() : nullptr;
219 }
220 
228 {
229  if (!userSizeHints)
231 }
232 
239 {
240  Q_Q(QGraphicsLayoutItem);
241 
242  if (userSizeHints) {
243  if (size == userSizeHints[which])
244  return;
245  } else if (size.width() < 0 && size.height() < 0) {
246  return;
247  }
248 
250  userSizeHints[which] = size;
251  q->updateGeometry();
252 }
253 
260  Qt::SizeHint which, SizeComponent component, qreal value)
261 {
262  Q_Q(QGraphicsLayoutItem);
264  qreal &userValue = (component == Width)
265  ? userSizeHints[which].rwidth()
266  : userSizeHints[which].rheight();
267  if (value == userValue)
268  return;
269  userValue = value;
270  q->updateGeometry();
271 }
272 
273 
275 {
276  Q_Q(const QGraphicsLayoutItem);
277  if (isLayout) {
278  const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
279  for (int i = l->count() - 1; i >= 0; --i) {
281  return true;
282  }
283  } else if (QGraphicsItem *item = q->graphicsItem()) {
284  if (item->isWidget()) {
285  QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
286  if (w->layout()) {
288  }
289  }
290  }
291  return q->sizePolicy().hasHeightForWidth();
292 }
293 
295 {
296  Q_Q(const QGraphicsLayoutItem);
297  if (isLayout) {
298  const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
299  for (int i = l->count() - 1; i >= 0; --i) {
301  return true;
302  }
303  } else if (QGraphicsItem *item = q->graphicsItem()) {
304  if (item->isWidget()) {
305  QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
306  if (w->layout()) {
308  }
309  }
310  }
311  return q->sizePolicy().hasWidthForHeight();
312 }
313 
391  : d_ptr(new QGraphicsLayoutItemPrivate(parent, isLayout))
392 {
393  Q_D(QGraphicsLayoutItem);
394  d->init();
396  d->q_ptr = this;
397 }
398 
403  : d_ptr(&dd)
404 {
405  Q_D(QGraphicsLayoutItem);
406  d->init();
407  d->q_ptr = this;
408 }
409 
414 {
416  if (parentLI && parentLI->isLayout()) {
417  QGraphicsLayout *lay = static_cast<QGraphicsLayout*>(parentLI);
418  // this is not optimal
419  for (int i = lay->count() - 1; i >= 0; --i) {
420  if (lay->itemAt(i) == this) {
421  lay->removeAt(i);
422  break;
423  }
424  }
425  }
426 }
427 
454 {
455  Q_D(QGraphicsLayoutItem);
456  if (d->sizePolicy == policy)
457  return;
458  d->sizePolicy = policy;
459  updateGeometry();
460 }
461 
471  QSizePolicy::Policy vPolicy,
472  QSizePolicy::ControlType controlType)
473 {
474  setSizePolicy(QSizePolicy(hPolicy, vPolicy, controlType));
475 }
476 
483 {
484  Q_D(const QGraphicsLayoutItem);
485  return d->sizePolicy;
486 }
487 
498 {
500 }
501 
518 {
520 }
521 
528 {
530 }
531 
538 {
540 }
541 
542 
552 {
554 }
555 
572 {
574 }
575 
582 {
584 }
585 
592 {
594 }
595 
606 {
608 }
609 
626 {
628 }
629 
636 {
638 }
639 
646 {
648 }
649 
716 {
717  Q_D(QGraphicsLayoutItem);
718  QSizeF effectiveSize = rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
719  .boundedTo(effectiveSizeHint(Qt::MaximumSize));
720  d->geom = QRectF(rect.topLeft(), effectiveSize);
721 }
722 
732 {
733  Q_D(const QGraphicsLayoutItem);
734  return d->geom;
735 }
736 
746 {
747  if (left)
748  *left = 0;
749  if (top)
750  *top = 0;
751  if (right)
752  *right = 0;
753  if (bottom)
754  *bottom = 0;
755 }
756 
769 {
772  return QRectF(QPointF(), geometry().size()).adjusted(+left, +top, -right, -bottom);
773 }
774 
804 {
805  Q_D(const QGraphicsLayoutItem);
806 
807  if (!d->userSizeHints && constraint.isValid())
808  return constraint;
809 
810  // ### should respect size policy???
811  return d_ptr->effectiveSizeHints(constraint)[which];
812 }
813 
823 {
824  Q_D(QGraphicsLayoutItem);
825  d->sizeHintCacheDirty = true;
826  d->sizeHintWithConstraintCacheDirty = true;
827 }
828 
841 {
842  bool isHidden = false;
845 
846  return isHidden && !sizePolicy().retainSizeWhenHidden();
847 }
848 
858 {
859  return d_func()->parent;
860 }
861 
868 {
869  d_func()->parent = parent;
870 }
871 
880 {
881  return d_func()->isLayout;
882 }
883 
909 {
910  return d_func()->ownedByLayout;
911 }
920 {
921  d_func()->ownedByLayout = ownership;
922 }
923 
932 {
933  return d_func()->graphicsItem;
934 }
935 
947 {
948  d_func()->graphicsItem = item;
949 }
950 
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:83
bool isWidget() const
static const QGraphicsItemPrivate * get(const QGraphicsItem *item)
The QGraphicsLayout class provides the base class for all layouts in Graphics View.
virtual int count() const =0
virtual QGraphicsLayoutItem * itemAt(int i) const =0
virtual void removeAt(int index)=0
The QGraphicsLayoutItem class can be inherited to allow your custom items to be managed by layouts.
void setPreferredWidth(qreal width)
void setMaximumWidth(qreal width)
void setGraphicsItem(QGraphicsItem *item)
QGraphicsItem * graphicsItem() const
QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
QScopedPointer< QGraphicsLayoutItemPrivate > d_ptr
void setMaximumSize(const QSizeF &size)
void setSizePolicy(const QSizePolicy &policy)
void setOwnedByLayout(bool ownedByLayout)
virtual bool isEmpty() const
void setPreferredHeight(qreal height)
void setPreferredSize(const QSizeF &size)
QGraphicsLayoutItem * parentLayoutItem() const
void setMinimumSize(const QSizeF &size)
void setMaximumHeight(qreal height)
void setParentLayoutItem(QGraphicsLayoutItem *parent)
virtual void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
virtual void setGeometry(const QRectF &rect)
QSizePolicy sizePolicy() const
void setMinimumWidth(qreal width)
void setMinimumHeight(qreal height)
QGraphicsLayoutItem(QGraphicsLayoutItem *parent=nullptr, bool isLayout=false)
QSizeF * effectiveSizeHints(const QSizeF &constraint) const
void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value)
void setSize(Qt::SizeHint which, const QSizeF &size)
QGraphicsLayoutItem * parent
static QGraphicsLayoutItemPrivate * get(QGraphicsLayoutItem *q)
QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout)
QGraphicsItem * parentItem() const
QSizeF cachedSizeHints[Qt::NSizeHints]
QSizeF cachedSizeHintsWithConstraints[Qt::NSizeHints]
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
constexpr QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const noexcept
Definition: qrect.h:822
The QSizeF class defines the size of a two-dimensional object using floating point precision.
Definition: qsize.h:235
constexpr qreal & rwidth() noexcept
Definition: qsize.h:373
constexpr bool isValid() const noexcept
Definition: qsize.h:346
constexpr qreal & rheight() noexcept
Definition: qsize.h:376
constexpr qreal width() const noexcept
Definition: qsize.h:349
constexpr qreal height() const noexcept
Definition: qsize.h:352
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition: qsizepolicy.h:54
constexpr bool retainSizeWhenHidden() const noexcept
Definition: qsizepolicy.h:133
rect
[4]
SizeHint
Definition: qnamespace.h:1589
@ MaximumSize
Definition: qnamespace.h:1592
@ PreferredSize
Definition: qnamespace.h:1591
@ MinimumDescent
Definition: qnamespace.h:1593
@ MinimumSize
Definition: qnamespace.h:1590
@ NSizeHints
Definition: qnamespace.h:1594
EGLOutputLayerEXT EGLint EGLAttrib value
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
#define COMBINE_SIZE(result, size)
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLint GLsizei width
GLint left
GLint GLint bottom
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
#define QWIDGETSIZE_MAX
Definition: qwidget.h:951
QObject::connect nullptr
QVBoxLayout * layout
size rwidth()+
QGraphicsItem * item
QSizePolicy policy
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent