QtBase  v6.3.1
qgraphicslayout.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 "qapplication.h"
41 
42 #include "qgraphicslayout.h"
43 #include "qgraphicslayout_p.h"
44 #include "qgraphicslayoutitem.h"
45 #include "qgraphicslayoutitem_p.h"
46 #include "qgraphicswidget.h"
47 #include "qgraphicswidget_p.h"
48 #include "qgraphicsscene.h"
49 
51 
160 {
162  if (parent && !parent->isLayout()) {
163  // If a layout has a parent that is not a layout it must be a QGraphicsWidget.
164  QGraphicsItem *itemParent = parent->graphicsItem();
165  if (itemParent && itemParent->isWidget()) {
166  static_cast<QGraphicsWidget *>(itemParent)->d_func()->setLayout_helper(this);
167  } else {
168  qWarning("QGraphicsLayout::QGraphicsLayout: Attempt to create a layout with a parent that is"
169  " neither a QGraphicsWidget nor QGraphicsLayout");
170  }
171  }
173  setOwnedByLayout(true);
174 }
175 
180  : QGraphicsLayoutItem(dd)
181 {
183  if (parent && !parent->isLayout()) {
184  // If a layout has a parent that is not a layout it must be a QGraphicsWidget.
185  QGraphicsItem *itemParent = parent->graphicsItem();
186  if (itemParent && itemParent->isWidget()) {
187  static_cast<QGraphicsWidget *>(itemParent)->d_func()->setLayout_helper(this);
188  } else {
189  qWarning("QGraphicsLayout::QGraphicsLayout: Attempt to create a layout with a parent that is"
190  " neither a QGraphicsWidget nor QGraphicsLayout");
191  }
192  }
194  setOwnedByLayout(true);
195 }
196 
201 {
202 }
203 
218 {
219  Q_D(QGraphicsLayout);
220  if (d->left == left && d->top == top && d->right == right && d->bottom == bottom)
221  return;
222  d->left = left;
223  d->right = right;
224  d->top = top;
225  d->bottom = bottom;
226  invalidate();
227 }
228 
233 {
234  Q_D(const QGraphicsLayout);
235  d->getMargin(left, d->left, QStyle::PM_LayoutLeftMargin);
236  d->getMargin(top, d->top, QStyle::PM_LayoutTopMargin);
237  d->getMargin(right, d->right, QStyle::PM_LayoutRightMargin);
238  d->getMargin(bottom, d->bottom, QStyle::PM_LayoutBottomMargin);
239 }
240 
258 {
259  Q_D(QGraphicsLayout);
260  if (d->activated)
261  return;
262 
263  d->activateRecursive(this);
264 
265  // we don't call activate on a sublayout, but somebody might.
266  // Therefore, we walk to the parentitem of the toplevel layout.
267  QGraphicsLayoutItem *parentItem = this;
268  while (parentItem && parentItem->isLayout())
269  parentItem = parentItem->parentLayoutItem();
270  if (!parentItem)
271  return;
272  Q_ASSERT(!parentItem->isLayout());
273 
275  QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem);
276  if (!parentWidget->parentLayoutItem()) {
277  // we've reached the topmost widget, resize it
278  bool wasResized = parentWidget->testAttribute(Qt::WA_Resized);
279  parentWidget->resize(parentWidget->size());
280  parentWidget->setAttribute(Qt::WA_Resized, wasResized);
281  }
282 
283  setGeometry(parentItem->contentsRect()); // relayout children
284  } else {
285  setGeometry(parentItem->contentsRect()); // relayout children
287  }
288 }
289 
299 {
300  Q_D(const QGraphicsLayout);
301  return d->activated;
302 }
303 
312 {
314  updateGeometry();
315  } else {
316  // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event.
317  QGraphicsLayoutItem *layoutItem = this;
318  while (layoutItem && layoutItem->isLayout()) {
319  // we could call updateGeometry(), but what if that method
320  // does not call the base implementation? In addition, updateGeometry()
321  // does more than we need.
322  layoutItem->d_func()->sizeHintCacheDirty = true;
323  layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
324  layoutItem = layoutItem->parentLayoutItem();
325  }
326  if (layoutItem) {
327  layoutItem->d_func()->sizeHintCacheDirty = true;
328  layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
329  }
330 
331  bool postIt = layoutItem ? !layoutItem->isLayout() : false;
332  if (postIt) {
333  layoutItem = this;
334  while (layoutItem && layoutItem->isLayout()
335  && static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) {
336  static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false;
337  layoutItem = layoutItem->parentLayoutItem();
338  }
339  if (layoutItem && !layoutItem->isLayout()) {
340  // If a layout has a parent that is not a layout it must be a QGraphicsWidget.
342  }
343  }
344  }
345 }
346 
351 {
352  Q_D(QGraphicsLayout);
354  d->activated = false;
356 
357  QGraphicsLayoutItem *parentItem = parentLayoutItem();
358  if (!parentItem)
359  return;
360 
361  if (parentItem->isLayout())
362  static_cast<QGraphicsLayout *>(parentItem)->invalidate();
363  else
364  parentItem->updateGeometry();
365  } else {
367  if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) {
368  if (parentItem->isLayout()) {
369  parentItem->updateGeometry();
370  } else {
371  invalidate();
372  }
373  }
374  }
375 }
376 
391 {
392  switch (e->type()) {
394  if (isActivated()) {
396  } else {
397  activate(); // relies on that activate() will call updateGeometry()
398  }
399  break;
401  activate();
402  break;
404  invalidate();
405  break;
406  default:
407  break;
408  }
409 }
410 
473 {
474  Q_D(QGraphicsLayout);
475  d->addChildLayoutItem(layoutItem);
476 }
477 
478 static bool g_instantInvalidatePropagation = false;
479 
506 {
507  g_instantInvalidatePropagation = enable;
508 }
509 
518 {
519  return g_instantInvalidatePropagation;
520 }
521 
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Definition: qcoreevent.h:58
@ LayoutDirectionChange
Definition: qcoreevent.h:137
@ LayoutRequest
Definition: qcoreevent.h:125
@ GraphicsSceneResize
Definition: qcoreevent.h:238
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:83
bool isWidget() const
The QGraphicsLayout class provides the base class for all layouts in Graphics View.
virtual void updateGeometry() override
static void setInstantInvalidatePropagation(bool enable)
bool isActivated() const
virtual void invalidate()
virtual void widgetEvent(QEvent *e)
void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const override
void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
void addChildLayoutItem(QGraphicsLayoutItem *layoutItem)
static bool instantInvalidatePropagation()
The QGraphicsLayoutItem class can be inherited to allow your custom items to be managed by layouts.
void setOwnedByLayout(bool ownedByLayout)
QGraphicsLayoutItem * parentLayoutItem() const
void setParentLayoutItem(QGraphicsLayoutItem *parent)
virtual void setGeometry(const QRectF &rect)
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.
void resize(const QSizeF &size)
void setAttribute(Qt::WidgetAttribute attribute, bool on=true)
bool testAttribute(Qt::WidgetAttribute attribute) const
QSizeF size
the size of the widget
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition: qsizepolicy.h:54
@ PM_LayoutBottomMargin
Definition: qstyle.h:549
@ PM_LayoutLeftMargin
Definition: qstyle.h:546
@ PM_LayoutTopMargin
Definition: qstyle.h:547
@ PM_LayoutRightMargin
Definition: qstyle.h:548
double e
@ WA_Resized
Definition: qnamespace.h:333
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
#define qWarning
Definition: qlogging.h:179
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLint left
GLint GLint bottom
GLboolean enable
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent