From 59ce8a850d158658c5ed5f2bdc8b9f2013fe4549 Mon Sep 17 00:00:00 2001 From: Sascha Siebert Date: Tue, 10 Jan 2017 18:54:56 +0100 Subject: Fix positioning and placement of initially invisible items in layouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of misusing implicitWidth/Height as a storage mechanism in scenarios where width/height is used for preferred size evaluation, new members are created to hold this information to prevent incorrect sizing in mentioned scenario and get rid of blocking signals. Task-number: QTBUG-57455 Change-Id: I102c45805c4106e5829b17b65c2e247b2381573f Reviewed-by: Jan Arve Sæther --- src/imports/layouts/qquicklayout.cpp | 55 ++++++++++++++++-------------------- src/imports/layouts/qquicklayout_p.h | 3 ++ 2 files changed, 28 insertions(+), 30 deletions(-) (limited to 'src/imports/layouts') diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp index df64b593d9..eb61eb687f 100644 --- a/src/imports/layouts/qquicklayout.cpp +++ b/src/imports/layouts/qquicklayout.cpp @@ -95,6 +95,8 @@ QQuickLayoutAttached::QQuickLayoutAttached(QObject *parent) m_maximumWidth(std::numeric_limits::infinity()), m_maximumHeight(std::numeric_limits::infinity()), m_defaultMargins(0), + m_fallbackWidth(-1), + m_fallbackHeight(-1), m_row(-1), m_column(-1), m_rowSpan(1), @@ -1049,39 +1051,32 @@ void QQuickLayout::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSiz prefHeight = qCeil(item->implicitHeight()); // If that fails, make an ultimate fallback to width/height - - if (!info && (prefWidth < 0 || prefHeight < 0)) - info = attachedLayoutObject(item); - - if (useFallbackToWidthOrHeight && info) { - /* This block is a bit hacky, but if we want to support using width/height - as preferred size hints in layouts, (which we think most people expect), - we only want to use the initial width. - This is because the width will change due to layout rearrangement, and the preferred - width should return the same value, regardless of the current width. - We therefore store the width in the implicitWidth attached property. - Since the layout listens to changes of implicitWidth, (it will - basically cause an invalidation of the layout), we have to disable that - notification while we set the implicit width (and height). - - Only use this fallback the first time the size hint is queried. Otherwise, we might - end up picking a width that is different than what was specified in the QML. + if (useFallbackToWidthOrHeight && !prefS.isValid()) { + /* If we want to support using width/height as preferred size hints in + layouts, (which we think most people expect), we only want to use the + initial width. + This is because the width will change due to layout rearrangement, + and the preferred width should return the same value, regardless of + the current width. + We therefore store this initial width in the attached layout object + and reuse it if needed rather than querying the width another time. + That means we need to ensure that an Layout attached object is available + by creating one if necessary. */ - if (prefWidth < 0 || prefHeight < 0) { - item->blockSignals(true); - if (prefWidth < 0) { - prefWidth = item->width(); - item->setImplicitWidth(prefWidth); - } - if (prefHeight < 0) { - prefHeight = item->height(); - item->setImplicitHeight(prefHeight); - } - item->blockSignals(false); - } - } + if (!info) + info = attachedLayoutObject(item); + auto updatePreferredSizes = [](qreal &cachedSize, qreal &attachedSize, qreal size) { + if (cachedSize < 0) { + if (attachedSize < 0) + attachedSize = size; + cachedSize = attachedSize; + } + }; + updatePreferredSizes(prefWidth, info->m_fallbackWidth, item->width()); + updatePreferredSizes(prefHeight, info->m_fallbackHeight, item->height()); + } // Normalize again after the implicit hints have been gathered expandSize(prefS, minS); diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h index 7984e1bd4d..1e9984e337 100644 --- a/src/imports/layouts/qquicklayout_p.h +++ b/src/imports/layouts/qquicklayout_p.h @@ -294,6 +294,9 @@ private: qreal m_defaultMargins; QMarginsF m_margins; + qreal m_fallbackWidth; + qreal m_fallbackHeight; + // GridLayout specific properties int m_row; int m_column; -- cgit v1.2.3