8static qreal width(QQStyleKitLayoutItem *li, qreal availableWidth = .0)
12 QQuickItem *item = li->item();
13 qreal w = item->implicitWidth();
15 w = qMax(.0, availableWidth - li->margins().left() - li->margins().right());
19static qreal height(QQStyleKitLayoutItem *li, qreal availableHeight = .0)
23 QQuickItem *item = li->item();
24 qreal h = item->implicitHeight();
26 h = qMax(.0, availableHeight - li->margins().top() - li->margins().bottom());
33 for (QQStyleKitLayoutItem *li : items) {
34 if (li->item() && li->item()->isVisible())
35 total += width(li) + li->margins().left() + li->margins().right() + spacing;
43 for (QQStyleKitLayoutItem *li : items) {
44 if (li->item() && li->item()->isVisible()) {
45 const qreal h = height(li) + li->margins().top() + li->margins().bottom();
53static qreal vAlignY(QQStyleKitLayoutItem *li, qreal containerY, qreal containerHeight)
58 const auto itemHeight = height(li, containerHeight);
59 const auto vAlign = li->alignment() & Qt::AlignVertical_Mask;
60 const auto margins = li->margins();
61 if (vAlign & Qt::AlignTop)
62 return containerY + margins.top();
63 if (vAlign & Qt::AlignBottom)
64 return containerY + containerHeight - itemHeight - margins.bottom();
65 return containerY + margins.top()
66 + (containerHeight - margins.top() - margins.bottom() - itemHeight) / 2.0;
69QQStyleKitLayoutItem::QQStyleKitLayoutItem(QObject *parent)
74QQuickItem *QQStyleKitLayoutItem::item()
const
79void QQStyleKitLayoutItem::setItem(QQuickItem *item)
85 disconnect(m_item,
nullptr,
this,
nullptr);
89 connect(m_item, &QQuickItem::implicitWidthChanged,
this, [
this]() { emit itemChanged(); });
90 connect(m_item, &QQuickItem::implicitHeightChanged,
this, [
this]() { emit itemChanged(); });
91 connect(m_item, &QQuickItem::visibleChanged,
this, [
this]() { emit itemChanged(); });
97qreal QQStyleKitLayoutItem::x()
const
102void QQStyleKitLayoutItem::setX(qreal x)
104 if (qFuzzyCompare(m_x, x))
111qreal QQStyleKitLayoutItem::y()
const
116void QQStyleKitLayoutItem::setY(qreal y)
118 if (qFuzzyCompare(m_y, y))
125qreal QQStyleKitLayoutItem::width()
const
130void QQStyleKitLayoutItem::setWidth(qreal width)
132 if (qFuzzyCompare(m_width, width))
139qreal QQStyleKitLayoutItem::height()
const
144void QQStyleKitLayoutItem::setHeight(qreal height)
146 if (qFuzzyCompare(m_height, height))
150 emit heightChanged();
153Qt::Alignment QQStyleKitLayoutItem::alignment()
const
158void QQStyleKitLayoutItem::setAlignment(Qt::Alignment alignment)
160 if (m_alignment == alignment)
163 m_alignment = alignment;
164 emit alignmentChanged();
167QMarginsF QQStyleKitLayoutItem::margins()
const
172void QQStyleKitLayoutItem::setMargins(
const QMarginsF &margins)
174 if (m_margins == margins)
178 emit marginsChanged();
181bool QQStyleKitLayoutItem::fillWidth()
const
186void QQStyleKitLayoutItem::setFillWidth(
bool fill)
188 if (m_fillWidth == fill)
192 emit fillWidthChanged();
195bool QQStyleKitLayoutItem::fillHeight()
const
200void QQStyleKitLayoutItem::setFillHeight(
bool fill)
202 if (m_fillHeight == fill)
206 emit fillHeightChanged();
213 , m_updatingLayout(
false)
215 m_updateTimer.setSingleShot(
true);
216 connect(&m_updateTimer, &QTimer::timeout,
this, &
QQStyleKitLayout::updateLayout);
226 if (m_container == container)
229 m_container = container;
230 emit containerChanged();
231 connect(m_container, &QQuickItem::widthChanged,
this, &
QQStyleKitLayout::scheduleUpdate);
232 connect(m_container, &QQuickItem::heightChanged,
this, &
QQStyleKitLayout::scheduleUpdate);
239 return QQmlListProperty<QQStyleKitLayoutItem>(
const_cast<
QQStyleKitLayout *>(
this),
241 &QQStyleKitLayout::layoutItem_append,
242 &QQStyleKitLayout::layoutItem_count,
243 &QQStyleKitLayout::layoutItem_at,
244 &QQStyleKitLayout::layoutItem_clear);
247void QQStyleKitLayout::layoutItem_append(QQmlListProperty<QQStyleKitLayoutItem> *list, QQStyleKitLayoutItem *item)
250 if (layout && item) {
251 layout->m_layoutItems.append(item);
252 connect(item, &QQStyleKitLayoutItem::itemChanged, layout, &
QQStyleKitLayout::scheduleUpdate);
253 connect(item, &QQStyleKitLayoutItem::alignmentChanged, layout, &
QQStyleKitLayout::scheduleUpdate);
254 connect(item, &QQStyleKitLayoutItem::marginsChanged, layout, &
QQStyleKitLayout::scheduleUpdate);
255 connect(item, &QQStyleKitLayoutItem::fillWidthChanged, layout, &
QQStyleKitLayout::scheduleUpdate);
256 connect(item, &QQStyleKitLayoutItem::fillHeightChanged, layout, &
QQStyleKitLayout::scheduleUpdate);
257 emit layout->layoutItemsChanged();
258 layout->scheduleUpdate();
262qsizetype
QQStyleKitLayout::layoutItem_count(QQmlListProperty<QQStyleKitLayoutItem> *list)
266 return layout->m_layoutItems.size();
270QQStyleKitLayoutItem *
QQStyleKitLayout::layoutItem_at(QQmlListProperty<QQStyleKitLayoutItem> *list, qsizetype index)
274 return layout->m_layoutItems.value(index);
278void QQStyleKitLayout::layoutItem_clear(QQmlListProperty<QQStyleKitLayoutItem> *list)
282 layout->m_layoutItems.clear();
283 emit layout->layoutItemsChanged();
284 layout->scheduleUpdate();
295 return m_contentMargins;
300 if (m_contentMargins == margins)
303 m_contentMargins = margins;
304 emit contentMarginsChanged();
315 if (qFuzzyCompare(m_spacing, spacing))
319 emit spacingChanged();
330 if (m_mirrored == mirrored)
333 m_mirrored = mirrored;
334 emit mirroredChanged();
340 return m_implicitWidth;
345 return m_implicitHeight;
350 if (qFuzzyCompare(m_implicitWidth, width))
353 m_implicitWidth = width;
354 emit implicitWidthChanged();
360 if (qFuzzyCompare(m_implicitHeight, height))
363 m_implicitHeight = height;
364 emit implicitHeightChanged();
375 if (m_enabled == enabled)
379 emit enabledChanged();
390 if (!m_container || m_container->width() <= 0 || m_container->height() <= 0)
393 if (m_updatingLayout)
395 m_updatingLayout =
true;
397 QList<QQStyleKitLayoutItem *> left;
398 QList<QQStyleKitLayoutItem *> right;
399 QList<QQStyleKitLayoutItem *> center;
401 for (QQStyleKitLayoutItem *li : m_layoutItems) {
402 if (!li->item() || !li->item()->isVisible())
404 const auto hAlign = li->alignment() & Qt::AlignHorizontal_Mask;
405 const bool isMirrored = m_mirrored && !(hAlign & Qt::AlignAbsolute);
425 const qreal containerWidth = m_container->width() ? m_container->width() : m_container->implicitWidth();
426 const qreal containerHeight = m_container->height() ? m_container->height() : m_container->implicitHeight();
427 const qreal paddedX = m_contentMargins.left();
428 const qreal paddedY = m_contentMargins.top();
429 const qreal paddedWidth = qMax(containerWidth - m_contentMargins.left() - m_contentMargins.right(), .0);
430 const qreal paddedHeight = qMax(containerHeight - m_contentMargins.top() - m_contentMargins.bottom(), .0);
432 qreal maxTopMargin = .0;
433 qreal maxBottomMargin = .0;
438 for (QQStyleKitLayoutItem *li : left) {
439 QQuickItem *item = li->item();
440 if (!item || !item->isVisible())
443 const QMarginsF margins = li->margins();
444 const qreal itemWidth = width(li, paddedWidth);
445 const qreal itemHeight = height(li, paddedHeight);
446 auto y = vAlignY(li, paddedY, paddedHeight);
447 li->setX(x + margins.left());
449 li->setWidth(itemWidth);
450 li->setHeight(itemHeight);
451 x += itemWidth + margins.left() + margins.right() + m_spacing;
452 maxTopMargin = qMax(maxTopMargin, margins.top());
453 maxBottomMargin = qMax(maxBottomMargin, margins.bottom());
459 qreal x = paddedX + paddedWidth;
460 for (QQStyleKitLayoutItem *li : right) {
461 QQuickItem *item = li->item();
462 if (!item || !item->isVisible())
465 const QMarginsF margins = li->margins();
466 const qreal itemWidth = width(li, paddedWidth);
467 const qreal itemHeight = height(li, paddedHeight);
468 x -= itemWidth + margins.right() + margins.left();
469 auto y = vAlignY(li, paddedY, paddedHeight);
470 li->setX(x + margins.left());
472 li->setWidth(itemWidth);
473 li->setHeight(itemHeight);
475 maxTopMargin = qMax(maxTopMargin, margins.top());
476 maxBottomMargin = qMax(maxBottomMargin, margins.bottom());
482 qreal x = paddedX + (paddedWidth - totalWidth(center, m_spacing)) / 2;
483 for (QQStyleKitLayoutItem *li : center) {
484 QQuickItem *item = li->item();
485 if (!item || !item->isVisible())
488 const QMarginsF margins = li->margins();
489 const qreal itemWidth = width(li, paddedWidth);
490 const qreal itemHeight = height(li, paddedHeight);
491 auto y = vAlignY(li, paddedY, paddedHeight);
492 li->setX(x + margins.left());
494 li->setWidth(itemWidth);
495 li->setHeight(itemHeight);
496 x += itemWidth + margins.left() + margins.right() + m_spacing;
497 maxTopMargin = qMax(maxTopMargin, margins.top());
498 maxBottomMargin = qMax(maxBottomMargin, margins.bottom());
502 const auto leftWidth = totalWidth(left, m_spacing);
503 const auto leftHeight = totalHeight(left);
504 const auto rightWidth = totalWidth(right, m_spacing);
505 const auto rightHeight = totalHeight(right);
506 const auto centerWidth = totalWidth(center, m_spacing);
507 const auto centerHeight = totalHeight(center);
509 const auto implicitWidth = leftWidth + rightWidth + centerWidth
510 - m_spacing * (left.isEmpty() ? 0 : 1)
511 - m_spacing * (right.isEmpty() ? 0 : 1)
512 - m_spacing * (center.isEmpty() ? 0 : 1)
513 + m_contentMargins.left() + m_contentMargins.right();
514 setImplicitWidth(implicitWidth);
515 const auto implicitHeight = qMax(qMax(leftHeight, rightHeight), centerHeight)
516 + m_contentMargins.top() + m_contentMargins.bottom();
517 setImplicitHeight(implicitHeight);
522 auto leftPadding = m_contentMargins.left() + leftWidth;
523 auto topPadding = m_contentMargins.top() + maxTopMargin;
524 auto rightPadding = m_contentMargins.right() + rightWidth;
525 auto bottomPadding = m_contentMargins.bottom() + maxBottomMargin;
527 std::swap(leftPadding, rightPadding);
528 QMarginsF newPadding = QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding);
529 if (m_padding != newPadding) {
530 m_padding = newPadding;
531 emit paddingChanged();
533 m_updatingLayout =
false;
538 if (!m_updateTimer.isActive())
539 m_updateTimer.start(0);
544#include "moc_qqstylekitlayout_p.cpp"
void setImplicitHeight(qreal height)
QMarginsF padding() const
void setSpacing(qreal spacing)
qreal implicitHeight() const
qreal implicitWidth() const
QMarginsF contentMargins() const
void setContentMargins(const QMarginsF &margins)
void setEnabled(bool enabled)
void setImplicitWidth(qreal width)
void setContainer(QQuickItem *item)
QQuickItem * container() const
QQmlListProperty< QQStyleKitLayoutItem > layoutItems()
void setMirrored(bool mirrored)
Combined button and popup list for selecting options.
static qreal height(QQStyleKitLayoutItem *li, qreal availableHeight=.0)
static qreal vAlignY(QQStyleKitLayoutItem *li, qreal containerY, qreal containerHeight)
static qreal totalWidth(const QList< QQStyleKitLayoutItem * > &items, qreal spacing)
static QT_BEGIN_NAMESPACE qreal width(QQStyleKitLayoutItem *li, qreal availableWidth=.0)
static qreal totalHeight(const QList< QQStyleKitLayoutItem * > &items)