diff options
author | Jan-Arve Saether <jan-arve.saether@nokia.com> | 2011-06-09 07:57:39 (GMT) |
---|---|---|
committer | Jan-Arve Saether <jan-arve.saether@nokia.com> | 2011-06-10 06:25:59 (GMT) |
commit | 4225a25efb46c9f5a3fbb8197286663b8cb21e27 (patch) | |
tree | 101e6b16cec0998ffafc0f5e89ebc20527588b18 /src/gui/graphicsview | |
parent | 575e832fd053df98e60aefebbc5843a4864f2523 (diff) | |
download | Qt-4225a25efb46c9f5a3fbb8197286663b8cb21e27.zip Qt-4225a25efb46c9f5a3fbb8197286663b8cb21e27.tar.gz Qt-4225a25efb46c9f5a3fbb8197286663b8cb21e27.tar.bz2 |
Fixes to how resize event and layout request are posted.
Also fixed how the relayout is initiated. This is because we needed
to react differently to *posted* layout requests than to sent layout
requests. (sent ones should activate the layout, posted ones should
also resize the widget).
We therefore introduced the private slot _q_relayout() in order to
be able to make the distinction between posted and sent layout
requests. (Instead of posting we now invokeMethod with a queued
connection. In order to make it behave as it was compressed we also
have to refcount the number of calls to invokeMethod.)
(Note that refCount is 16 bits only, so it should not overflow
in sane cases. In the insane cases, the worst thing that will happen
is that it'll relayout the layout one extra time).
Make sure we resize QGraphicsWidget to be within its min,max sizes
when we change one of its constraints. (e.g. we change minimumSize to
something bigger than the current size). This did not work if the
widget did not have a layout.
Send a resize event whenever a QGraphicsWidget changes its size.
This did not happen before, because in the cases where a Layout Request
was sent, we did not send a resize event. This patch changes that, so
that when we send a resize event, we do not send a Layout Request
event.
This means that a Layout Request event is now *only* sent in order to
tell a widget to relayout its children (but the widgets size was not
changed, that's why we cannot send a resize event in that case)
Also includes a unit test, and a fix to make sure that we send a resize
event when we resize due to the sizehint changing followed by a setPos
command.
Added autotests for this. (and changed some)
Many thanks to John Tapsell and Stanislav Ionascu for help.
(autotests were provided by them).
My poor explanation did not convince Frederik 100%, but he is
"convinced enough" :)
Reviewed-by: Frederik Gladhorn
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicslayout.cpp | 14 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 16 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.h | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget_p.cpp | 14 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget_p.h | 5 |
5 files changed, 29 insertions, 22 deletions
diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index b37dfd4..f983955 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -269,18 +269,8 @@ void QGraphicsLayout::activate() 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 + setGeometry(parentItem->contentsRect()); // relayout children + if (!QGraphicsLayout::instantInvalidatePropagation()) { parentLayoutItem()->updateGeometry(); } } diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 7048fcc..965b1b34 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -404,14 +404,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) emit widthChanged(); if (oldSize.height() != newGeom.size().height()) emit heightChanged(); - QGraphicsLayout *lay = wd->layout; - if (QGraphicsLayout::instantInvalidatePropagation()) { - if (!lay || lay->isActivated()) { - QApplication::sendEvent(this, &re); - } - } else { - QApplication::sendEvent(this, &re); - } + QApplication::sendEvent(this, &re); } } @@ -1090,8 +1083,11 @@ void QGraphicsWidget::updateGeometry() * When the event is received, it will start flowing all the way down to the leaf * widgets in one go. This will make a relayout flicker-free. */ - if (QGraphicsLayout::instantInvalidatePropagation()) - QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest)); + if (QGraphicsLayout::instantInvalidatePropagation()) { + Q_D(QGraphicsWidget); + ++d->refCountInvokeRelayout; + QMetaObject::invokeMethod(this, "_q_relayout", Qt::QueuedConnection); + } } if (!QGraphicsLayout::instantInvalidatePropagation()) { bool wasResized = testAttribute(Qt::WA_Resized); diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 063be2d..5085817 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -234,6 +234,8 @@ protected: private: Q_DISABLE_COPY(QGraphicsWidget) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsWidget) + Q_PRIVATE_SLOT(d_func(), void _q_relayout()) + friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QGraphicsView; diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 059051e..dc0f7c0 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -232,6 +232,18 @@ void QGraphicsWidgetPrivate::resolveLayoutDirection() } } +/* private slot */ +void QGraphicsWidgetPrivate::_q_relayout() +{ + --refCountInvokeRelayout; + if (refCountInvokeRelayout == 0) { + Q_Q(QGraphicsWidget); + bool wasResized = q->testAttribute(Qt::WA_Resized); + q->resize(q->size()); // this will restrict the size + q->setAttribute(Qt::WA_Resized, wasResized); + } +} + QPalette QGraphicsWidgetPrivate::naturalWidgetPalette() const { Q_Q(const QGraphicsWidget); @@ -897,4 +909,6 @@ void QGraphicsWidgetPrivate::setGeometryFromSetPos() QT_END_NAMESPACE +#include "moc_qgraphicswidget.cpp" + #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index 398abc3..6ea2586 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -81,6 +81,7 @@ public: polished(0), inSetPos(0), autoFillBackground(0), + refCountInvokeRelayout(0), focusPolicy(Qt::NoFocus), focusNext(0), focusPrev(0), @@ -106,6 +107,7 @@ public: QGraphicsLayout *layout; void setLayoutDirection_helper(Qt::LayoutDirection direction); void resolveLayoutDirection(); + void _q_relayout(); // Style QPalette palette; @@ -179,11 +181,14 @@ public: return false; return (attributes & (1 << bit)) != 0; } + // 32 bits + quint32 refCountInvokeRelayout : 16; quint32 attributes : 10; quint32 inSetGeometry : 1; quint32 polished: 1; quint32 inSetPos : 1; quint32 autoFillBackground : 1; + quint32 padding : 2; // feel free to use // Focus Qt::FocusPolicy focusPolicy; |