Qt 4.8
qgraphicslayoutitem.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qglobal.h"
43 
44 #ifndef QT_NO_GRAPHICSVIEW
45 
46 #include "qgraphicslayout.h"
47 #include "qgraphicsscene.h"
48 #include "qgraphicslayoutitem.h"
49 #include "qgraphicslayoutitem_p.h"
50 #include "qwidget.h"
51 #include "qgraphicswidget.h"
52 
53 #include <QtDebug>
54 
56 
57 /*
58  COMBINE_SIZE() is identical to combineSize(), except that it
59  doesn't evaluate 'size' unless necessary.
60 */
61 #define COMBINE_SIZE(result, size) \
62  do { \
63  if ((result).width() < 0 || (result).height() < 0) \
64  combineSize((result), (size)); \
65  } while (false)
66 
67 static void combineSize(QSizeF &result, const QSizeF &size)
68 {
69  if (result.width() < 0)
70  result.setWidth(size.width());
71  if (result.height() < 0)
72  result.setHeight(size.height());
73 }
74 
75 static void boundSize(QSizeF &result, const QSizeF &size)
76 {
77  if (size.width() >= 0 && size.width() < result.width())
78  result.setWidth(size.width());
79  if (size.height() >= 0 && size.height() < result.height())
80  result.setHeight(size.height());
81 }
82 
83 static void expandSize(QSizeF &result, const QSizeF &size)
84 {
85  if (size.width() >= 0 && size.width() > result.width())
86  result.setWidth(size.width());
87  if (size.height() >= 0 && size.height() > result.height())
88  result.setHeight(size.height());
89 }
90 
91 static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent)
92 {
93  if (minimum >= 0 && maximum >= 0 && minimum > maximum)
94  minimum = maximum;
95 
96  if (preferred >= 0) {
97  if (minimum >= 0 && preferred < minimum) {
98  preferred = minimum;
99  } else if (maximum >= 0 && preferred > maximum) {
100  preferred = maximum;
101  }
102  }
103 
104  if (minimum >= 0 && descent > minimum)
105  descent = minimum;
106 }
107 
112  : parent(par), userSizeHints(0), isLayout(layout), ownedByLayout(false), graphicsItem(0)
113 {
114 }
115 
120 {
121  // Remove any lazily allocated data
122  delete[] userSizeHints;
123 }
124 
129 {
130  sizeHintCacheDirty = true;
132 }
133 
189 {
190  Q_Q(const QGraphicsLayoutItem);
191  QSizeF *sizeHintCache;
192  const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0;
193  QSizeF adjustedConstraint = constraint;
194  if (hasConstraint) {
197 
198  const QSizeF *hintsWithoutConstraint = effectiveSizeHints(QSizeF(-1,-1));
199 
200  if (adjustedConstraint.width() >= 0)
201  adjustedConstraint.setWidth( qBound( hintsWithoutConstraint[Qt::MinimumSize].width(),
202  adjustedConstraint.width(),
203  hintsWithoutConstraint[Qt::MaximumSize].width()));
204  if (adjustedConstraint.height() >= 0)
205  adjustedConstraint.setHeight( qBound( hintsWithoutConstraint[Qt::MinimumSize].height(),
206  adjustedConstraint.height(),
207  hintsWithoutConstraint[Qt::MaximumSize].height()));
208 
209  if (!sizeHintWithConstraintCacheDirty && adjustedConstraint == cachedConstraint)
211  sizeHintCache = cachedSizeHintsWithConstraints;
212  } else {
213  if (!sizeHintCacheDirty)
214  return cachedSizeHints;
215  sizeHintCache = cachedSizeHints;
216  }
217 
218  for (int i = 0; i < Qt::NSizeHints; ++i) {
219  sizeHintCache[i] = adjustedConstraint;
220  if (userSizeHints)
221  combineSize(sizeHintCache[i], userSizeHints[i]);
222  }
223 
224  QSizeF &minS = sizeHintCache[Qt::MinimumSize];
225  QSizeF &prefS = sizeHintCache[Qt::PreferredSize];
226  QSizeF &maxS = sizeHintCache[Qt::MaximumSize];
227  QSizeF &descentS = sizeHintCache[Qt::MinimumDescent];
228 
229  normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
230  normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
231 
232  // if the minimum, preferred and maximum sizes contradict each other
233  // (e.g. the minimum is larger than the maximum) we give priority to
234  // the maximum size, then the minimum size and finally the preferred size
235  COMBINE_SIZE(maxS, q->sizeHint(Qt::MaximumSize, maxS));
237  expandSize(maxS, prefS);
238  expandSize(maxS, minS);
240 
241  COMBINE_SIZE(minS, q->sizeHint(Qt::MinimumSize, minS));
242  expandSize(minS, QSizeF(0, 0));
243  boundSize(minS, prefS);
244  boundSize(minS, maxS);
245 
246  COMBINE_SIZE(prefS, q->sizeHint(Qt::PreferredSize, prefS));
247  expandSize(prefS, minS);
248  boundSize(prefS, maxS);
249 
250  // Not supported yet
251  // COMBINE_SIZE(descentS, q->sizeHint(Qt::MinimumDescent, constraint));
252 
253  if (hasConstraint) {
254  cachedConstraint = adjustedConstraint;
256  } else {
257  sizeHintCacheDirty = false;
258  }
259  return sizeHintCache;
260 }
261 
262 
283 {
284  Q_Q(const QGraphicsLayoutItem);
285 
286  const QGraphicsLayoutItem *parent = q;
287  while (parent && parent->isLayout()) {
288  parent = parent->parentLayoutItem();
289  }
290  return parent ? parent->graphicsItem() : 0;
291 }
292 
303 {
304  if (!userSizeHints)
306 }
307 
317 {
319 
320  if (userSizeHints) {
321  if (size == userSizeHints[which])
322  return;
323  } else if (size.width() < 0 && size.height() < 0) {
324  return;
325  }
326 
328  userSizeHints[which] = size;
329  q->updateGeometry();
330 }
331 
342 {
345  qreal &userValue = (component == Width)
346  ? userSizeHints[which].rwidth()
347  : userSizeHints[which].rheight();
348  if (value == userValue)
349  return;
350  userValue = value;
351  q->updateGeometry();
352 }
353 
354 
356 {
357  Q_Q(const QGraphicsLayoutItem);
358  if (isLayout) {
359  const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
360  for (int i = l->count() - 1; i >= 0; --i) {
362  return true;
363  }
364  } else if (QGraphicsItem *item = q->graphicsItem()) {
365  if (item->isWidget()) {
366  QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
367  if (w->layout()) {
369  }
370  }
371  }
372  return q->sizePolicy().hasHeightForWidth();
373 }
374 
376 {
377  Q_Q(const QGraphicsLayoutItem);
378  if (isLayout) {
379  const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
380  for (int i = l->count() - 1; i >= 0; --i) {
382  return true;
383  }
384  } else if (QGraphicsItem *item = q->graphicsItem()) {
385  if (item->isWidget()) {
386  QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
387  if (w->layout()) {
389  }
390  }
391  }
392  return q->sizePolicy().hasWidthForHeight();
393 }
394 
474  : d_ptr(new QGraphicsLayoutItemPrivate(parent, isLayout))
475 {
477  d->init();
479  d->q_ptr = this;
480 }
481 
486  : d_ptr(&dd)
487 {
489  d->init();
490  d->q_ptr = this;
491 }
492 
497 {
499  if (parentLI && parentLI->isLayout()) {
500  QGraphicsLayout *lay = static_cast<QGraphicsLayout*>(parentLI);
501  // this is not optimal
502  for (int i = lay->count() - 1; i >= 0; --i) {
503  if (lay->itemAt(i) == this) {
504  lay->removeAt(i);
505  break;
506  }
507  }
508  }
509 }
510 
540 {
542  if (d->sizePolicy == policy)
543  return;
544  d->sizePolicy = policy;
545  updateGeometry();
546 }
547 
560  QSizePolicy::Policy vPolicy,
561  QSizePolicy::ControlType controlType)
562 {
563  setSizePolicy(QSizePolicy(hPolicy, vPolicy, controlType));
564 }
565 
572 {
573  Q_D(const QGraphicsLayoutItem);
574  return d->sizePolicy;
575 }
576 
587 {
588  d_ptr->setSize(Qt::MinimumSize, size);
589 }
590 
610 {
612 }
613 
620 {
622 }
623 
630 {
632 }
633 
634 
644 {
646 }
647 
667 {
669 }
670 
677 {
679 }
680 
687 {
689 }
690 
701 {
702  d_ptr->setSize(Qt::MaximumSize, size);
703 }
704 
724 {
726 }
727 
734 {
736 }
737 
744 {
746 }
747 
835 {
837  QSizeF effectiveSize = rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
839  d->geom = QRectF(rect.topLeft(), effectiveSize);
840 }
841 
854 {
855  Q_D(const QGraphicsLayoutItem);
856  return d->geom;
857 }
858 
868 {
869  if (left)
870  *left = 0;
871  if (top)
872  *top = 0;
873  if (right)
874  *right = 0;
875  if (bottom)
876  *bottom = 0;
877 }
878 
891 {
892  qreal left, top, right, bottom;
893  getContentsMargins(&left, &top, &right, &bottom);
894  return QRectF(QPointF(), geometry().size()).adjusted(+left, +top, -right, -bottom);
895 }
896 
926 {
927  Q_D(const QGraphicsLayoutItem);
928 
929  if (!d->userSizeHints && constraint.isValid())
930  return constraint;
931 
932  // ### should respect size policy???
933  return d_ptr->effectiveSizeHints(constraint)[which];
934 }
935 
945 {
947  d->sizeHintCacheDirty = true;
948  d->sizeHintWithConstraintCacheDirty = true;
949 }
950 
960 {
961  return d_func()->parent;
962 }
963 
970 {
971  d_func()->parent = parent;
972 }
973 
982 {
983  return d_func()->isLayout;
984 }
985 
1014 {
1015  return d_func()->ownedByLayout;
1016 }
1028 {
1029  d_func()->ownedByLayout = ownership;
1030 }
1031 
1040 {
1041  return d_func()->graphicsItem;
1042 }
1043 
1055 {
1056  d_func()->graphicsItem = item;
1057 }
1058 
1060 
1061 #endif //QT_NO_GRAPHICSVIEW
virtual void removeAt(int index)=0
This pure virtual function must be reimplemented in a subclass of QGraphicsLayout to remove the item ...
virtual ~QGraphicsLayoutItem()
Destroys the QGraphicsLayoutItem object.
double d
Definition: qnumeric_p.h:62
QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Returns the effective size hint for this QGraphicsLayoutItem.
void setPreferredHeight(qreal height)
Sets the preferred height to height.
virtual void setGeometry(const QRectF &rect)
This virtual function sets the geometry of the QGraphicsLayoutItem to rect, which is in parent coordi...
static QGraphicsLayoutItemPrivate * get(QGraphicsLayoutItem *q)
QSizeF cachedSizeHints[Qt::NSizeHints]
QGraphicsLayout * layout
The layout of the widget.
double qreal
Definition: qglobal.h:1193
#define COMBINE_SIZE(result, size)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QScopedPointer< QGraphicsLayoutItemPrivate > d_ptr
void setMaximumHeight(qreal height)
Sets the maximum height to height.
QSizeF * effectiveSizeHints(const QSizeF &constraint) const
QGraphicsItem * graphicsItem() const
Returns the QGraphicsItem that this layout item represents.
qreal width() const
Returns the width.
Definition: qsize.h:284
QRectF contentsRect() const
Returns the contents rect in local coordinates.
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:89
qreal height() const
Returns the height.
Definition: qsize.h:287
#define QWIDGETSIZE_MAX
Defines the maximum size for a QWidget object.
Definition: qwidget.h:1087
QPointF topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:539
void setParentLayoutItem(QGraphicsLayoutItem *parent)
Sets the parent of this QGraphicsLayoutItem to parent.
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
Definition: qsize.h:281
void setWidth(qreal w)
Sets the width to the given width.
Definition: qsize.h:290
static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent)
#define Q_D(Class)
Definition: qglobal.h:2482
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
#define Q_Q(Class)
Definition: qglobal.h:2483
QRectF geometry() const
Returns the item&#39;s geometry (e.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
virtual void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
This virtual function provides the left, top, right and bottom contents margins for this QGraphicsLay...
void setMaximumWidth(qreal width)
Sets the maximum width to width.
const char * layout
virtual void updateGeometry()
This virtual function discards any cached size hint information.
QSizeF preferredSize() const
Returns the preferred size.
The QGraphicsLayoutItem class can be inherited to allow your custom items to be managed by layouts...
void setPreferredSize(const QSizeF &size)
Sets the preferred size to size.
static qreal component(const QPointF &point, unsigned int i)
QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition: qrect.h:781
bool ownedByLayout() const
Returns whether a layout should delete this item in its destructor.
QGraphicsItem * parentItem() const
Returns the parent item of this layout, or 0 if this layout is not installed on any widget...
QSizeF maximumSize() const
Returns the maximum size.
QSizeF minimumSize() const
Returns the minimum size.
bool isLayout() const
Returns true if this QGraphicsLayoutItem is a layout (e.g., is inherited by an object that arranges o...
virtual int count() const =0
This pure virtual function must be reimplemented in a subclass of QGraphicsLayout to return the numbe...
void setOwnedByLayout(bool ownedByLayout)
Sets whether a layout should delete this item in its destructor or not.
SizeHint
Definition: qnamespace.h:1708
QGraphicsLayoutItem(QGraphicsLayoutItem *parent=0, bool isLayout=false)
Constructs the QGraphicsLayoutItem object.
static void expandSize(QSizeF &result, const QSizeF &size)
QSizeF boundedTo(const QSizeF &) const
Returns a size holding the minimum width and height of this size and the given otherSize.
Definition: qsize.h:350
QSizeF expandedTo(const QSizeF &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:345
void setMinimumHeight(qreal height)
Sets the minimum height to height.
QGraphicsLayoutItem * parentLayoutItem() const
Returns the parent of this QGraphicsLayoutItem, or 0 if there is no parent, or if the parent does not...
QSizePolicy sizePolicy() const
Returns the current size policy.
void setMinimumWidth(qreal width)
Sets the minimum width to width.
void setPreferredWidth(qreal width)
Sets the preferred width to width.
static void boundSize(QSizeF &result, const QSizeF &size)
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
Definition: qglobal.h:1219
QSizeF cachedSizeHintsWithConstraints[Qt::NSizeHints]
The QGraphicsLayout class provides the base class for all layouts in Graphics View.
QFactoryLoader * l
void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value)
Sets the width of the user size hint which to width.
QSizeF size() const
Returns the size of the rectangle.
Definition: qrect.h:713
void setSizePolicy(const QSizePolicy &policy)
Sets the size policy to policy.
static void combineSize(QSizeF &result, const QSizeF &size)
void setHeight(qreal h)
Sets the height to the given height.
Definition: qsize.h:293
void setGraphicsItem(QGraphicsItem *item)
If the QGraphicsLayoutItem represents a QGraphicsItem, and it wants to take advantage of the automati...
virtual QGraphicsLayoutItem * itemAt(int i) const =0
This pure virtual function must be reimplemented in a subclass of QGraphicsLayout to return a pointer...
void ensureUserSizeHints()
Ensures that userSizeHints is allocated.
qreal & rheight()
Returns a reference to the height.
Definition: qsize.h:302
void setMinimumSize(const QSizeF &size)
Sets the minimum size to size.
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
qreal & rwidth()
Returns a reference to the width.
Definition: qsize.h:299
QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout)
void setSize(Qt::SizeHint which, const QSizeF &size)
Sets the user size hint which to size.
void setMaximumSize(const QSizeF &size)
Sets the maximum size to size.
QGraphicsLayoutItem * parent
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.