File indexing completed on 2024-05-12 05:38:56

0001 /* SPDX-FileCopyrightText: 2017 The Qt Company Ltd.
0002  * SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
0003  * SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-or-later
0004  */
0005 
0006 #include "iconlabellayout.h"
0007 #include "iconlabellayout_p.h"
0008 
0009 #include <QGuiApplication>
0010 
0011 #include <cmath>
0012 #include <unordered_map>
0013 
0014 bool IconLabelLayoutPrivate::createIconItem()
0015 {
0016     Q_Q(IconLabelLayout);
0017     if (iconItem)
0018         return false;
0019 
0020     iconItem = qobject_cast<QQuickItem *>(iconComponent->create());
0021     iconItem->setParentItem(q);
0022     iconItem->setObjectName(QStringLiteral("iconItem"));
0023     iconItem->setProperty("source", icon.nameOrSource());
0024     iconItem->setProperty("implicitWidth", icon.width());
0025     iconItem->setProperty("implicitHeight", icon.height());
0026     iconItem->setProperty("color", icon.color());
0027     iconItem->setProperty("cache", icon.cache());
0028     return true;
0029 }
0030 
0031 bool IconLabelLayoutPrivate::destroyIconItem()
0032 {
0033     if (!iconItem)
0034         return false;
0035 
0036     iconItem->deleteLater();
0037     iconItem = nullptr;
0038     return true;
0039 }
0040 
0041 bool IconLabelLayoutPrivate::updateIconItem()
0042 {
0043     Q_Q(IconLabelLayout);
0044     if (!q->hasIcon())
0045         return destroyIconItem();
0046     return createIconItem();
0047 }
0048 
0049 void IconLabelLayoutPrivate::syncIconItem()
0050 {
0051     if (!iconItem || icon.isEmpty())
0052         return;
0053 
0054     iconItem->setProperty("source", icon.nameOrSource());
0055     iconItem->setProperty("implicitWidth", icon.width());
0056     iconItem->setProperty("implicitHeight", icon.height());
0057     iconItem->setProperty("color", icon.color());
0058     iconItem->setProperty("cache", icon.cache());
0059 }
0060 
0061 void IconLabelLayoutPrivate::updateOrSyncIconItem()
0062 {
0063     Q_Q(IconLabelLayout);
0064     if (!updateIconItem()) {
0065         syncIconItem();
0066     }
0067     q->relayout();
0068 }
0069 
0070 bool IconLabelLayoutPrivate::createLabelItem()
0071 {
0072     Q_Q(IconLabelLayout);
0073     if (labelItem)
0074         return false;
0075 
0076     labelItem = qobject_cast<QQuickItem *>(labelComponent->create());
0077     labelItem->setParentItem(q);
0078     labelItem->setObjectName(QStringLiteral("labelItem"));
0079     labelItem->setProperty("text", text);
0080     labelItem->setProperty("font", font);
0081     labelItem->setProperty("color", color);
0082     const int halign = alignment & Qt::AlignHorizontal_Mask;
0083     labelItem->setProperty("horizontalAlignment", halign);
0084     const int valign = alignment & Qt::AlignVertical_Mask;
0085     labelItem->setProperty("verticalAlignment", valign);
0086     return true;
0087 }
0088 
0089 bool IconLabelLayoutPrivate::destroyLabelItem()
0090 {
0091     if (!labelItem)
0092         return false;
0093 
0094     labelItem->deleteLater();
0095     labelItem = nullptr;
0096     return true;
0097 }
0098 
0099 bool IconLabelLayoutPrivate::updateLabelItem()
0100 {
0101     Q_Q(IconLabelLayout);
0102     if (!q->hasLabel())
0103         return destroyLabelItem();
0104     return createLabelItem();
0105 }
0106 
0107 void IconLabelLayoutPrivate::syncLabelItem()
0108 {
0109     if (!labelItem)
0110         return;
0111 
0112     labelItem->setProperty("text", text);
0113 }
0114 
0115 void IconLabelLayoutPrivate::updateOrSyncLabelItem()
0116 {
0117     Q_Q(IconLabelLayout);
0118     if (!updateLabelItem()) {
0119         syncLabelItem();
0120     }
0121     q->relayout();
0122 }
0123 
0124 void IconLabelLayoutPrivate::updateImplicitSize()
0125 {
0126     Q_Q(IconLabelLayout);
0127     bool showIcon = iconItem && q->hasIcon();
0128     bool showLabel = labelItem && q->hasLabel();
0129 
0130     const qreal iconImplicitWidth = showIcon ? iconItem->implicitWidth() : 0;
0131     const qreal iconImplicitHeight = showIcon ? iconItem->implicitHeight() : 0;
0132     // Always ceil text size to prevent pixel misalignment. If you use round or floor, you may cause text elision.
0133     const qreal labelImplicitWidth = showLabel ? std::ceil(labelItem->implicitWidth()) : 0;
0134     const qreal labelImplicitHeight = showLabel ? std::ceil(labelItem->implicitHeight()) : 0;
0135     const qreal effectiveSpacing = showLabel && showIcon && iconItem->implicitWidth() > 0 ? spacing : 0;
0136     contentWidth = (display == IconLabelLayout::TextBesideIcon //
0137                         ? iconImplicitWidth + labelImplicitWidth + effectiveSpacing
0138                         : qMax(iconImplicitWidth, labelImplicitWidth));
0139     contentHeight = (display == IconLabelLayout::TextUnderIcon //
0140                          ? iconImplicitHeight + labelImplicitHeight + effectiveSpacing
0141                          : qMax(iconImplicitHeight, labelImplicitHeight));
0142     q->setImplicitSize(contentWidth + leftPadding + rightPadding, contentHeight + topPadding + bottomPadding);
0143     q->setAvailableWidth();
0144     q->setAvailableHeight();
0145 }
0146 
0147 static QRectF alignedRect(bool mirrored, Qt::Alignment alignment, const QSizeF &size, const QRectF &rectangle)
0148 {
0149     Qt::Alignment halign = alignment & Qt::AlignHorizontal_Mask;
0150     if (mirrored && (halign & Qt::AlignRight) == Qt::AlignRight) {
0151         halign = Qt::AlignLeft;
0152     } else if (mirrored && (halign & Qt::AlignLeft) == Qt::AlignLeft) {
0153         halign = Qt::AlignRight;
0154     }
0155     qreal x = rectangle.x();
0156     qreal y = rectangle.y();
0157     const qreal w = size.width();
0158     const qreal h = size.height();
0159     if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
0160         y += rectangle.height() / 2 - h / 2;
0161     else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
0162         y += rectangle.height() - h;
0163     if ((halign & Qt::AlignRight) == Qt::AlignRight)
0164         x += rectangle.width() - w;
0165     else if ((halign & Qt::AlignHCenter) == Qt::AlignHCenter)
0166         x += rectangle.width() / 2 - w / 2;
0167     return QRectF(x, y, w, h);
0168 }
0169 
0170 void IconLabelLayoutPrivate::layout()
0171 {
0172     Q_Q(IconLabelLayout);
0173     if (!q->isComponentComplete())
0174         return;
0175 
0176     switch (display) {
0177     case IconLabelLayout::IconOnly:
0178         if (iconItem) {
0179             // Icons should always be pixel aligned, so convert to QRect
0180             QSizeF size(qMin(iconItem->implicitWidth(), q->availableWidth()), qMin(iconItem->implicitHeight(), q->availableHeight()));
0181             QRectF rect(mirrored ? rightPadding : leftPadding, topPadding, q->availableWidth(), q->availableHeight());
0182             q->setIconRect(alignedRect(mirrored, alignment, size, rect));
0183             iconItem->setSize(iconRect.size());
0184             iconItem->setPosition(iconRect.topLeft()); // Not animating icon positions because it tends to look wrong
0185         }
0186         break;
0187     case IconLabelLayout::TextOnly:
0188         if (labelItem) {
0189             QSizeF size(qMin(labelItem->implicitWidth(), q->availableWidth()), qMin(labelItem->implicitHeight(), q->availableHeight()));
0190             QRectF rect(mirrored ? rightPadding : leftPadding, topPadding, q->availableWidth(), q->availableHeight());
0191             q->setLabelRect(alignedRect(mirrored, alignment, size, rect));
0192             labelItem->setSize(labelRect.size());
0193             labelItem->setPosition(labelRect.topLeft()); // Not animating when text only because the text tends to clip outside
0194         }
0195         break;
0196 
0197     case IconLabelLayout::TextUnderIcon: {
0198         // Work out the sizes first, as the positions depend on them.
0199         QSizeF iconSize;
0200         QSizeF textSize;
0201         if (iconItem) {
0202             iconSize.setWidth(qMin(iconItem->implicitWidth(), q->availableWidth()));
0203             iconSize.setHeight(qMin(iconItem->implicitHeight(), q->availableHeight()));
0204         }
0205         qreal effectiveSpacing = 0;
0206         if (labelItem) {
0207             if (!iconSize.isEmpty())
0208                 effectiveSpacing = spacing;
0209             textSize.setWidth(qMin(labelItem->implicitWidth(), q->availableWidth()));
0210             textSize.setHeight(qMin(labelItem->implicitHeight(), q->availableHeight() - iconSize.height() - effectiveSpacing));
0211         }
0212 
0213         QSizeF size(qMax(iconSize.width(), textSize.width()), iconSize.height() + effectiveSpacing + textSize.height());
0214         QRectF rect(mirrored ? rightPadding : leftPadding, topPadding, q->availableWidth(), q->availableHeight());
0215         QRectF combinedRect = alignedRect(mirrored, alignment, size, rect);
0216         q->setIconRect(alignedRect(mirrored, Qt::AlignHCenter | Qt::AlignTop, iconSize, combinedRect));
0217         q->setLabelRect(alignedRect(mirrored, Qt::AlignHCenter | Qt::AlignBottom, textSize, combinedRect));
0218         if (iconItem) {
0219             iconItem->setSize(iconRect.size());
0220             iconItem->setPosition(iconRect.topLeft());
0221         }
0222         if (labelItem) {
0223             labelItem->setSize(labelRect.size());
0224             labelItem->setPosition(labelRect.topLeft());
0225             // NOTE: experimental animations when changing display types
0226             // labelItem->setOpacity(0); // Reset opacity before OpacityAnimator is activated
0227             // labelItem->setY(iconRect.y() + iconRect.height());
0228             // labelItem->setProperty("opacity", 1); // Activate OpacityAnimator
0229             // labelItem->setX(labelRect.x()); // Not animating X so that the text will only slide vertically
0230             // labelItem->setProperty("y", labelRect.y());
0231         }
0232         break;
0233     }
0234 
0235     case IconLabelLayout::TextBesideIcon:
0236     default:
0237         // Work out the sizes first, as the positions depend on them.
0238         QSizeF iconSize(0, 0);
0239         QSizeF textSize(0, 0);
0240         if (iconItem) {
0241             iconSize.setWidth(qMin(iconItem->implicitWidth(), q->availableWidth()));
0242             iconSize.setHeight(qMin(iconItem->implicitHeight(), q->availableHeight()));
0243         }
0244         qreal effectiveSpacing = 0;
0245         if (labelItem) {
0246             if (!iconSize.isEmpty())
0247                 effectiveSpacing = spacing;
0248             textSize.setWidth(qMin(labelItem->implicitWidth(), q->availableWidth() - iconSize.width() - effectiveSpacing));
0249             textSize.setHeight(qMin(labelItem->implicitHeight(), q->availableHeight()));
0250         }
0251 
0252         QSizeF size(iconSize.width() + effectiveSpacing + textSize.width(), qMax(iconSize.height(), textSize.height()));
0253         QRectF rect(mirrored ? rightPadding : leftPadding, topPadding, q->availableWidth(), q->availableHeight());
0254         const QRectF combinedRect = alignedRect(mirrored, alignment, size, rect);
0255         q->setIconRect(alignedRect(mirrored, Qt::AlignLeft | Qt::AlignVCenter, iconSize, combinedRect));
0256         q->setLabelRect(alignedRect(mirrored, Qt::AlignRight | Qt::AlignVCenter, textSize, combinedRect));
0257         if (iconItem) {
0258             iconItem->setSize(iconRect.size());
0259             iconItem->setPosition(iconRect.topLeft());
0260         }
0261         if (labelItem) {
0262             labelItem->setSize(labelRect.size());
0263             labelItem->setPosition(labelRect.topLeft());
0264             // NOTE: experimental animations when changing display types
0265             // labelItem->setOpacity(0); // Reset opacity before OpacityAnimator is activated
0266             // labelItem->setX(iconRect.x() + (mirrored ? -labelRect.width() : iconRect.width()));
0267             // labelItem->setProperty("opacity", 1); // Activate OpacityAnimator
0268             // labelItem->setProperty("x", labelRect.x());
0269             // labelItem->setY(labelRect.y()); // Not animating Y so that the text will only slide horizontally
0270         }
0271         break;
0272     }
0273 
0274     q->setBaselineOffset(labelItem ? labelItem->y() + labelItem->baselineOffset() : 0);
0275     if (!firstLayoutCompleted) {
0276         firstLayoutCompleted = true;
0277         if (iconItem) {
0278             iconItem->setProperty("firstLayoutCompleted", true);
0279         }
0280         if (labelItem) {
0281             labelItem->setProperty("firstLayoutCompleted", true);
0282         }
0283     }
0284     // qDebug() << q << "d->layout()" << layoutCount;
0285     // layoutCount += 1;
0286 }
0287 
0288 IconLabelLayout::IconLabelLayout(QQuickItem *parent)
0289     : QQuickItem(parent)
0290     , d_ptr(new IconLabelLayoutPrivate(this))
0291 {
0292 }
0293 
0294 IconLabelLayout::~IconLabelLayout()
0295 {
0296 }
0297 
0298 QQmlComponent *IconLabelLayout::iconComponent() const
0299 {
0300     Q_D(const IconLabelLayout);
0301     return d->iconComponent;
0302 }
0303 
0304 void IconLabelLayout::setIconComponent(QQmlComponent *iconComponent)
0305 {
0306     Q_D(IconLabelLayout);
0307     if (iconComponent == d->iconComponent) {
0308         return;
0309     }
0310 
0311     d->iconComponent = iconComponent;
0312     d->updateOrSyncIconItem();
0313     Q_EMIT iconComponentChanged();
0314 }
0315 
0316 QQmlComponent *IconLabelLayout::labelComponent() const
0317 {
0318     Q_D(const IconLabelLayout);
0319     return d->labelComponent;
0320 }
0321 
0322 void IconLabelLayout::setLabelComponent(QQmlComponent *labelComponent)
0323 {
0324     Q_D(IconLabelLayout);
0325     if (labelComponent == d->labelComponent) {
0326         return;
0327     }
0328 
0329     d->labelComponent = labelComponent;
0330     d->updateOrSyncLabelItem();
0331     Q_EMIT labelComponentChanged();
0332 }
0333 
0334 bool IconLabelLayout::hasIcon() const
0335 {
0336     Q_D(const IconLabelLayout);
0337     return d->hasIcon;
0338 }
0339 
0340 void IconLabelLayout::setHasIcon()
0341 {
0342     Q_D(IconLabelLayout);
0343     if (d->hasIcon == !textOnly() && !d->icon.isEmpty()) {
0344         return;
0345     }
0346 
0347     d->hasIcon = !textOnly() && !d->icon.isEmpty();
0348     Q_EMIT hasIconChanged();
0349 }
0350 
0351 bool IconLabelLayout::hasLabel() const
0352 {
0353     Q_D(const IconLabelLayout);
0354     return d->hasLabel;
0355 }
0356 
0357 void IconLabelLayout::setHasLabel()
0358 {
0359     Q_D(IconLabelLayout);
0360     if (d->hasLabel == !iconOnly() && !d->text.isEmpty()) {
0361         return;
0362     }
0363 
0364     d->hasLabel = !iconOnly() && !d->text.isEmpty();
0365     Q_EMIT hasLabelChanged();
0366 }
0367 
0368 Breeze::QQuickIcon IconLabelLayout::icon() const
0369 {
0370     Q_D(const IconLabelLayout);
0371     return d->icon;
0372 }
0373 
0374 void IconLabelLayout::setIcon(const Breeze::QQuickIcon &icon)
0375 {
0376     Q_D(IconLabelLayout);
0377     if (icon == d->icon) {
0378         return;
0379     }
0380 
0381     d->icon = icon;
0382     setHasIcon();
0383     d->updateOrSyncIconItem();
0384 
0385     Q_EMIT iconChanged();
0386 }
0387 
0388 QString IconLabelLayout::text() const
0389 {
0390     Q_D(const IconLabelLayout);
0391     return d->text;
0392 }
0393 
0394 void IconLabelLayout::setText(const QString &text)
0395 {
0396     Q_D(IconLabelLayout);
0397     if (text == d->text) {
0398         return;
0399     }
0400 
0401     d->text = text;
0402     setHasLabel();
0403     d->updateOrSyncLabelItem();
0404     Q_EMIT textChanged(text);
0405 }
0406 
0407 QFont IconLabelLayout::font() const
0408 {
0409     Q_D(const IconLabelLayout);
0410     return d->font;
0411 }
0412 
0413 void IconLabelLayout::setFont(const QFont &font)
0414 {
0415     Q_D(IconLabelLayout);
0416     if (font == d->font) {
0417         return;
0418     }
0419 
0420     d->font = font;
0421     if (d->labelItem) {
0422         d->labelItem->setProperty("font", font);
0423     }
0424     d->updateOrSyncLabelItem();
0425     Q_EMIT fontChanged(font);
0426 }
0427 
0428 QColor IconLabelLayout::color() const
0429 {
0430     Q_D(const IconLabelLayout);
0431     return d->color;
0432 }
0433 
0434 void IconLabelLayout::setColor(const QColor &color)
0435 {
0436     Q_D(IconLabelLayout);
0437     if (color == d->color) {
0438         return;
0439     }
0440 
0441     d->color = color;
0442     if (d->labelItem) {
0443         d->labelItem->setProperty("color", color);
0444     }
0445 
0446     Q_EMIT colorChanged();
0447 }
0448 
0449 QRectF IconLabelLayout::iconRect() const
0450 {
0451     Q_D(const IconLabelLayout);
0452     return d->iconRect;
0453 }
0454 
0455 void IconLabelLayout::setIconRect(const QRectF &rect)
0456 {
0457     Q_D(IconLabelLayout);
0458     // Icons should always be pixel aligned
0459     QRectF alignedRect = rect.toAlignedRect();
0460     if (d->iconRect == alignedRect) {
0461         return;
0462     }
0463 
0464     d->iconRect = alignedRect;
0465     Q_EMIT iconRectChanged();
0466 }
0467 
0468 QRectF IconLabelLayout::labelRect() const
0469 {
0470     Q_D(const IconLabelLayout);
0471     return d->labelRect;
0472 }
0473 
0474 void IconLabelLayout::setLabelRect(const QRectF &rect)
0475 {
0476     Q_D(IconLabelLayout);
0477     if (d->labelRect == rect) {
0478         return;
0479     }
0480 
0481     d->labelRect = rect;
0482     Q_EMIT labelRectChanged();
0483 }
0484 
0485 qreal IconLabelLayout::availableWidth() const
0486 {
0487     Q_D(const IconLabelLayout);
0488     return d->availableWidth;
0489 }
0490 
0491 void IconLabelLayout::setAvailableWidth()
0492 {
0493     Q_D(IconLabelLayout);
0494     qreal newAvailableWidth = std::max(0.0, width() - leftPadding() - rightPadding());
0495     if (d->availableWidth == newAvailableWidth) {
0496         return;
0497     }
0498 
0499     d->availableWidth = newAvailableWidth;
0500     Q_EMIT availableWidthChanged();
0501 }
0502 
0503 qreal IconLabelLayout::availableHeight() const
0504 {
0505     Q_D(const IconLabelLayout);
0506     return d->availableHeight;
0507 }
0508 
0509 void IconLabelLayout::setAvailableHeight()
0510 {
0511     Q_D(IconLabelLayout);
0512     qreal newAvailableHeight = std::max(0.0, height() - topPadding() - bottomPadding());
0513     if (d->availableHeight == newAvailableHeight) {
0514         return;
0515     }
0516 
0517     d->availableHeight = newAvailableHeight;
0518     Q_EMIT availableHeightChanged();
0519 }
0520 
0521 qreal IconLabelLayout::spacing() const
0522 {
0523     Q_D(const IconLabelLayout);
0524     return d->spacing;
0525 }
0526 
0527 void IconLabelLayout::setSpacing(qreal spacing)
0528 {
0529     Q_D(IconLabelLayout);
0530     if (spacing == d->spacing) {
0531         return;
0532     }
0533 
0534     d->spacing = spacing;
0535     Q_EMIT spacingChanged();
0536     if (d->iconItem && d->labelItem) {
0537         relayout();
0538     }
0539 }
0540 
0541 qreal IconLabelLayout::leftPadding() const
0542 {
0543     Q_D(const IconLabelLayout);
0544     return d->leftPadding;
0545 }
0546 
0547 void IconLabelLayout::setLeftPadding(qreal leftPadding)
0548 {
0549     Q_D(IconLabelLayout);
0550     if (leftPadding == d->leftPadding) {
0551         return;
0552     }
0553 
0554     d->leftPadding = leftPadding;
0555     Q_EMIT leftPaddingChanged();
0556     relayout();
0557 }
0558 
0559 qreal IconLabelLayout::rightPadding() const
0560 {
0561     Q_D(const IconLabelLayout);
0562     return d->rightPadding;
0563 }
0564 
0565 void IconLabelLayout::setRightPadding(qreal rightPadding)
0566 {
0567     Q_D(IconLabelLayout);
0568     if (rightPadding == d->rightPadding) {
0569         return;
0570     }
0571 
0572     d->rightPadding = rightPadding;
0573     Q_EMIT rightPaddingChanged();
0574     relayout();
0575 }
0576 
0577 qreal IconLabelLayout::topPadding() const
0578 {
0579     Q_D(const IconLabelLayout);
0580     return d->topPadding;
0581 }
0582 
0583 void IconLabelLayout::setTopPadding(qreal topPadding)
0584 {
0585     Q_D(IconLabelLayout);
0586     if (topPadding == d->topPadding) {
0587         return;
0588     }
0589 
0590     d->topPadding = topPadding;
0591     Q_EMIT topPaddingChanged();
0592     relayout();
0593 }
0594 
0595 qreal IconLabelLayout::bottomPadding() const
0596 {
0597     Q_D(const IconLabelLayout);
0598     return d->bottomPadding;
0599 }
0600 
0601 void IconLabelLayout::setBottomPadding(qreal bottomPadding)
0602 {
0603     Q_D(IconLabelLayout);
0604     if (bottomPadding == d->bottomPadding) {
0605         return;
0606     }
0607 
0608     d->bottomPadding = bottomPadding;
0609     Q_EMIT bottomPaddingChanged();
0610     relayout();
0611 }
0612 
0613 bool IconLabelLayout::mirrored() const
0614 {
0615     Q_D(const IconLabelLayout);
0616     return d->mirrored;
0617 }
0618 
0619 void IconLabelLayout::setMirrored(bool mirrored)
0620 {
0621     Q_D(IconLabelLayout);
0622     if (mirrored == d->mirrored) {
0623         return;
0624     }
0625 
0626     d->mirrored = mirrored;
0627     Q_EMIT mirroredChanged();
0628     if (isComponentComplete()) {
0629         d->layout();
0630     }
0631 }
0632 
0633 Qt::Alignment IconLabelLayout::alignment() const
0634 {
0635     Q_D(const IconLabelLayout);
0636     return d->alignment;
0637 }
0638 
0639 void IconLabelLayout::setAlignment(Qt::Alignment alignment)
0640 {
0641     Q_D(IconLabelLayout);
0642     const int valign = alignment & Qt::AlignVertical_Mask;
0643     const int halign = alignment & Qt::AlignHorizontal_Mask;
0644     const uint align = (valign ? valign : Qt::AlignVCenter) | (halign ? halign : Qt::AlignHCenter);
0645     if (d->alignment == align) {
0646         return;
0647     }
0648 
0649     d->alignment = static_cast<Qt::Alignment>(align);
0650     if (d->labelItem) {
0651         d->labelItem->setProperty("horizontalAlignment", halign);
0652         d->labelItem->setProperty("verticalAlignment", valign);
0653     }
0654     Q_EMIT alignmentChanged();
0655     if (isComponentComplete()) {
0656         d->layout();
0657     }
0658 }
0659 
0660 IconLabelLayout::Display IconLabelLayout::display() const
0661 {
0662     Q_D(const IconLabelLayout);
0663     return d->display;
0664 }
0665 
0666 void IconLabelLayout::setDisplay(IconLabelLayout::Display display)
0667 {
0668     Q_D(IconLabelLayout);
0669     Display oldDisplay = d->display;
0670     if (display == oldDisplay) {
0671         return;
0672     }
0673 
0674     d->display = display;
0675     Q_EMIT displayChanged();
0676 
0677     if (oldDisplay == iconOnly()) {
0678         Q_EMIT iconOnlyChanged();
0679     } else if (oldDisplay == textOnly()) {
0680         Q_EMIT textOnlyChanged();
0681     } else if (oldDisplay == textBesideIcon()) {
0682         Q_EMIT textBesideIconChanged();
0683     } else if (oldDisplay == textUnderIcon()) {
0684         Q_EMIT textUnderIconChanged();
0685     }
0686 
0687     setHasIcon();
0688     setHasLabel();
0689 
0690     d->updateIconItem();
0691     d->updateLabelItem();
0692     relayout();
0693 }
0694 
0695 bool IconLabelLayout::iconOnly() const
0696 {
0697     Q_D(const IconLabelLayout);
0698     return d->display == Display::IconOnly;
0699 }
0700 
0701 bool IconLabelLayout::textOnly() const
0702 {
0703     Q_D(const IconLabelLayout);
0704     return d->display == Display::TextOnly;
0705 }
0706 
0707 bool IconLabelLayout::textBesideIcon() const
0708 {
0709     Q_D(const IconLabelLayout);
0710     return d->display == Display::TextBesideIcon;
0711 }
0712 
0713 bool IconLabelLayout::textUnderIcon() const
0714 {
0715     Q_D(const IconLabelLayout);
0716     return d->display == Display::TextUnderIcon;
0717 }
0718 
0719 void IconLabelLayout::relayout()
0720 {
0721     Q_D(IconLabelLayout);
0722     if (isComponentComplete()) {
0723         d->updateImplicitSize();
0724         d->layout();
0725     }
0726 }
0727 
0728 void IconLabelLayout::componentComplete()
0729 {
0730     QQuickItem::componentComplete();
0731     relayout();
0732 }
0733 
0734 void IconLabelLayout::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
0735 {
0736     if (newGeometry != oldGeometry) {
0737         setAvailableWidth();
0738         setAvailableHeight();
0739         relayout();
0740     }
0741     QQuickItem::geometryChange(newGeometry, oldGeometry);
0742 }
0743 
0744 #include "moc_iconlabellayout.cpp"