summaryrefslogtreecommitdiffstats
path: root/src/gui/graphicsview
diff options
context:
space:
mode:
authorJan-Arve Saether <jan-arve.saether@nokia.com>2011-06-09 07:57:39 (GMT)
committerJan-Arve Saether <jan-arve.saether@nokia.com>2011-06-10 06:25:59 (GMT)
commit4225a25efb46c9f5a3fbb8197286663b8cb21e27 (patch)
tree101e6b16cec0998ffafc0f5e89ebc20527588b18 /src/gui/graphicsview
parent575e832fd053df98e60aefebbc5843a4864f2523 (diff)
downloadQt-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.cpp14
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp16
-rw-r--r--src/gui/graphicsview/qgraphicswidget.h2
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp14
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.h5
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;