/*! Clears any cached geometry and size hint information in the layout, and posts a \l{QEvent::LayoutRequest}{LayoutRequest} event to the managed parent QGraphicsLayoutItem. \sa activate(), setGeometry() */ void QGraphicsLayout::invalidate() { // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event. QGraphicsLayoutItem *layoutItem = this; while (layoutItem && layoutItem->isLayout()) { // we could call updateGeometry(), but what if that method // does not call the base implementation? In addition, updateGeometry() // does more than we need. layoutItem->d_func()->sizeHintCacheDirty = true; layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; layoutItem = layoutItem->parentLayoutItem(); } if (layoutItem) { layoutItem->d_func()->sizeHintCacheDirty = true; layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; } bool postIt = layoutItem ? !layoutItem->isLayout() : false; if (postIt) { layoutItem = this; while (layoutItem && layoutItem->isLayout() && static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) { static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false; layoutItem = layoutItem->parentLayoutItem(); } if (layoutItem && !layoutItem->isLayout()) { // If a layout has a parent that is not a layout it must be a QGraphicsWidget. QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest)); } } }
void MMessageBoxViewPrivate::updateLayout() { clearLayout(); prepareLayout(); if (centralWidget) { contentsLayout->insertItem(0, centralWidget); } if (textLabel) { contentsLayout->insertItem(0, textLabel); contentsLayout->setAlignment(textLabel, Qt::AlignCenter); } if (titleLabel) { contentsLayout->insertItem(0, titleLabel); contentsLayout->setAlignment(titleLabel, Qt::AlignCenter); } if (iconImage) { contentsLayout->insertItem(0, iconImage); contentsLayout->setAlignment(iconImage, Qt::AlignCenter); } if (!QGraphicsLayout::instantInvalidatePropagation()) { /* Update the geometry of the parents immediately. This simply makes the layout have the correct sizehint * immediately instead of one frame later, removing a single frame of 'flicker'. */ QGraphicsLayoutItem *item = contents; do { item->updateGeometry(); } while( (item = item->parentLayoutItem()) ); } }
/*! Activates the layout, causing all items in the layout to be immediately rearranged. This function is based on calling count() and itemAt(), and then calling setGeometry() on all items sequentially. When activated, the layout will adjust its geometry to its parent's contentsRect(). The parent will then invalidate any layout of its own. If called in sequence or recursively, e.g., by one of the arranged items in response to being resized, this function will do nothing. Note that the layout is free to use geometry caching to optimize this process. To forcefully invalidate any such cache, you can call invalidate() before calling activate(). \sa invalidate() */ void QGraphicsLayout::activate() { Q_D(QGraphicsLayout); if (d->activated) return; d->activateRecursive(this); // we don't call activate on a sublayout, but somebody might. // Therefore, we walk to the parentitem of the toplevel layout. QGraphicsLayoutItem *parentItem = this; while (parentItem && parentItem->isLayout()) parentItem = parentItem->parentLayoutItem(); if (!parentItem) return; Q_ASSERT(!parentItem->isLayout()); if (QGraphicsLayout::instantInvalidatePropagation()) { QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem); if (!parentWidget->parentLayoutItem()) { // we've reached the topmost widget, resize it bool wasResized = parentWidget->testAttribute(Qt::WA_Resized); parentWidget->resize(parentWidget->size()); parentWidget->setAttribute(Qt::WA_Resized, wasResized); } setGeometry(parentItem->contentsRect()); // relayout children } else { setGeometry(parentItem->contentsRect()); // relayout children parentLayoutItem()->updateGeometry(); } }
/*! Activates the layout, causing all items in the layout to be immediately rearranged. This function is based on calling count() and itemAt(), and then calling setGeometry() on all items sequentially. When activated, the layout will adjust its geometry to its parent's contentsRect(). The parent will then invalidate any layout of its own. If called in sequence or recursively, e.g., by one of the arranged items in response to being resized, this function will do nothing. Note that the layout is free to use geometry caching to optimize this process. To forcefully invalidate any such cache, you can call invalidate() before calling activate(). \sa invalidate() */ void QGraphicsLayout::activate() { Q_D(QGraphicsLayout); if (d->activated) return; d->activateRecursive(this); // we don't call activate on a sublayout, but somebody might. // Therefore, we walk to the parentitem of the toplevel layout. QGraphicsLayoutItem *parentItem = this; while (parentItem && parentItem->isLayout()) parentItem = parentItem->parentLayoutItem(); if (!parentItem) return; Q_ASSERT(!parentItem->isLayout()); setGeometry(parentItem->contentsRect()); // relayout children if (!QGraphicsLayout::instantInvalidatePropagation()) { parentLayoutItem()->updateGeometry(); } }
/*! Activates the layout, causing all items in the layout to be immediately rearranged. This function is based on calling count() and itemAt(), and then calling setGeometry() on all items sequentially. When activated, the layout will adjust its geometry to its parent's contentsRect(). The parent will then invalidate any layout of its own. If called in sequence or recursively, e.g., by one of the arranged items in response to being resized, this function will do nothing. Note that the layout is free to use geometry caching to optimize this process. To forcefully invalidate any such cache, you can call invalidate() before calling activate(). \sa invalidate() */ void QGraphicsLayout::activate() { Q_D(QGraphicsLayout); if (d->activated) return; d->activateRecursive(this); // we don't call activate on a sublayout, but somebody might. // Therefore, we walk to the parentitem of the toplevel layout. QGraphicsLayoutItem *parentItem = this; while (parentItem && parentItem->isLayout()) parentItem = parentItem->parentLayoutItem(); if (!parentItem) return; Q_ASSERT(!parentItem->isLayout()); setGeometry(parentItem->contentsRect()); // relayout children // ### bug, should be parentItem ? parentLayoutItem()->updateGeometry(); // bubble up; will set activated to false // ### too many resizes? maybe we should walk up the chain to the // ### top-level layouted layoutItem and call activate there. }