776void QQuickLayoutPrivate::applySizeHints()
const
778 Q_Q(
const QQuickLayout);
780 QQuickLayout *that =
const_cast<QQuickLayout*>(q);
781 QQuickLayoutAttached *info = attachedLayoutObject(that,
true);
783 const QSizeF min = q->sizeHint(Qt::MinimumSize);
784 const QSizeF max = q->sizeHint(Qt::MaximumSize);
785 const QSizeF pref = q->sizeHint(Qt::PreferredSize);
786 info->setMinimumImplicitSize(min);
787 info->setMaximumImplicitSize(max);
788 that->setImplicitSize(pref.width(), pref.height());
845void QQuickLayout::maybeSubscribeToBaseLineOffsetChanges(QQuickItem *item)
847 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
849 if (info->alignment() == Qt::AlignBaseline &&
static_cast<QQuickLayout*>(item->parentItem()) ==
this) {
850 qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)),
this, QQuickLayout, SLOT(invalidateSenderItem()));
852 qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)),
this, QQuickLayout, SLOT(invalidateSenderItem()));
898void QQuickLayout::ensureLayoutItemsUpdated(EnsureLayoutItemsUpdatedOptions options)
const
900 Q_D(
const QQuickLayout);
903 qCDebug(lcQuickLayouts) <<
"ENTER QQuickLayout::ensureLayoutItemsUpdated()" <<
this << options;
904 QQuickLayoutPrivate *priv =
const_cast<QQuickLayoutPrivate*>(d);
909 const_cast<QQuickLayout*>(
this)->updateLayoutItems();
914 if (options & Recursive) {
915 for (
int i = 0; i < itemCount(); ++i) {
916 QQuickItem *itm = itemAt(i);
917 if (QQuickLayout *lay = qobject_cast<QQuickLayout*>(itm)) {
918 lay->ensureLayoutItemsUpdated(options);
924 if (options & ApplySizeHints)
925 priv->applySizeHints();
926 qCDebug(lcQuickLayouts) <<
"LEAVE QQuickLayout::ensureLayoutItemsUpdated()" <<
this;
930void QQuickLayout::itemChange(ItemChange change,
const ItemChangeData &value)
932 if (change == ItemChildAddedChange) {
934 QQuickItem *item = value.item;
935 maybeSubscribeToBaseLineOffsetChanges(item);
936 QQuickItemPrivate::get(item)->addItemChangeListener(
this, changeTypes);
937 d->m_hasItemChangeListeners =
true;
938 qCDebug(lcQuickLayouts) <<
"ChildAdded" << item;
941 }
else if (change == ItemChildRemovedChange) {
942 QQuickItem *item = value.item;
943 maybeSubscribeToBaseLineOffsetChanges(item);
944 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
945 qCDebug(lcQuickLayouts) <<
"ChildRemoved" << item;
949 QQuickItem::itemChange(change, value);
952void QQuickLayout::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
955 qCDebug(lcQuickLayouts) <<
"QQuickLayout::geometryChange"
956 << oldGeometry <<
"-->" << newGeometry;
958 QQuickItem::geometryChange(newGeometry, oldGeometry);
960 if ((invalidated() && !qobject_cast<QQuickLayout *>(parentItem())) ||
961 d->m_disableRearrange || !isReady())
969 const qreal w = d->width.valueBypassingBindings();
970 const qreal h = d->height.valueBypassingBindings();
971 const QSizeF currentSize(w, h);
972 if (currentSize != newGeometry.size()) {
973 qCDebug(lcQuickLayouts) <<
"QQuickItem::geometryChange resulted"
974 <<
"in size change from" << newGeometry.size() <<
"to"
975 << currentSize <<
"; layout should already be up to date.";
979 rearrange(newGeometry.size());
1004void QQuickLayout::deactivateRecur()
1006 if (d_func()->m_hasItemChangeListeners) {
1007 ensureLayoutItemsUpdated();
1008 for (
int i = 0; i < itemCount(); ++i) {
1009 QQuickItem *item = itemAt(i);
1013 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
1014 if (QQuickLayout *layout = qobject_cast<QQuickLayout*>(item))
1015 layout->deactivateRecur();
1017 d_func()->m_hasItemChangeListeners =
false;
1135 Q_ASSERT(which == Qt::MinimumSize || which == Qt::MaximumSize);
1137 const QSizeF constraint(which == Qt::MinimumSize
1138 ? QSizeF(info->minimumWidth(), info->minimumHeight())
1139 : QSizeF(info->maximumWidth(), info->maximumHeight()));
1141 if (!info->isExtentExplicitlySet(Qt::Horizontal, which))
1142 combineHints(size->rwidth(), constraint.width());
1143 if (!info->isExtentExplicitlySet(Qt::Vertical, which))
1144 combineHints(size->rheight(), constraint.height());
1181void QQuickLayout::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **attachedInfo,
bool useFallbackToWidthOrHeight)
1183 for (
int i = 0; i < Qt::NSizeHints; ++i)
1184 cachedSizeHints[i] = QSizeF();
1185 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
1189 SizeGetter call[NSizes];
1192 static Getters horGetters = {
1193 {&QQuickLayoutAttached::minimumWidth, &QQuickLayoutAttached::preferredWidth, &QQuickLayoutAttached::maximumWidth},
1196 static Getters verGetters = {
1197 {&QQuickLayoutAttached::minimumHeight, &QQuickLayoutAttached::preferredHeight, &QQuickLayoutAttached::maximumHeight}
1199 for (
int i = 0; i < NSizes; ++i) {
1200 SizeGetter getter = horGetters.call[i];
1203 if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i))
1204 cachedSizeHints[i].setWidth((info->*getter)());
1206 getter = verGetters.call[i];
1208 if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i))
1209 cachedSizeHints[i].setHeight((info->*getter)());
1213 QSizeF &minS = cachedSizeHints[Qt::MinimumSize];
1214 QSizeF &prefS = cachedSizeHints[Qt::PreferredSize];
1215 QSizeF &maxS = cachedSizeHints[Qt::MaximumSize];
1216 QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent];
1221 normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
1222 normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
1227 combineImplicitHints(info, Qt::MaximumSize, &maxS);
1228 combineSize(maxS, QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity()));
1230 expandSize(maxS, prefS);
1231 expandSize(maxS, minS);
1234 combineImplicitHints(info, Qt::MinimumSize, &minS);
1235 expandSize(minS, QSizeF(0,0));
1236 boundSize(minS, prefS);
1237 boundSize(minS, maxS);
1241 qreal &prefWidth = prefS.rwidth();
1242 qreal &prefHeight = prefS.rheight();
1243 if (prefWidth < 0 && item->implicitWidth() > 0)
1244 prefWidth = qCeil(item->implicitWidth());
1245 if (prefHeight < 0 && item->implicitHeight() > 0)
1246 prefHeight = qCeil(item->implicitHeight());
1249 if (useFallbackToWidthOrHeight && !prefS.isValid()) {
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1262 info = attachedLayoutObject(item);
1264 auto updatePreferredSizes = [](qreal &cachedSize, qreal &attachedSize, qreal size) {
1265 if (cachedSize < 0) {
1266 if (attachedSize < 0)
1267 attachedSize = size;
1269 cachedSize = attachedSize;
1272 updatePreferredSizes(prefWidth, info->m_fallbackWidth, item->width());
1273 updatePreferredSizes(prefHeight, info->m_fallbackHeight, item->height());
1277 expandSize(prefS, minS);
1278 boundSize(prefS, maxS);
1283 const qreal minimumDescent = minS.height() - item->baselineOffset();
1284 descentS.setHeight(minimumDescent);
1287 QMarginsF margins = info->qMargins();
1288 QSizeF extraMargins(margins.left() + margins.right(), margins.top() + margins.bottom());
1289 minS += extraMargins;
1290 prefS += extraMargins;
1291 maxS += extraMargins;
1292 descentS += extraMargins;
1295 *attachedInfo = info;
1303QLayoutPolicy::Policy QQuickLayout::effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info)
1305 QLayoutPolicy::Policy pol{QLayoutPolicy::Fixed};
1308 if (orientation == Qt::Horizontal) {
1309 isSet = info->isFillWidthSet();
1310 if (isSet && info->fillWidth())
1311 pol = QLayoutPolicy::Preferred;
1313 isSet = info->isFillHeightSet();
1314 if (isSet && info->fillHeight())
1315 pol = QLayoutPolicy::Preferred;
1318 if (!isSet && item) {
1319 auto effectiveUseDefaultSizePolicy = [info]() {
1320 return info ? info->useDefaultSizePolicy() == QQuickLayout::SizePolicyImplicit
1321 : QGuiApplication::testAttribute(Qt::AA_QtQuickUseDefaultSizePolicy);
1323 if (qobject_cast<QQuickLayout*>(item)) {
1324 pol = QLayoutPolicy::Preferred;
1325 }
else if (effectiveUseDefaultSizePolicy()) {
1326 QLayoutPolicy sizePolicy = QQuickItemPrivate::get(item)->sizePolicy();
1327 pol = (orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy() : sizePolicy.verticalPolicy();
1341void QQuickLayout::dumpLayoutTreeRecursive(
int level, QString &buf)
const
1343 auto formatLine = [&level](
const char *fmt) -> QString {
1344 QString ss(level *4, QLatin1Char(
' '));
1345 return ss + QLatin1String(fmt) + QLatin1Char(
'\n');
1348 auto f2s = [](qreal f) {
1349 return QString::number(f);
1351 auto b2s = [](
bool b) {
1352 static const char *strBool[] = {
"false",
"true"};
1353 return QLatin1String(strBool[
int(b)]);
1356 buf += formatLine(
"%1 {").arg(QQmlMetaType::prettyTypeName(
this));
1358 buf += formatLine(
"// Effective calculated values:");
1359 buf += formatLine(
"sizeHintDirty: %2").arg(invalidated());
1360 QSizeF min = sizeHint(Qt::MinimumSize);
1361 buf += formatLine(
"sizeHint.min : [%1, %2]").arg(f2s(min.width()), 5).arg(min.height(), 5);
1362 QSizeF pref = sizeHint(Qt::PreferredSize);
1363 buf += formatLine(
"sizeHint.pref: [%1, %2]").arg(pref.width(), 5).arg(pref.height(), 5);
1364 QSizeF max = sizeHint(Qt::MaximumSize);
1365 buf += formatLine(
"sizeHint.max : [%1, %2]").arg(f2s(max.width()), 5).arg(f2s(max.height()), 5);
1367 for (QQuickItem *item : childItems()) {
1368 buf += QLatin1Char(
'\n');
1369 if (QQuickLayout *childLayout = qobject_cast<QQuickLayout*>(item)) {
1370 childLayout->dumpLayoutTreeRecursive(level, buf);
1372 buf += formatLine(
"%1 {").arg(QQmlMetaType::prettyTypeName(item));
1374 if (item->implicitWidth() > 0)
1375 buf += formatLine(
"implicitWidth: %1").arg(f2s(item->implicitWidth()));
1376 if (item->implicitHeight() > 0)
1377 buf += formatLine(
"implicitHeight: %1").arg(f2s(item->implicitHeight()));
1381 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
1383 min = QSizeF(info->minimumWidth(), info->minimumHeight());
1384 pref = QSizeF(info->preferredWidth(), info->preferredHeight());
1385 max = QSizeF(info->maximumWidth(), info->maximumHeight());
1386 if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MinimumSize))
1387 buf += formatLine(
"Layout.minimumWidth: %1").arg(f2s(min.width()));
1388 if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MinimumSize))
1389 buf += formatLine(
"Layout.minimumHeight: %1").arg(f2s(min.height()));
1390 if (pref.width() >= 0)
1391 buf += formatLine(
"Layout.preferredWidth: %1").arg(f2s(pref.width()));
1392 if (pref.height() >= 0)
1393 buf += formatLine(
"Layout.preferredHeight: %1").arg(f2s(pref.height()));
1394 if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MaximumSize))
1395 buf += formatLine(
"Layout.maximumWidth: %1").arg(f2s(max.width()));
1396 if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MaximumSize))
1397 buf += formatLine(
"Layout.maximumHeight: %1").arg(f2s(max.height()));
1399 if (info->isFillWidthSet())
1400 buf += formatLine(
"Layout.fillWidth: %1").arg(b2s(info->fillWidth()));
1401 if (info->isFillHeightSet())
1402 buf += formatLine(
"Layout.fillHeight: %1").arg(b2s(info->fillHeight()));
1405 buf += formatLine(
"}");
1409 buf += formatLine(
"}");