772void QQuickLayoutPrivate::applySizeHints()
const
774 Q_Q(
const QQuickLayout);
776 QQuickLayout *that =
const_cast<QQuickLayout*>(q);
777 QQuickLayoutAttached *info = attachedLayoutObject(that,
true);
779 const QSizeF min = q->sizeHint(Qt::MinimumSize);
780 const QSizeF max = q->sizeHint(Qt::MaximumSize);
781 const QSizeF pref = q->sizeHint(Qt::PreferredSize);
782 info->setMinimumImplicitSize(min);
783 info->setMaximumImplicitSize(max);
784 that->setImplicitSize(pref.width(), pref.height());
841void QQuickLayout::maybeSubscribeToBaseLineOffsetChanges(QQuickItem *item)
843 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
845 if (info->alignment() == Qt::AlignBaseline &&
static_cast<QQuickLayout*>(item->parentItem()) ==
this) {
846 qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)),
this, QQuickLayout, SLOT(invalidateSenderItem()));
848 qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)),
this, QQuickLayout, SLOT(invalidateSenderItem()));
894void QQuickLayout::ensureLayoutItemsUpdated(EnsureLayoutItemsUpdatedOptions options)
const
896 Q_D(
const QQuickLayout);
899 qCDebug(lcQuickLayouts) <<
"ENTER QQuickLayout::ensureLayoutItemsUpdated()" <<
this << options;
900 QQuickLayoutPrivate *priv =
const_cast<QQuickLayoutPrivate*>(d);
905 const_cast<QQuickLayout*>(
this)->updateLayoutItems();
910 if (options & Recursive) {
911 for (
int i = 0; i < itemCount(); ++i) {
912 QQuickItem *itm = itemAt(i);
913 if (QQuickLayout *lay = qobject_cast<QQuickLayout*>(itm)) {
914 lay->ensureLayoutItemsUpdated(options);
920 if (options & ApplySizeHints)
921 priv->applySizeHints();
922 qCDebug(lcQuickLayouts) <<
"LEAVE QQuickLayout::ensureLayoutItemsUpdated()" <<
this;
926void QQuickLayout::itemChange(ItemChange change,
const ItemChangeData &value)
928 if (change == ItemChildAddedChange) {
930 QQuickItem *item = value.item;
931 maybeSubscribeToBaseLineOffsetChanges(item);
932 QQuickItemPrivate::get(item)->addItemChangeListener(
this, changeTypes);
933 d->m_hasItemChangeListeners =
true;
934 qCDebug(lcQuickLayouts) <<
"ChildAdded" << item;
937 }
else if (change == ItemChildRemovedChange) {
938 QQuickItem *item = value.item;
939 maybeSubscribeToBaseLineOffsetChanges(item);
940 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
941 qCDebug(lcQuickLayouts) <<
"ChildRemoved" << item;
945 QQuickItem::itemChange(change, value);
982void QQuickLayout::deactivateRecur()
984 if (d_func()->m_hasItemChangeListeners) {
985 ensureLayoutItemsUpdated();
986 for (
int i = 0; i < itemCount(); ++i) {
987 QQuickItem *item = itemAt(i);
991 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
992 if (QQuickLayout *layout = qobject_cast<QQuickLayout*>(item))
993 layout->deactivateRecur();
995 d_func()->m_hasItemChangeListeners =
false;
1113 Q_ASSERT(which == Qt::MinimumSize || which == Qt::MaximumSize);
1115 const QSizeF constraint(which == Qt::MinimumSize
1116 ? QSizeF(info->minimumWidth(), info->minimumHeight())
1117 : QSizeF(info->maximumWidth(), info->maximumHeight()));
1119 if (!info->isExtentExplicitlySet(Qt::Horizontal, which))
1120 combineHints(size->rwidth(), constraint.width());
1121 if (!info->isExtentExplicitlySet(Qt::Vertical, which))
1122 combineHints(size->rheight(), constraint.height());
1159void QQuickLayout::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **attachedInfo,
bool useFallbackToWidthOrHeight)
1161 for (
int i = 0; i < Qt::NSizeHints; ++i)
1162 cachedSizeHints[i] = QSizeF();
1163 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
1167 SizeGetter call[NSizes];
1170 static Getters horGetters = {
1171 {&QQuickLayoutAttached::minimumWidth, &QQuickLayoutAttached::preferredWidth, &QQuickLayoutAttached::maximumWidth},
1174 static Getters verGetters = {
1175 {&QQuickLayoutAttached::minimumHeight, &QQuickLayoutAttached::preferredHeight, &QQuickLayoutAttached::maximumHeight}
1177 for (
int i = 0; i < NSizes; ++i) {
1178 SizeGetter getter = horGetters.call[i];
1181 if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i))
1182 cachedSizeHints[i].setWidth((info->*getter)());
1184 getter = verGetters.call[i];
1186 if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i))
1187 cachedSizeHints[i].setHeight((info->*getter)());
1191 QSizeF &minS = cachedSizeHints[Qt::MinimumSize];
1192 QSizeF &prefS = cachedSizeHints[Qt::PreferredSize];
1193 QSizeF &maxS = cachedSizeHints[Qt::MaximumSize];
1194 QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent];
1199 normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
1200 normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
1205 combineImplicitHints(info, Qt::MaximumSize, &maxS);
1206 combineSize(maxS, QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity()));
1208 expandSize(maxS, prefS);
1209 expandSize(maxS, minS);
1212 combineImplicitHints(info, Qt::MinimumSize, &minS);
1213 expandSize(minS, QSizeF(0,0));
1214 boundSize(minS, prefS);
1215 boundSize(minS, maxS);
1219 qreal &prefWidth = prefS.rwidth();
1220 qreal &prefHeight = prefS.rheight();
1221 if (prefWidth < 0 && item->implicitWidth() > 0)
1222 prefWidth = qCeil(item->implicitWidth());
1223 if (prefHeight < 0 && item->implicitHeight() > 0)
1224 prefHeight = qCeil(item->implicitHeight());
1227 if (useFallbackToWidthOrHeight && !prefS.isValid()) {
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1240 info = attachedLayoutObject(item);
1242 auto updatePreferredSizes = [](qreal &cachedSize, qreal &attachedSize, qreal size) {
1243 if (cachedSize < 0) {
1244 if (attachedSize < 0)
1245 attachedSize = size;
1247 cachedSize = attachedSize;
1250 updatePreferredSizes(prefWidth, info->m_fallbackWidth, item->width());
1251 updatePreferredSizes(prefHeight, info->m_fallbackHeight, item->height());
1255 expandSize(prefS, minS);
1256 boundSize(prefS, maxS);
1261 const qreal minimumDescent = minS.height() - item->baselineOffset();
1262 descentS.setHeight(minimumDescent);
1265 QMarginsF margins = info->qMargins();
1266 QSizeF extraMargins(margins.left() + margins.right(), margins.top() + margins.bottom());
1267 minS += extraMargins;
1268 prefS += extraMargins;
1269 maxS += extraMargins;
1270 descentS += extraMargins;
1273 *attachedInfo = info;
1281QLayoutPolicy::Policy QQuickLayout::effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info)
1283 QLayoutPolicy::Policy pol{QLayoutPolicy::Fixed};
1286 if (orientation == Qt::Horizontal) {
1287 isSet = info->isFillWidthSet();
1288 if (isSet && info->fillWidth())
1289 pol = QLayoutPolicy::Preferred;
1291 isSet = info->isFillHeightSet();
1292 if (isSet && info->fillHeight())
1293 pol = QLayoutPolicy::Preferred;
1296 if (!isSet && item) {
1297 auto effectiveUseDefaultSizePolicy = [info]() {
1298 return info ? info->useDefaultSizePolicy() == QQuickLayout::SizePolicyImplicit
1299 : QGuiApplication::testAttribute(Qt::AA_QtQuickUseDefaultSizePolicy);
1301 if (qobject_cast<QQuickLayout*>(item)) {
1302 pol = QLayoutPolicy::Preferred;
1303 }
else if (effectiveUseDefaultSizePolicy()) {
1304 QLayoutPolicy sizePolicy = QQuickItemPrivate::get(item)->sizePolicy();
1305 pol = (orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy() : sizePolicy.verticalPolicy();
1319void QQuickLayout::dumpLayoutTreeRecursive(
int level, QString &buf)
const
1321 auto formatLine = [&level](
const char *fmt) -> QString {
1322 QString ss(level *4, QLatin1Char(
' '));
1323 return ss + QLatin1String(fmt) + QLatin1Char(
'\n');
1326 auto f2s = [](qreal f) {
1327 return QString::number(f);
1329 auto b2s = [](
bool b) {
1330 static const char *strBool[] = {
"false",
"true"};
1331 return QLatin1String(strBool[
int(b)]);
1334 buf += formatLine(
"%1 {").arg(QQmlMetaType::prettyTypeName(
this));
1336 buf += formatLine(
"// Effective calculated values:");
1337 buf += formatLine(
"sizeHintDirty: %2").arg(invalidated());
1338 QSizeF min = sizeHint(Qt::MinimumSize);
1339 buf += formatLine(
"sizeHint.min : [%1, %2]").arg(f2s(min.width()), 5).arg(min.height(), 5);
1340 QSizeF pref = sizeHint(Qt::PreferredSize);
1341 buf += formatLine(
"sizeHint.pref: [%1, %2]").arg(pref.width(), 5).arg(pref.height(), 5);
1342 QSizeF max = sizeHint(Qt::MaximumSize);
1343 buf += formatLine(
"sizeHint.max : [%1, %2]").arg(f2s(max.width()), 5).arg(f2s(max.height()), 5);
1345 for (QQuickItem *item : childItems()) {
1346 buf += QLatin1Char(
'\n');
1347 if (QQuickLayout *childLayout = qobject_cast<QQuickLayout*>(item)) {
1348 childLayout->dumpLayoutTreeRecursive(level, buf);
1350 buf += formatLine(
"%1 {").arg(QQmlMetaType::prettyTypeName(item));
1352 if (item->implicitWidth() > 0)
1353 buf += formatLine(
"implicitWidth: %1").arg(f2s(item->implicitWidth()));
1354 if (item->implicitHeight() > 0)
1355 buf += formatLine(
"implicitHeight: %1").arg(f2s(item->implicitHeight()));
1359 QQuickLayoutAttached *info = attachedLayoutObject(item,
false);
1361 min = QSizeF(info->minimumWidth(), info->minimumHeight());
1362 pref = QSizeF(info->preferredWidth(), info->preferredHeight());
1363 max = QSizeF(info->maximumWidth(), info->maximumHeight());
1364 if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MinimumSize))
1365 buf += formatLine(
"Layout.minimumWidth: %1").arg(f2s(min.width()));
1366 if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MinimumSize))
1367 buf += formatLine(
"Layout.minimumHeight: %1").arg(f2s(min.height()));
1368 if (pref.width() >= 0)
1369 buf += formatLine(
"Layout.preferredWidth: %1").arg(f2s(pref.width()));
1370 if (pref.height() >= 0)
1371 buf += formatLine(
"Layout.preferredHeight: %1").arg(f2s(pref.height()));
1372 if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MaximumSize))
1373 buf += formatLine(
"Layout.maximumWidth: %1").arg(f2s(max.width()));
1374 if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MaximumSize))
1375 buf += formatLine(
"Layout.maximumHeight: %1").arg(f2s(max.height()));
1377 if (info->isFillWidthSet())
1378 buf += formatLine(
"Layout.fillWidth: %1").arg(b2s(info->fillWidth()));
1379 if (info->isFillHeightSet())
1380 buf += formatLine(
"Layout.fillHeight: %1").arg(b2s(info->fillHeight()));
1383 buf += formatLine(
"}");
1387 buf += formatLine(
"}");