777void QQuickLayoutPrivate::applySizeHints()
const
779 Q_Q(
const QQuickLayout);
781 QQuickLayout *that =
const_cast<QQuickLayout*>(q);
782 QQuickLayoutAttached *info = attachedLayoutObject(that,
true);
784 const QSizeF min = q->sizeHint(Qt::MinimumSize);
785 const QSizeF max = q->sizeHint(Qt::MaximumSize);
786 const QSizeF pref = q->sizeHint(Qt::PreferredSize);
787 info->setMinimumImplicitSize(min);
788 info->setMaximumImplicitSize(max);
789 that->setImplicitSize(pref.width(), pref.height());
846void QQuickLayout::maybeSubscribeToBaseLineOffsetChanges(QQuickItem *item)
848 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
850 if (info->alignment() == Qt::AlignBaseline &&
static_cast<QQuickLayout*>(item->parentItem()) ==
this) {
851 qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)),
this, QQuickLayout, SLOT(invalidateSenderItem()));
853 qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)),
this, QQuickLayout, SLOT(invalidateSenderItem()));
899void QQuickLayout::ensureLayoutItemsUpdated(EnsureLayoutItemsUpdatedOptions options)
const
901 Q_D(
const QQuickLayout);
904 qCDebug(lcQuickLayouts) <<
"ENTER QQuickLayout::ensureLayoutItemsUpdated()" <<
this << options;
905 QQuickLayoutPrivate *priv =
const_cast<QQuickLayoutPrivate*>(d);
910 const_cast<QQuickLayout*>(
this)->updateLayoutItems();
915 if (options & Recursive) {
916 for (
int i = 0; i < itemCount(); ++i) {
917 QQuickItem *itm = itemAt(i);
918 if (QQuickLayout *lay = qobject_cast<QQuickLayout*>(itm)) {
919 lay->ensureLayoutItemsUpdated(options);
925 if (options & ApplySizeHints)
926 priv->applySizeHints();
927 qCDebug(lcQuickLayouts) <<
"LEAVE QQuickLayout::ensureLayoutItemsUpdated()" <<
this;
931void QQuickLayout::itemChange(ItemChange change,
const ItemChangeData &value)
933 if (change == ItemChildAddedChange) {
935 QQuickItem *item = value.item;
936 maybeSubscribeToBaseLineOffsetChanges(item);
937 QQuickItemPrivate::get(item)->addItemChangeListener(
this, changeTypes);
938 d->m_hasItemChangeListeners =
true;
939 qCDebug(lcQuickLayouts) <<
"ChildAdded" << item;
942 }
else if (change == ItemChildRemovedChange) {
943 QQuickItem *item = value.item;
944 maybeSubscribeToBaseLineOffsetChanges(item);
945 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
946 qCDebug(lcQuickLayouts) <<
"ChildRemoved" << item;
950 QQuickItem::itemChange(change, value);
953void QQuickLayout::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
956 qCDebug(lcQuickLayouts) <<
"QQuickLayout::geometryChange"
957 << oldGeometry <<
"-->" << newGeometry;
959 QQuickItem::geometryChange(newGeometry, oldGeometry);
961 if ((invalidated() && !qobject_cast<QQuickLayout *>(parentItem())) ||
962 d->m_disableRearrange || !isReady())
970 const qreal w = d->width.valueBypassingBindings();
971 const qreal h = d->height.valueBypassingBindings();
972 const QSizeF currentSize(w, h);
973 if (currentSize != newGeometry.size()) {
974 qCDebug(lcQuickLayouts) <<
"QQuickItem::geometryChange resulted"
975 <<
"in size change from" << newGeometry.size() <<
"to"
976 << currentSize <<
"; layout should already be up to date.";
980 rearrange(newGeometry.size());
1005void QQuickLayout::deactivateRecur()
1007 if (d_func()->m_hasItemChangeListeners) {
1008 ensureLayoutItemsUpdated();
1009 for (
int i = 0; i < itemCount(); ++i) {
1010 QQuickItem *item = itemAt(i);
1014 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
1015 if (QQuickLayout *layout = qobject_cast<QQuickLayout*>(item))
1016 layout->deactivateRecur();
1018 d_func()->m_hasItemChangeListeners =
false;
1136 Q_ASSERT(which == Qt::MinimumSize || which == Qt::MaximumSize);
1138 const QSizeF constraint(which == Qt::MinimumSize
1139 ? QSizeF(info->minimumWidth(), info->minimumHeight())
1140 : QSizeF(info->maximumWidth(), info->maximumHeight()));
1142 if (!info->isExtentExplicitlySet(Qt::Horizontal, which))
1143 combineHints(size->rwidth(), constraint.width());
1144 if (!info->isExtentExplicitlySet(Qt::Vertical, which))
1145 combineHints(size->rheight(), constraint.height());
1182void QQuickLayout::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **attachedInfo,
bool useFallbackToWidthOrHeight)
1184 for (
int i = 0; i < Qt::NSizeHints; ++i)
1185 cachedSizeHints[i] = QSizeF();
1186 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
1190 SizeGetter call[NSizes];
1193 static Getters horGetters = {
1194 {&QQuickLayoutAttached::minimumWidth, &QQuickLayoutAttached::preferredWidth, &QQuickLayoutAttached::maximumWidth},
1197 static Getters verGetters = {
1198 {&QQuickLayoutAttached::minimumHeight, &QQuickLayoutAttached::preferredHeight, &QQuickLayoutAttached::maximumHeight}
1200 for (
int i = 0; i < NSizes; ++i) {
1201 SizeGetter getter = horGetters.call[i];
1204 if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i))
1205 cachedSizeHints[i].setWidth((info->*getter)());
1207 getter = verGetters.call[i];
1209 if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i))
1210 cachedSizeHints[i].setHeight((info->*getter)());
1214 QSizeF &minS = cachedSizeHints[Qt::MinimumSize];
1215 QSizeF &prefS = cachedSizeHints[Qt::PreferredSize];
1216 QSizeF &maxS = cachedSizeHints[Qt::MaximumSize];
1217 QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent];
1222 normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
1223 normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
1228 combineImplicitHints(info, Qt::MaximumSize, &maxS);
1229 combineSize(maxS, QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity()));
1231 expandSize(maxS, prefS);
1232 expandSize(maxS, minS);
1235 combineImplicitHints(info, Qt::MinimumSize, &minS);
1236 expandSize(minS, QSizeF(0,0));
1237 boundSize(minS, prefS);
1238 boundSize(minS, maxS);
1242 qreal &prefWidth = prefS.rwidth();
1243 qreal &prefHeight = prefS.rheight();
1244 if (prefWidth < 0 && item->implicitWidth() > 0)
1245 prefWidth = qCeil(item->implicitWidth());
1246 if (prefHeight < 0 && item->implicitHeight() > 0)
1247 prefHeight = qCeil(item->implicitHeight());
1250 if (useFallbackToWidthOrHeight && !prefS.isValid()) {
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1263 info = attachedLayoutObject(item);
1265 auto updatePreferredSizes = [](qreal &cachedSize, qreal &attachedSize, qreal size) {
1266 if (cachedSize < 0) {
1267 if (attachedSize < 0)
1268 attachedSize = size;
1270 cachedSize = attachedSize;
1273 updatePreferredSizes(prefWidth, info->m_fallbackWidth, item->width());
1274 updatePreferredSizes(prefHeight, info->m_fallbackHeight, item->height());
1278 expandSize(prefS, minS);
1279 boundSize(prefS, maxS);
1284 const qreal minimumDescent = minS.height() - item->baselineOffset();
1285 descentS.setHeight(minimumDescent);
1288 QMarginsF margins = info->qMargins();
1289 QSizeF extraMargins(margins.left() + margins.right(), margins.top() + margins.bottom());
1290 minS += extraMargins;
1291 prefS += extraMargins;
1292 maxS += extraMargins;
1293 descentS += extraMargins;
1296 *attachedInfo = info;
1304QLayoutPolicy::Policy QQuickLayout::effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info)
1306 QLayoutPolicy::Policy pol{QLayoutPolicy::Fixed};
1309 if (orientation == Qt::Horizontal) {
1310 isSet = info->isFillWidthSet();
1311 if (isSet && info->fillWidth())
1312 pol = QLayoutPolicy::Preferred;
1314 isSet = info->isFillHeightSet();
1315 if (isSet && info->fillHeight())
1316 pol = QLayoutPolicy::Preferred;
1319 if (!isSet && item) {
1320 auto effectiveUseDefaultSizePolicy = [info]() {
1321 return info ? info->useDefaultSizePolicy() == QQuickLayout::SizePolicyImplicit
1322 : QGuiApplication::testAttribute(Qt::AA_QtQuickUseDefaultSizePolicy);
1324 if (qobject_cast<QQuickLayout*>(item)) {
1325 pol = QLayoutPolicy::Preferred;
1326 }
else if (effectiveUseDefaultSizePolicy()) {
1327 QLayoutPolicy sizePolicy = QQuickItemPrivate::get(item)->sizePolicy();
1328 pol = (orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy() : sizePolicy.verticalPolicy();
1342void QQuickLayout::dumpLayoutTreeRecursive(
int level, QString &buf)
const
1344 auto formatLine = [&level](
const char *fmt) -> QString {
1345 QString ss(level *4, QLatin1Char(
' '));
1346 return ss + QLatin1String(fmt) + QLatin1Char(
'\n');
1349 auto f2s = [](qreal f) {
1350 return QString::number(f);
1352 auto b2s = [](
bool b) {
1353 static const char *strBool[] = {
"false",
"true"};
1354 return QLatin1String(strBool[
int(b)]);
1357 buf += formatLine(
"%1 {").arg(QQmlMetaType::prettyTypeName(
this));
1359 buf += formatLine(
"// Effective calculated values:");
1360 buf += formatLine(
"sizeHintDirty: %2").arg(invalidated());
1361 QSizeF min = sizeHint(Qt::MinimumSize);
1362 buf += formatLine(
"sizeHint.min : [%1, %2]").arg(f2s(min.width()), 5).arg(min.height(), 5);
1363 QSizeF pref = sizeHint(Qt::PreferredSize);
1364 buf += formatLine(
"sizeHint.pref: [%1, %2]").arg(pref.width(), 5).arg(pref.height(), 5);
1365 QSizeF max = sizeHint(Qt::MaximumSize);
1366 buf += formatLine(
"sizeHint.max : [%1, %2]").arg(f2s(max.width()), 5).arg(f2s(max.height()), 5);
1368 for (QQuickItem *item : childItems()) {
1369 buf += QLatin1Char(
'\n');
1370 if (QQuickLayout *childLayout = qobject_cast<QQuickLayout*>(item)) {
1371 childLayout->dumpLayoutTreeRecursive(level, buf);
1373 buf += formatLine(
"%1 {").arg(QQmlMetaType::prettyTypeName(item));
1375 if (item->implicitWidth() > 0)
1376 buf += formatLine(
"implicitWidth: %1").arg(f2s(item->implicitWidth()));
1377 if (item->implicitHeight() > 0)
1378 buf += formatLine(
"implicitHeight: %1").arg(f2s(item->implicitHeight()));
1382 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
1384 min = QSizeF(info->minimumWidth(), info->minimumHeight());
1385 pref = QSizeF(info->preferredWidth(), info->preferredHeight());
1386 max = QSizeF(info->maximumWidth(), info->maximumHeight());
1387 if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MinimumSize))
1388 buf += formatLine(
"Layout.minimumWidth: %1").arg(f2s(min.width()));
1389 if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MinimumSize))
1390 buf += formatLine(
"Layout.minimumHeight: %1").arg(f2s(min.height()));
1391 if (pref.width() >= 0)
1392 buf += formatLine(
"Layout.preferredWidth: %1").arg(f2s(pref.width()));
1393 if (pref.height() >= 0)
1394 buf += formatLine(
"Layout.preferredHeight: %1").arg(f2s(pref.height()));
1395 if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MaximumSize))
1396 buf += formatLine(
"Layout.maximumWidth: %1").arg(f2s(max.width()));
1397 if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MaximumSize))
1398 buf += formatLine(
"Layout.maximumHeight: %1").arg(f2s(max.height()));
1400 if (info->isFillWidthSet())
1401 buf += formatLine(
"Layout.fillWidth: %1").arg(b2s(info->fillWidth()));
1402 if (info->isFillHeightSet())
1403 buf += formatLine(
"Layout.fillHeight: %1").arg(b2s(info->fillHeight()));
1406 buf += formatLine(
"}");
1410 buf += formatLine(
"}");