1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtQuickLayouts/private/qquickflexboxlayout_p.h>
5#include <QtQuickLayouts/private/qquickflexboxlayoutengine_p.h>
6#include <QtQml/qqmlinfo.h>
7
8/*!
9 \qmltype FlexboxLayout
10 //! \nativetype QQuickFlexboxLayout
11 \inherits Item
12 \inqmlmodule QtQuick.Layouts
13 \ingroup layouts
14 \since 6.10
15 \preliminary
16 \brief The FlexboxLayout QML construct provides a flex layout for the
17 quick items.
18
19 The FlexboxLayout enables to layout the quick items in a flexible way as
20 similar to that of
21 \l {https://www.w3.org/TR/css-flexbox-1/}{CSS Flexible Box Layout}.
22 Internally Qt FlexboxLayout uses the \l{qtquick-attribution-yoga.html}{yoga engine}
23 to derive the geometry of
24 the flex items. The \l {https://www.yogalayout.dev/}{yoga library} is a
25 subset of the
26 \l {https://www.w3.org/TR/css-flexbox-1/}{CSS Flexible Box Layout}. Thus
27 FlexboxLayout can be limited to the feature as supported in the
28 \l {https://www.yogalayout.dev/}{yoga library}.
29
30 \note The FlexboxLayout adheres to yoga library version 2.0 for its
31 features.
32
33 The items within the FlexboxLayout can be configured with preferred,
34 minimum and maximum sizes through the existing layout attached properties.
35 For instance, if the item within the FlexboxLayout need to be stretched,
36 the layout attached property \l{Layout::fillWidth}{Layout.fillWidth} or
37 \l{Layout::fillHeight}{Layout.fillHeight} can be set.
38
39 Items in a FlexboxLayout support these attached properties:
40 \list
41 \li \l{FlexboxLayout::alignSelf}{FlexboxLayout.alignSelf}
42 \li \l{Layout::minimumWidth}{Layout.minimumWidth}
43 \li \l{Layout::minimumHeight}{Layout.minimumHeight}
44 \li \l{Layout::preferredWidth}{Layout.preferredWidth}
45 \li \l{Layout::preferredHeight}{Layout.preferredHeight}
46 \li \l{Layout::maximumWidth}{Layout.maximumWidth}
47 \li \l{Layout::maximumHeight}{Layout.maximumHeight}
48 \li \l{Layout::fillWidth}{Layout.fillWidth}
49 \li \l{Layout::fillHeight}{Layout.fillHeight}
50 \li \l{Layout::margins}{Layout.margins}
51 \li \l{Layout::leftMargin}{Layout.leftMargin}
52 \li \l{Layout::rightMargin}{Layout.rightMargin}
53 \li \l{Layout::topMargin}{Layout.topMargin}
54 \li \l{Layout::bottomMargin}{Layout.bottomMargin}
55 \endlist
56
57 Read more about attached properties \l{QML Object Attributes}{here}.
58 \sa ColumnLayout
59 \sa GridLayout
60 \sa RowLayout
61 \sa {QtQuick.Controls::StackView}{StackView}
62 \sa {Qt Quick Layouts Overview}
63
64 To be able to use this type more efficiently, it is recommended that you
65 understand the general mechanism of the Qt Quick Layouts module. Refer to
66 \l{Qt Quick Layouts Overview} for more information.
67
68 \section1 Example Usage
69
70 The following snippet shows the minimalistic example of using QML
71 FlexboxLayout to arrange the rectangle items in more flexible way
72
73 \snippet layouts/simpleFlexboxLayout.qml layout-definition
74
75 \note This API is considered tech preview and may change or be removed in
76 future versions of Qt.
77*/
78
79QT_BEGIN_NAMESPACE
80
81class QQuickFlexboxLayoutPrivate : public QQuickLayoutPrivate
82{
83 Q_DECLARE_PUBLIC(QQuickFlexboxLayout)
84
85public:
86 QQuickFlexboxLayoutPrivate() : QQuickLayoutPrivate() {}
87 const QQuickFlexboxLayoutEngine& getFlexEngine() const { return m_flexEngine; }
88
89private:
90 QQuickFlexboxLayoutEngine m_flexEngine;
91 QQuickFlexboxLayout::FlexboxDirection m_direction = QQuickFlexboxLayout::Row;
92 QQuickFlexboxLayout::FlexboxWrap m_wrap = QQuickFlexboxLayout::NoWrap;
93 QQuickFlexboxLayout::FlexboxAlignment m_alignItems = QQuickFlexboxLayout::AlignStart;
94 // Align items within the layout in the multi-line containter (i.e. with
95 // wrap enabled) and its aligned to the cross axis of the flexbox layout
96 QQuickFlexboxLayout::FlexboxAlignment m_alignContent = QQuickFlexboxLayout::AlignStart;
97 // Align content item in the multi-line containter and its aligned to the
98 // main axis of the flexbox layout
99 QQuickFlexboxLayout::FlexboxJustify m_justifyContent = QQuickFlexboxLayout::JustifyStart;
100 qreal m_gap = 0.;
101 qreal m_rowGap = 0.;
102 qreal m_columnGap = 0.;
103 std::bitset<QQuickFlexboxLayout::GapMax> m_gapBitSet;
104};
105
106static QQuickFlexboxLayoutAttached *attachedFlexboxLayoutObject(QQuickItem *item, bool create = false)
107{
108 return static_cast<QQuickFlexboxLayoutAttached*>(
109 qmlAttachedPropertiesObject<QQuickFlexboxLayout>(obj: item, create));
110}
111
112QQuickFlexboxLayout::QQuickFlexboxLayout(QQuickItem *parent) :
113 QQuickLayout(*new QQuickFlexboxLayoutPrivate, parent)
114{
115 Q_D(QQuickFlexboxLayout);
116 d->m_flexEngine.setFlexboxParentItem(new QQuickFlexboxLayoutItem(this));
117}
118
119QQuickFlexboxLayout::~QQuickFlexboxLayout()
120{
121 Q_D(QQuickFlexboxLayout);
122 d->m_flexEngine.clearItems();
123}
124
125/*!
126 \qmlproperty enumeration FlexboxLayout::direction
127
128 This property holds the item layout direction within the flex box layout
129 and it defines the
130 \l {https://www.w3.org/TR/css-flexbox-1/#box-model}{main-axis}.
131
132 Possible values:
133
134 \value FlexboxLayout.Row (default) Items are laid out from
135 left to right.
136 \value FlexboxLayout.RowReversed Items are laid out from right to
137 left.
138 \value FlexboxLayout.Column Items are laid out from top to
139 bottom.
140 \value FlexboxLayout.ColumnReversed Items are laid out from bottom to
141 top.
142
143 The default value is \c FlexboxLayout.Row.
144*/
145QQuickFlexboxLayout::FlexboxDirection QQuickFlexboxLayout::direction() const
146{
147 Q_D(const QQuickFlexboxLayout);
148 return d->m_direction;
149}
150
151void QQuickFlexboxLayout::setDirection(QQuickFlexboxLayout::FlexboxDirection direction)
152{
153 Q_D(QQuickFlexboxLayout);
154 if (d->m_direction == direction)
155 return;
156 d->m_direction = direction;
157 invalidate();
158 emit directionChanged();
159}
160
161/*!
162 \qmlproperty enumeration FlexboxLayout::wrap
163
164 This property specifies that the items within the flex box layout can wrap
165 or not and it happens when the children overflow the size of the flex box
166 layout. If the items are wrapped, it will be placed in multiple lines
167 depending on overflow condition as stated. Each line takes up the
168 maximum size of the item along the
169 \l {https://www.w3.org/TR/css-flexbox-1/#box-model}{cross-axis}.
170
171 Possible values:
172
173 \value FlexboxLayout.Wrap Items are wrapped into multiple lines
174 within the flex box layout.
175 \value FlexboxLayout.NoWrap (default) Items are not wrapped and
176 laid out in single line within the
177 flex box layout.
178 \value FlexboxLayout.WrapReverse Items are wrapped into multiple lines
179 within the flex box layout in the
180 reverse direction.
181
182 The default value is \c FlexboxLayout.NoWrap.
183*/
184QQuickFlexboxLayout::FlexboxWrap QQuickFlexboxLayout::wrap() const
185{
186 Q_D(const QQuickFlexboxLayout);
187 return d->m_wrap;
188}
189
190void QQuickFlexboxLayout::setWrap(QQuickFlexboxLayout::FlexboxWrap wrapMode)
191{
192 Q_D(QQuickFlexboxLayout);
193 if (d->m_wrap == wrapMode)
194 return;
195 d->m_wrap = wrapMode;
196 invalidate();
197 emit wrapChanged();
198}
199
200/*!
201 \qmlproperty enumeration FlexboxLayout::alignItems
202
203 This property specifies the alignment of the items within the
204 \l {https://www.w3.org/TR/css-flexbox-1/#flex-lines}{flex lines} of the
205 flex box layout and its aligned along the
206 \l {https://www.w3.org/TR/css-flexbox-1/#box-model}{cross-axis}
207 (which is orthogonal to the main-axis, as defined by the property
208 \l {direction}). This property can be overridden by the
209 items within the flex box layout through the attached property
210 \l {FlexboxLayout::alignSelf}{FlexboxLayout.alignSelf}.
211
212 Possible values:
213
214 \value FlexboxLayout.AlignStart (default) Items are aligned to the
215 start of the flex box layout
216 cross-axis.
217 \value FlexboxLayout.AlignCenter Items are aligned along the center
218 of the flex box layout cross-axis.
219 \value FlexboxLayout.AlignEnd Items are aligned to the end of the
220 flex box layout cross-axis.
221
222 \note The alignments mentioned in possible values are only applicable for
223 the \l{alignItems} property
224
225 The default value is \c FlexboxLayout.AlignStart.
226*/
227QQuickFlexboxLayout::FlexboxAlignment QQuickFlexboxLayout::alignItems() const
228{
229 Q_D(const QQuickFlexboxLayout);
230 return d->m_alignItems;
231}
232
233void QQuickFlexboxLayout::setAlignItems(QQuickFlexboxLayout::FlexboxAlignment alignment)
234{
235 Q_D(QQuickFlexboxLayout);
236 if (alignment >= QQuickFlexboxLayout::AlignStretch || alignment <= QQuickFlexboxLayout::AlignAuto) {
237 qWarning(msg: "Not applicable for Flexbox layout container");
238 return;
239 }
240 if (d->m_alignItems == alignment)
241 return;
242 d->m_alignItems = alignment;
243 invalidate();
244 emit alignItemsChanged();
245}
246
247/*!
248 \qmlproperty enumeration FlexboxLayout::alignContent
249
250 This property specifies the distribution of the
251 \l {https://www.w3.org/TR/css-flexbox-1/#flex-lines}{flex lines} along the
252 \l {https://www.w3.org/TR/css-flexbox-1/#box-model}{cross-axis} of the
253 flex box layout.
254
255 Possible values:
256
257 \value FlexboxLayout.AlignStart (default) Flex lines are aligned to
258 the start of the flex box layout.
259 \value FlexboxLayout.AlignCenter Flex lines are aligned along the
260 center of the flex box layout.
261 \value FlexboxLayout.AlignEnd Flex lines are aligned to the end
262 of the flex box layout.
263 \value FlexboxLayout.AlignStretch Flex lines are stretched according
264 to the height of the flex box
265 layout.
266 \value FlexboxLayout.AlignSpaceBetween The spaces are evenly distributed
267 between the lines and no space
268 along the edge of the flex box
269 layout.
270 \value FlexboxLayout.AlignSpaceAround The spaces are evenly distributed
271 between the lines and half-size
272 space on the edges of the flex box
273 layout.
274 \value FlexboxLayout.AlignSpaceEvenly The spaces are evenly distributed
275 between the lines and the edges of
276 the flex box layout. Not supported
277 in Qt 6.10.
278
279 The default value is \c FlexboxLayout.AlignStart.
280*/
281QQuickFlexboxLayout::FlexboxAlignment QQuickFlexboxLayout::alignContent() const
282{
283 Q_D(const QQuickFlexboxLayout);
284 return d->m_alignContent;
285}
286
287void QQuickFlexboxLayout::setAlignContent(QQuickFlexboxLayout::FlexboxAlignment alignment)
288{
289 Q_D(QQuickFlexboxLayout);
290 if (alignment == QQuickFlexboxLayout::AlignSpaceEvenly) {
291 qmlWarning(me: this) << "Currently not supported for Flexbox layout container";
292 return;
293 }
294 if (d->m_alignContent == alignment)
295 return;
296 d->m_alignContent = alignment;
297 invalidate();
298 emit alignContentChanged();
299}
300
301/*!
302 \qmlproperty enumeration FlexboxLayout::justifyContent
303
304 This property specifies the distribution of the items along the
305 \l {https://www.w3.org/TR/css-flexbox-1/#box-model}{main-axis} of the
306 flex box layout.
307
308 Possible values:
309
310 \value FlexboxLayout.JustifyStart (default) Items are aligned to
311 the start of the flex box
312 layout.
313 \value FlexboxLayout.JustifyCenter Items are aligned along the
314 center of the flex box layout.
315 \value FlexboxLayout.JustifyEnd Items are aligned to the end of
316 the flex box layout.
317 \value FlexboxLayout.JustifySpaceBetween The spaces are evenly
318 distributed between the items
319 and no space along the edges
320 of the flex box layout.
321 \value FlexboxLayout.JustifySpaceAround The spaces are evenly
322 distributed between the items
323 and half-size space on the
324 edges of the flex box layout.
325 \value FlexboxLayout.JustiftSpaceEvenly The spaces are evenly
326 distributed between the items
327 and edges of the flex
328 box layout.
329
330 The default value is \c FlexboxLayout.JustifyStart.
331*/
332QQuickFlexboxLayout::FlexboxJustify QQuickFlexboxLayout::justifyContent() const
333{
334 Q_D(const QQuickFlexboxLayout);
335 return d->m_justifyContent;
336}
337
338void QQuickFlexboxLayout::setJustifyContent(QQuickFlexboxLayout::FlexboxJustify justifyContent)
339{
340 Q_D(QQuickFlexboxLayout);
341 if (d->m_justifyContent == justifyContent)
342 return;
343 d->m_justifyContent = justifyContent;
344 invalidate();
345 emit justifyContentChanged();
346}
347
348/*!
349 \qmlproperty real FlexboxLayout::gap
350
351 This property holds the amount of space that need to be applied
352 to the \l {FlexboxLayout} both along the
353 \l {https://www.w3.org/TR/css-align-3/#gaps}{inline axis and block axis}.
354
355 The default value is \c 0.
356*/
357qreal QQuickFlexboxLayout::gap() const
358{
359 Q_D(const QQuickFlexboxLayout);
360 return d->m_gap;
361}
362
363void QQuickFlexboxLayout::setGap(qreal gap)
364{
365 Q_D(QQuickFlexboxLayout);
366 if (d->m_gap == gap)
367 return;
368 d->m_gap = gap;
369 d->m_gapBitSet.set(position: GapAll);
370 invalidate();
371 emit gapChanged();
372 if (!isGapBitSet(gap: GapRow))
373 emit rowGapChanged();
374 if (!isGapBitSet(gap: GapColumn))
375 emit columnGapChanged();
376}
377
378void QQuickFlexboxLayout::resetGap()
379{
380 Q_D(QQuickFlexboxLayout);
381 d->m_gap = 0;
382 d->m_gapBitSet.reset(position: GapAll);
383 emit gapChanged();
384 if (!isGapBitSet(gap: GapRow))
385 emit rowGapChanged();
386 if (!isGapBitSet(gap: GapColumn))
387 emit columnGapChanged();
388}
389
390/*!
391 \qmlproperty real FlexboxLayout::rowGap
392
393 This property holds the amount of space that need to be applied to the
394 \l {FlexboxLayout} along the
395 \l {https://www.w3.org/TR/css-align-3/#gaps}{block axis}. Setting this
396 property overrides the \l{gap} value affecting the
397 \l {https://www.w3.org/TR/css-align-3/#gaps}{block axis}.
398
399 The default value is \c 0.
400*/
401qreal QQuickFlexboxLayout::rowGap() const
402{
403 Q_D(const QQuickFlexboxLayout);
404 if (!isGapBitSet(gap: GapRow))
405 return d->m_gap;
406 return d->m_rowGap;
407}
408
409void QQuickFlexboxLayout::setRowGap(qreal gap)
410{
411 Q_D(QQuickFlexboxLayout);
412 if (d->m_rowGap == gap)
413 return;
414 d->m_rowGap = gap;
415 d->m_gapBitSet.set(position: QQuickFlexboxLayout::GapRow);
416 invalidate();
417 emit rowGapChanged();
418}
419
420void QQuickFlexboxLayout::resetRowGap()
421{
422 Q_D(QQuickFlexboxLayout);
423 d->m_rowGap = 0;
424 d->m_gapBitSet.reset(position: GapRow);
425 emit rowGapChanged();
426}
427
428/*!
429 \qmlproperty real FlexboxLayout::columnGap
430
431 This property holds the amount of space that need to be applied
432 to the \l {FlexboxLayout} along the
433 \l {https://www.w3.org/TR/css-align-3/#gaps}{inline axis}. Setting this
434 property override the \l{gap} value affecting the
435 \l {https://www.w3.org/TR/css-align-3/#gaps}{inline axis}.
436
437 The default value is \c 0.
438*/
439qreal QQuickFlexboxLayout::columnGap() const
440{
441 Q_D(const QQuickFlexboxLayout);
442 if (!isGapBitSet(gap: GapColumn))
443 return d->m_gap;
444 return d->m_columnGap;
445}
446
447void QQuickFlexboxLayout::setColumnGap(qreal gap)
448{
449 Q_D(QQuickFlexboxLayout);
450 if (d->m_columnGap == gap)
451 return;
452 d->m_columnGap = gap;
453 d->m_gapBitSet.set(position: QQuickFlexboxLayout::GapColumn);
454 invalidate();
455 emit columnGapChanged();
456}
457
458void QQuickFlexboxLayout::resetColumnGap()
459{
460 Q_D(QQuickFlexboxLayout);
461 d->m_columnGap = 0;
462 d->m_gapBitSet.reset(position: GapColumn);
463 emit columnGapChanged();
464}
465
466void QQuickFlexboxLayout::updateLayoutItems()
467{
468 Q_D(QQuickFlexboxLayout);
469 // Clean all the items in the layout
470 d->m_flexEngine.clearItems();
471 // Update the parent item properties
472 if (auto *flexParentItem = d->m_flexEngine.getFlexboxParentItem()) {
473 flexParentItem->setFlexDirection(d->m_direction);
474 flexParentItem->setFlexWrap(d->m_wrap);
475 flexParentItem->setFlexAlignItemsProperty(d->m_alignItems);
476 flexParentItem->setFlexAlignContentProperty(d->m_alignContent);
477 flexParentItem->setFlexJustifyContentProperty(d->m_justifyContent);
478 if (isGapBitSet(gap: QQuickFlexboxLayout::GapAll))
479 flexParentItem->setFlexGap(gap: QQuickFlexboxLayout::GapAll, value: d->m_gap);
480 if (isGapBitSet(gap: QQuickFlexboxLayout::GapRow))
481 flexParentItem->setFlexGap(gap: QQuickFlexboxLayout::GapRow, value: d->m_rowGap);
482 if (isGapBitSet(gap: QQuickFlexboxLayout::GapColumn))
483 flexParentItem->setFlexGap(gap: QQuickFlexboxLayout::GapColumn, value: d->m_columnGap);
484 }
485
486 // Insert the items in the layout
487 const QList<QQuickItem *> items = childItems();
488 for (auto *childItem : items) {
489 Q_ASSERT(childItem);
490 checkAnchors(item: childItem);
491 if (shouldIgnoreItem(child: childItem))
492 continue;
493 // Create and set the attached properties of the flex item and add it as child
494 auto *flexLayoutItem = new QQuickFlexboxLayoutItem(childItem);
495 if (auto *flexItemAttachedProperties = attachedFlexboxLayoutObject(item: childItem))
496 flexLayoutItem->setFlexAlignSelfProperty(flexItemAttachedProperties->alignSelf());
497 d->m_flexEngine.insertItem(item: flexLayoutItem);
498 }
499}
500
501void QQuickFlexboxLayout::checkAnchors(QQuickItem *item) const
502{
503 QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors;
504 if (anchors && anchors->activeDirections())
505 qmlWarning(me: item) << "Detected anchors on an item that is managed by a layout. This is undefined behavior; use FlexboxLayout alignment properties instead.";
506}
507
508void QQuickFlexboxLayout::componentComplete()
509{
510 QQuickLayout::componentComplete();
511 ensureLayoutItemsUpdated(options: ApplySizeHints);
512 if (qobject_cast<QQuickLayout*>(object: parentItem()))
513 return;
514 rearrange(QSizeF(width(), height()));
515}
516
517void QQuickFlexboxLayout::itemVisibilityChanged(QQuickItem *item)
518{
519 if (!isReady())
520 return;
521 invalidate(childItem: item);
522}
523
524QSizeF QQuickFlexboxLayout::sizeHint(Qt::SizeHint whichSizeHint) const
525{
526 Q_D(const QQuickFlexboxLayout);
527 QSizeF sizeHint = d->m_flexEngine.sizeHint(whichSizeHint);
528 d->m_dirty = false;
529 return sizeHint;
530}
531
532QQuickFlexboxLayoutAttached *QQuickFlexboxLayout::qmlAttachedProperties(QObject *object)
533{
534 return new QQuickFlexboxLayoutAttached(object);
535}
536
537bool QQuickFlexboxLayout::isGapBitSet(QQuickFlexboxLayout::FlexboxGap gap) const
538{
539 Q_D(const QQuickFlexboxLayout);
540 if (gap < QQuickFlexboxLayout::GapRow || gap > QQuickFlexboxLayout::GapAll)
541 return false;
542 return d->m_gapBitSet[gap];
543}
544
545QQuickItem *QQuickFlexboxLayout::itemAt(int index) const
546{
547 const auto items = childItems();
548 for (QQuickItem *item : items) {
549 if (shouldIgnoreItem(child: item))
550 continue;
551 if (index == 0)
552 return item;
553 --index;
554 }
555 return nullptr;
556}
557
558int QQuickFlexboxLayout::itemCount() const
559{
560 int count = 0;
561 const auto items = childItems();
562 for (QQuickItem *item : items) {
563 if (shouldIgnoreItem(child: item))
564 continue;
565 ++count;
566 }
567 return count;
568}
569
570void QQuickFlexboxLayout::invalidate(QQuickItem *childItem)
571{
572 Q_D(QQuickFlexboxLayout);
573 d->m_flexEngine.invalidateItemSizeHint(item: childItem);
574 QQuickLayout::invalidate(childItem: this);
575 if (QQuickLayout *parentLayout = qobject_cast<QQuickLayout *>(object: parentItem()))
576 parentLayout->invalidate(childItem: this);
577}
578
579void QQuickFlexboxLayout::childItemsChanged()
580{
581 const int count = itemCount();
582 for (int i = 0; i < count; ++i) {
583 QQuickItem *child = itemAt(index: i);
584 checkAnchors(item: child);
585 }
586}
587
588void QQuickFlexboxLayout::rearrange(const QSizeF &newSize)
589{
590 Q_D(QQuickFlexboxLayout);
591 if (newSize.isNull() || !newSize.isValid())
592 return;
593 d->m_flexEngine.setGeometries(newSize);
594 QQuickLayout::rearrange(newSize);
595}
596
597void QQuickFlexboxLayout::itemSiblingOrderChanged(QQuickItem *)
598{
599 if (!isReady())
600 return;
601 invalidate();
602}
603
604QQuickFlexboxLayoutAttached::QQuickFlexboxLayoutAttached(QObject *object)
605{
606 auto item = qobject_cast<QQuickItem*>(o: object);
607 if (!item) {
608 qmlWarning(me: object) << "FlexboxLayout attached property must be attached to an object deriving from Item";
609 return;
610 }
611 setParent(object);
612 if (auto flexboxLayout = qobject_cast<QQuickFlexboxLayout*>(object: item->parentItem())) {
613 if (!flexboxLayout->isComponentComplete()) {
614 // Don't try to get the index if the FlexboxLayout itself hasn't
615 // loaded yet.
616 return;
617 }
618 // In case of lazy loading in loader, attachedProperties are created
619 // and updated for the object after adding the child object to the
620 // stack layout, which leads to entries with same index. Triggering
621 // childItemsChanged() resets to right index in the stack layout.
622 flexboxLayout->childItemsChanged();
623 }
624}
625
626/*!
627 \qmlattachedproperty enumeration FlexboxLayout::alignSelf
628
629 This attached property allows to align this item in the flex box layout
630 along the \l {https://www.w3.org/TR/css-flexbox-1/#box-model}{cross-axis}
631 and it overrides the parent flex box layout property
632 \l{alignItems}.
633
634 By default, the child item inherit the alignment from the parent and it can
635 override the parent flex box layout
636 \l{alignItems} property with the values
637 \c {FlexboxLayout.AlignStart}, \c {FlexboxLayout.AlignCenter}
638 and \c {FlexboxLayout.AlignEnd}.
639
640 The default value is \c {FlexboxLayout.AlignAuto}.
641*/
642QQuickFlexboxLayout::FlexboxAlignment QQuickFlexboxLayoutAttached::alignSelf() const
643{
644 return m_alignSelf;
645}
646
647void QQuickFlexboxLayoutAttached::setAlignSelf(QQuickFlexboxLayout::FlexboxAlignment alignment)
648{
649 if (m_alignSelf == alignment)
650 return;
651
652 m_alignSelf = alignment;
653 const auto *item = qobject_cast<QQuickItem*>(o: parent());
654 if (auto *flexLayout = qobject_cast<QQuickFlexboxLayout *>(object: item->parent())) {
655 auto *priv = dynamic_cast<QQuickFlexboxLayoutPrivate *>(QQuickLayoutPrivate::get(item: flexLayout));
656 auto &flexEngine = priv->getFlexEngine();
657 auto *item = qobject_cast<QQuickItem *>(o: parent());
658 if (auto *flexLayoutItem = flexEngine.findFlexboxLayoutItem(item)) {
659 flexLayoutItem->setFlexAlignSelfProperty(alignment);
660 flexLayout->invalidate();
661 }
662 }
663 emit alignSelfChanged();
664}
665
666QT_END_NAMESPACE
667
668#include "moc_qquickflexboxlayout_p.cpp"
669

source code of qtdeclarative/src/quicklayouts/qquickflexboxlayout.cpp