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"