From 53a101f35b76ccea0e8a6bd00055259811df41d1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 11 Apr 2017 16:42:12 +0200 Subject: QQuickIconLabel: create icon and label items lazily Before: Average: 120.2 frames; using samples; MedianAll=120; StdDev=0.447214, CoV=0.00372058 After: Average: 129.8 frames; using samples; MedianAll=130; StdDev=0.447214, CoV=0.00344541 Task-number: QTBUG-59746 Change-Id: I44b521688cd60e7e287968828f9d4062cc642a0d Reviewed-by: J-P Nurmi --- src/imports/controls/Button.qml | 22 +- src/imports/controls/ToolButton.qml | 17 +- src/imports/controls/material/Button.qml | 21 +- src/imports/controls/material/ToolButton.qml | 19 +- src/imports/controls/universal/Button.qml | 18 +- src/imports/controls/universal/ToolButton.qml | 18 +- src/quickcontrols2/qquickiconlabel.cpp | 295 ++++++++++++++++----- src/quickcontrols2/qquickiconlabel_p.h | 21 +- src/quickcontrols2/qquickiconlabel_p_p.h | 30 ++- tests/auto/controls/data/tst_button.qml | 47 ++-- tests/auto/controls/data/tst_toolbutton.qml | 38 ++- tests/auto/qquickiconlabel/data/iconlabel.qml | 13 +- .../qquickiconlabel/data/spacingWithOnlyIcon.qml | 9 +- .../qquickiconlabel/data/spacingWithOnlyText.qml | 5 +- tests/auto/qquickiconlabel/tst_qquickiconlabel.cpp | 50 ++-- 15 files changed, 381 insertions(+), 242 deletions(-) diff --git a/src/imports/controls/Button.qml b/src/imports/controls/Button.qml index 8a98bbad..438265d1 100644 --- a/src/imports/controls/Button.qml +++ b/src/imports/controls/Button.qml @@ -62,22 +62,12 @@ T.Button { mirrored: control.mirrored display: control.display - icon: IconImage { - name: control.icon.name - source: control.icon.source - sourceSize.width: control.icon.width - sourceSize.height: control.icon.height - color: control.icon.color - } - label: Text { - text: control.text - font: control.font - opacity: enabled || control.highlighted || control.checked ? 1 : 0.3 - color: control.checked || control.highlighted ? - Default.textLightColor : - (control.visualFocus ? Default.focusColor : (control.down ? Default.textDarkColor : Default.textColor)) - elide: Text.ElideRight - } + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.checked || control.highlighted ? Default.textLightColor : + control.visualFocus ? Default.focusColor : control.down ? Default.textDarkColor : Default.textColor, + enabled || control.highlighted || control.checked ? 1 : 0.3) } background: Rectangle { diff --git a/src/imports/controls/ToolButton.qml b/src/imports/controls/ToolButton.qml index e31f45a0..184bbfad 100644 --- a/src/imports/controls/ToolButton.qml +++ b/src/imports/controls/ToolButton.qml @@ -60,19 +60,10 @@ T.ToolButton { mirrored: control.mirrored display: control.display - icon: IconImage { - name: control.icon.name - source: control.icon.source - sourceSize.width: control.icon.width - sourceSize.height: control.icon.height - color: control.icon.color - } - label: Text { - text: control.text - font: control.font - color: control.enabled ? (control.visualFocus ? Default.focusColor : Default.textDarkColor) : Default.textDisabledLightColor - elide: Text.ElideRight - } + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? (control.visualFocus ? Default.focusColor : Default.textDarkColor) : Default.textDisabledLightColor } background: Rectangle { diff --git a/src/imports/controls/material/Button.qml b/src/imports/controls/material/Button.qml index 0142dacf..9e21c8a0 100644 --- a/src/imports/controls/material/Button.qml +++ b/src/imports/controls/material/Button.qml @@ -69,21 +69,12 @@ T.Button { mirrored: control.mirrored display: control.display - icon: IconImage { - name: control.icon.name - source: control.icon.source - sourceSize.width: control.icon.width - sourceSize.height: control.icon.height - color: control.icon.color - } - label: Text { - text: control.text - font: control.font - color: !control.enabled ? control.Material.hintTextColor : - control.flat && control.highlighted ? control.Material.accentColor : - control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.foreground - elide: Text.ElideRight - } + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Material.hintTextColor : + control.flat && control.highlighted ? control.Material.accentColor : + control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.foreground } // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state diff --git a/src/imports/controls/material/ToolButton.qml b/src/imports/controls/material/ToolButton.qml index 4f0fdc9b..c794a468 100644 --- a/src/imports/controls/material/ToolButton.qml +++ b/src/imports/controls/material/ToolButton.qml @@ -62,20 +62,11 @@ T.ToolButton { mirrored: control.mirrored display: control.display - icon: IconImage { - name: control.icon.name - source: control.icon.source - sourceSize.width: control.icon.width - sourceSize.height: control.icon.height - color: control.icon.color - } - label: Text { - text: control.text - font: control.font - color: !control.enabled ? control.Material.hintTextColor : - control.checked || control.highlighted ? control.Material.accent : control.Material.foreground - elide: Text.ElideRight - } + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Material.hintTextColor : + control.checked || control.highlighted ? control.Material.accent : control.Material.foreground } background: Ripple { diff --git a/src/imports/controls/universal/Button.qml b/src/imports/controls/universal/Button.qml index d2f4f10d..44f86a38 100644 --- a/src/imports/controls/universal/Button.qml +++ b/src/imports/controls/universal/Button.qml @@ -65,20 +65,10 @@ T.Button { mirrored: control.mirrored display: control.display - icon: IconImage { - name: control.icon.name - source: control.icon.source - sourceSize.width: control.icon.width - sourceSize.height: control.icon.height - color: control.icon.color - } - label: Text { - text: control.text - font: control.font - elide: Text.ElideRight - opacity: enabled ? 1.0 : 0.2 - color: control.Universal.foreground - } + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) } background: Rectangle { diff --git a/src/imports/controls/universal/ToolButton.qml b/src/imports/controls/universal/ToolButton.qml index 5a2e98fd..3b349717 100644 --- a/src/imports/controls/universal/ToolButton.qml +++ b/src/imports/controls/universal/ToolButton.qml @@ -63,20 +63,10 @@ T.ToolButton { mirrored: control.mirrored display: control.display - icon: IconImage { - name: control.icon.name - source: control.icon.source - sourceSize.width: control.icon.width - sourceSize.height: control.icon.height - color: control.icon.color - } - label: Text { - text: control.text - font: control.font - elide: Text.ElideRight - opacity: enabled ? 1.0 : 0.2 - color: control.Universal.foreground - } + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) } background: Rectangle { diff --git a/src/quickcontrols2/qquickiconlabel.cpp b/src/quickcontrols2/qquickiconlabel.cpp index cfb733ac..3d7aac06 100644 --- a/src/quickcontrols2/qquickiconlabel.cpp +++ b/src/quickcontrols2/qquickiconlabel.cpp @@ -36,38 +36,184 @@ #include "qquickiconlabel_p.h" #include "qquickiconlabel_p_p.h" +#include "qquickiconimage_p.h" #include #include +#include +#include QT_BEGIN_NAMESPACE +static void beginClass(QQuickItem *item) +{ + if (QQmlParserStatus *parserStatus = qobject_cast(item)) + parserStatus->classBegin(); +} + +static void completeComponent(QQuickItem *item) +{ + if (QQmlParserStatus *parserStatus = qobject_cast(item)) + parserStatus->componentComplete(); +} + QQuickIconLabelPrivate::QQuickIconLabelPrivate() - : icon(nullptr), - label(nullptr), + : mirrored(false), display(QQuickIconLabel::TextBesideIcon), alignment(Qt::AlignCenter), spacing(0), - mirrored(false), topPadding(0), leftPadding(0), rightPadding(0), - bottomPadding(0) + bottomPadding(0), + icon(nullptr), + image(nullptr), + label(nullptr) +{ +} + +bool QQuickIconLabelPrivate::hasIcon() const +{ + return display != QQuickIconLabel::TextOnly && icon && (!icon->name().isEmpty() || !icon->source().isEmpty()); +} + +bool QQuickIconLabelPrivate::hasText() const +{ + return display != QQuickIconLabel::IconOnly && !text.isEmpty(); +} + +bool QQuickIconLabelPrivate::createImage() +{ + Q_Q(QQuickIconLabel); + if (image) + return false; + + image = new QQuickIconImage(q); + watchChanges(image); + beginClass(image); + image->setObjectName(QLatin1String("image")); + image->setName(icon->name()); + image->setSource(icon->source()); + image->setSourceSize(QSize(icon->width(), icon->height())); + image->setColor(icon->color()); + if (componentComplete) + completeComponent(image); + return true; +} + +bool QQuickIconLabelPrivate::destroyImage() +{ + if (!image) + return false; + + unwatchChanges(image); + delete image; + image = nullptr; + return true; +} + +bool QQuickIconLabelPrivate::updateImage() +{ + if (!hasIcon()) + return destroyImage(); + return createImage(); +} + +void QQuickIconLabelPrivate::syncImage() +{ + if (!image || !icon) + return; + + image->setName(icon->name()); + image->setSource(icon->source()); +} + +void QQuickIconLabelPrivate::updateOrSyncImage() +{ + if (updateImage()) { + updateImplicitSize(); + layout(); + } else { + syncImage(); + } +} + +bool QQuickIconLabelPrivate::createLabel() { + Q_Q(QQuickIconLabel); + if (label) + return false; + + label = new QQuickText(q); + watchChanges(label); + beginClass(label); + label->setObjectName(QLatin1String("label")); + label->setFont(font); + label->setColor(color); + label->setElideMode(QQuickText::ElideRight); + label->setText(text); + if (componentComplete) + completeComponent(label); + return true; +} + +bool QQuickIconLabelPrivate::destroyLabel() +{ + if (!label) + return false; + + unwatchChanges(label); + delete label; + label = nullptr; + return true; +} + +bool QQuickIconLabelPrivate::updateLabel() +{ + if (!hasText()) + return destroyLabel(); + return createLabel(); +} + +void QQuickIconLabelPrivate::syncLabel() +{ + if (!label) + return; + + label->setText(text); +} + +void QQuickIconLabelPrivate::updateOrSyncLabel() +{ + if (updateLabel()) { + updateImplicitSize(); + layout(); + } else { + syncLabel(); + } +} + +void QQuickIconLabelPrivate::updateIcon() +{ + if (!image || !icon) + return; + + image->setColor(icon->color()); + image->setSourceSize(QSize(icon->width(), icon->height())); } void QQuickIconLabelPrivate::updateImplicitSize() { Q_Q(QQuickIconLabel); - const bool showIcon = icon && display != QQuickIconLabel::TextOnly; - const bool showText = label && display != QQuickIconLabel::IconOnly; + const bool showIcon = image && hasIcon(); + const bool showText = label && hasText(); const qreal horizontalPadding = leftPadding + rightPadding; const qreal verticalPadding = topPadding + bottomPadding; - const qreal iconImplicitWidth = showIcon ? icon->implicitWidth() : 0; - const qreal iconImplicitHeight = showIcon ? icon->implicitHeight() : 0; + const qreal iconImplicitWidth = showIcon ? image->implicitWidth() : 0; + const qreal iconImplicitHeight = showIcon ? image->implicitHeight() : 0; const qreal textImplicitWidth = showText ? label->implicitWidth() : 0; const qreal textImplicitHeight = showText ? label->implicitHeight() : 0; - const qreal effectiveSpacing = showText && showIcon && icon->implicitWidth() > 0 ? spacing : 0; + const qreal effectiveSpacing = showText && showIcon && image->implicitWidth() > 0 ? spacing : 0; const qreal implicitWidth = display == QQuickIconLabel::TextBesideIcon ? iconImplicitWidth + textImplicitWidth + effectiveSpacing : qMax(iconImplicitWidth, textImplicitWidth); const qreal implicitHeight = display == QQuickIconLabel::TextUnderIcon ? iconImplicitHeight + textImplicitHeight + effectiveSpacing @@ -104,17 +250,14 @@ void QQuickIconLabelPrivate::layout() switch (display) { case QQuickIconLabel::IconOnly: - if (icon) { + if (image) { const QRectF iconRect = alignedRect(mirrored, alignment, - QSizeF(qMin(icon->implicitWidth(), availableWidth), - qMin(icon->implicitHeight(), availableHeight)), + QSizeF(qMin(image->implicitWidth(), availableWidth), + qMin(image->implicitHeight(), availableHeight)), QRectF(leftPadding, topPadding, availableWidth, availableHeight)); - icon->setSize(iconRect.size()); - icon->setPosition(iconRect.topLeft()); - icon->setVisible(true); + image->setSize(iconRect.size()); + image->setPosition(iconRect.topLeft()); } - if (label) - label->setVisible(false); break; case QQuickIconLabel::TextOnly: if (label) { @@ -124,19 +267,16 @@ void QQuickIconLabelPrivate::layout() QRectF(leftPadding, topPadding, availableWidth, availableHeight)); label->setSize(textRect.size()); label->setPosition(textRect.topLeft()); - label->setVisible(true); } - if (icon) - icon->setVisible(false); break; case QQuickIconLabel::TextUnderIcon: { // Work out the sizes first, as the positions depend on them. QSizeF iconSize; QSizeF textSize; - if (icon) { - iconSize.setWidth(qMin(icon->implicitWidth(), availableWidth)); - iconSize.setHeight(qMin(icon->implicitHeight(), availableHeight)); + if (image) { + iconSize.setWidth(qMin(image->implicitWidth(), availableWidth)); + iconSize.setHeight(qMin(image->implicitHeight(), availableHeight)); } qreal effectiveSpacing = 0; if (label) { @@ -150,17 +290,15 @@ void QQuickIconLabelPrivate::layout() QSizeF(qMax(iconSize.width(), textSize.width()), iconSize.height() + effectiveSpacing + textSize.height()), QRectF(leftPadding, topPadding, availableWidth, availableHeight)); - if (icon) { + if (image) { QRectF iconRect = alignedRect(mirrored, Qt::AlignHCenter | Qt::AlignTop, iconSize, combinedRect); - icon->setSize(iconRect.size()); - icon->setPosition(iconRect.topLeft()); - icon->setVisible(true); + image->setSize(iconRect.size()); + image->setPosition(iconRect.topLeft()); } if (label) { QRectF textRect = alignedRect(mirrored, Qt::AlignHCenter | Qt::AlignBottom, textSize, combinedRect); label->setSize(textRect.size()); label->setPosition(textRect.topLeft()); - label->setVisible(true); } break; } @@ -170,9 +308,9 @@ void QQuickIconLabelPrivate::layout() // Work out the sizes first, as the positions depend on them. QSizeF iconSize(0, 0); QSizeF textSize(0, 0); - if (icon) { - iconSize.setWidth(qMin(icon->implicitWidth(), availableWidth)); - iconSize.setHeight(qMin(icon->implicitHeight(), availableHeight)); + if (image) { + iconSize.setWidth(qMin(image->implicitWidth(), availableWidth)); + iconSize.setHeight(qMin(image->implicitHeight(), availableHeight)); } qreal effectiveSpacing = 0; if (label) { @@ -186,17 +324,15 @@ void QQuickIconLabelPrivate::layout() QSizeF(iconSize.width() + effectiveSpacing + textSize.width(), qMax(iconSize.height(), textSize.height())), QRectF(leftPadding, topPadding, availableWidth, availableHeight)); - if (icon) { + if (image) { const QRectF iconRect = alignedRect(mirrored, Qt::AlignLeft | Qt::AlignVCenter, iconSize, combinedRect); - icon->setSize(iconRect.size()); - icon->setPosition(iconRect.topLeft()); - icon->setVisible(true); + image->setSize(iconRect.size()); + image->setPosition(iconRect.topLeft()); } if (label) { const QRectF textRect = alignedRect(mirrored, Qt::AlignRight | Qt::AlignVCenter, textSize, combinedRect); label->setSize(textRect.size()); label->setPosition(textRect.topLeft()); - label->setVisible(true); } break; } @@ -234,8 +370,8 @@ void QQuickIconLabelPrivate::itemImplicitHeightChanged(QQuickItem *) void QQuickIconLabelPrivate::itemDestroyed(QQuickItem *item) { unwatchChanges(item); - if (item == icon) - icon = nullptr; + if (item == image) + image = nullptr; else if (item == label) label = nullptr; } @@ -248,60 +384,92 @@ QQuickIconLabel::QQuickIconLabel(QQuickItem *parent) QQuickIconLabel::~QQuickIconLabel() { Q_D(QQuickIconLabel); - if (d->icon) - d->unwatchChanges(d->icon); + if (d->image) + d->unwatchChanges(d->image); if (d->label) d->unwatchChanges(d->label); } -QQuickItem *QQuickIconLabel::icon() const +QQuickIcon *QQuickIconLabel::icon() const { Q_D(const QQuickIconLabel); return d->icon; } -void QQuickIconLabel::setIcon(QQuickItem *icon) +void QQuickIconLabel::setIcon(QQuickIcon *icon) { Q_D(QQuickIconLabel); if (d->icon == icon) return; - if (d->icon) - d->unwatchChanges(d->icon); + if (QQuickIcon *oldIcon = d->icon) { + QObjectPrivate::disconnect(oldIcon, &QQuickIcon::nameChanged, d, &QQuickIconLabelPrivate::updateOrSyncImage); + QObjectPrivate::disconnect(oldIcon, &QQuickIcon::sourceChanged, d, &QQuickIconLabelPrivate::updateOrSyncImage); + QObjectPrivate::disconnect(oldIcon, &QQuickIcon::colorChanged, d, &QQuickIconLabelPrivate::updateIcon); + QObjectPrivate::disconnect(oldIcon, &QQuickIcon::widthChanged, d, &QQuickIconLabelPrivate::updateIcon); + QObjectPrivate::disconnect(oldIcon, &QQuickIcon::heightChanged, d, &QQuickIconLabelPrivate::updateIcon); + } d->icon = icon; if (icon) { - icon->setParentItem(this); - d->watchChanges(icon); + QObjectPrivate::connect(icon, &QQuickIcon::nameChanged, d, &QQuickIconLabelPrivate::updateOrSyncImage); + QObjectPrivate::connect(icon, &QQuickIcon::sourceChanged, d, &QQuickIconLabelPrivate::updateOrSyncImage); + QObjectPrivate::connect(icon, &QQuickIcon::colorChanged, d, &QQuickIconLabelPrivate::updateIcon); + QObjectPrivate::connect(icon, &QQuickIcon::widthChanged, d, &QQuickIconLabelPrivate::updateIcon); + QObjectPrivate::connect(icon, &QQuickIcon::heightChanged, d, &QQuickIconLabelPrivate::updateIcon); } - d->updateImplicitSize(); - d->layout(); + d->updateOrSyncImage(); } -QQuickItem *QQuickIconLabel::label() const +QString QQuickIconLabel::text() const { Q_D(const QQuickIconLabel); - return d->label; + return d->text; } -void QQuickIconLabel::setLabel(QQuickItem *label) +void QQuickIconLabel::setText(const QString text) { Q_D(QQuickIconLabel); - if (d->label == label) + if (d->text == text) return; + d->text = text; + d->updateOrSyncLabel(); +} + +QFont QQuickIconLabel::font() const +{ + Q_D(const QQuickIconLabel); + return d->font; +} + +void QQuickIconLabel::setFont(const QFont &font) +{ + Q_D(QQuickIconLabel); + if (d->font == font) + return; + + d->font = font; if (d->label) - d->unwatchChanges(d->label); + d->label->setFont(font); +} - d->label = label; - if (label) { - label->setParentItem(this); - d->watchChanges(label); - } +QColor QQuickIconLabel::color() const +{ + Q_D(const QQuickIconLabel); + return d->color; +} - d->updateImplicitSize(); - d->layout(); +void QQuickIconLabel::setColor(const QColor &color) +{ + Q_D(QQuickIconLabel); + if (d->color == color) + return; + + d->color = color; + if (d->label) + d->label->setColor(color); } QQuickIconLabel::Display QQuickIconLabel::display() const @@ -317,6 +485,8 @@ void QQuickIconLabel::setDisplay(Display display) return; d->display = display; + d->updateImage(); + d->updateLabel(); d->updateImplicitSize(); d->layout(); } @@ -351,7 +521,6 @@ void QQuickIconLabel::setMirrored(bool mirrored) return; d->mirrored = mirrored; - d->updateImplicitSize(); d->layout(); } @@ -466,6 +635,10 @@ void QQuickIconLabel::componentComplete() { Q_D(QQuickIconLabel); QQuickItem::componentComplete(); + if (d->image) + completeComponent(d->image); + if (d->label) + completeComponent(d->label); d->layout(); } diff --git a/src/quickcontrols2/qquickiconlabel_p.h b/src/quickcontrols2/qquickiconlabel_p.h index 880d088e..63b7fbd2 100644 --- a/src/quickcontrols2/qquickiconlabel_p.h +++ b/src/quickcontrols2/qquickiconlabel_p.h @@ -53,13 +53,16 @@ QT_BEGIN_NAMESPACE +class QQuickIcon; class QQuickIconLabelPrivate; class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickIconLabel : public QQuickItem { Q_OBJECT - Q_PROPERTY(QQuickItem *icon READ icon WRITE setIcon FINAL) - Q_PROPERTY(QQuickItem *label READ label WRITE setLabel FINAL) + Q_PROPERTY(QQuickIcon *icon READ icon WRITE setIcon FINAL) + Q_PROPERTY(QString text READ text WRITE setText FINAL) + Q_PROPERTY(QFont font READ font WRITE setFont FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) Q_PROPERTY(Display display READ display WRITE setDisplay FINAL) Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing FINAL) Q_PROPERTY(bool mirrored READ isMirrored WRITE setMirrored FINAL) @@ -81,11 +84,17 @@ public: explicit QQuickIconLabel(QQuickItem *parent = nullptr); ~QQuickIconLabel(); - QQuickItem *icon() const; - void setIcon(QQuickItem *icon); + QQuickIcon *icon() const; + void setIcon(QQuickIcon *icon); - QQuickItem *label() const; - void setLabel(QQuickItem *label); + QString text() const; + void setText(const QString text); + + QFont font() const; + void setFont(const QFont &font); + + QColor color() const; + void setColor(const QColor &color); Display display() const; void setDisplay(Display display); diff --git a/src/quickcontrols2/qquickiconlabel_p_p.h b/src/quickcontrols2/qquickiconlabel_p_p.h index bdd3e373..00c2d404 100644 --- a/src/quickcontrols2/qquickiconlabel_p_p.h +++ b/src/quickcontrols2/qquickiconlabel_p_p.h @@ -54,6 +54,10 @@ QT_BEGIN_NAMESPACE +class QQuickText; +class QQuickIcon; +class QQuickIconImage; + class QQuickIconLabelPrivate : public QQuickItemPrivate, public QQuickItemChangeListener { Q_DECLARE_PUBLIC(QQuickIconLabel) @@ -61,6 +65,22 @@ class QQuickIconLabelPrivate : public QQuickItemPrivate, public QQuickItemChange public: explicit QQuickIconLabelPrivate(); + bool hasIcon() const; + bool hasText() const; + + bool createImage(); + bool destroyImage(); + bool updateImage(); + void syncImage(); + void updateOrSyncImage(); + + bool createLabel(); + bool destroyLabel(); + bool updateLabel(); + void syncLabel(); + void updateOrSyncLabel(); + + void updateIcon(); void updateImplicitSize(); void layout(); @@ -74,16 +94,20 @@ public: void itemImplicitHeightChanged(QQuickItem *) override; void itemDestroyed(QQuickItem *item) override; - QQuickItem *icon; - QQuickItem *label; + bool mirrored; QQuickIconLabel::Display display; Qt::Alignment alignment; qreal spacing; - bool mirrored; qreal topPadding; qreal leftPadding; qreal rightPadding; qreal bottomPadding; + QFont font; + QColor color; + QString text; + QQuickIcon *icon; + QQuickIconImage *image; + QQuickText *label; }; QT_END_NAMESPACE diff --git a/tests/auto/controls/data/tst_button.qml b/tests/auto/controls/data/tst_button.qml index aa9e5751..67268187 100644 --- a/tests/auto/controls/data/tst_button.qml +++ b/tests/auto/controls/data/tst_button.qml @@ -437,16 +437,19 @@ TestCase { verify(control) verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + // The implicitWidth of the IconLabel that all buttons use as their contentItem // should be equal to the implicitWidth of the Text while no icon is set. - compare(control.contentItem.implicitWidth, control.contentItem.label.implicitWidth) + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) // That means that spacing shouldn't affect it. control.spacing += 100 - compare(control.contentItem.implicitWidth, control.contentItem.label.implicitWidth) + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) // The implicitWidth of the Button itself should, therefore, also never include spacing while no icon is set. - compare(control.implicitWidth, control.contentItem.label.implicitWidth + control.leftPadding + control.rightPadding) + compare(control.implicitWidth, textLabel.implicitWidth + control.leftPadding + control.rightPadding) } function test_display_data() { @@ -472,42 +475,38 @@ TestCase { verify(control) verify(control.icon.source.length > 0) - var iconImage = control.contentItem.icon - verify(iconImage) - verify(iconImage.hasOwnProperty("name")) - var label = control.contentItem.label - verify(label) - verify(label.hasOwnProperty("text")) + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") switch (control.display) { case Button.IconOnly: - compare(iconImage.visible, true) - compare(label.visible, false) + verify(iconImage) + verify(!textLabel) compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) break; case Button.TextOnly: - compare(iconImage.visible, false) - compare(label.visible, true) - compare(label.x, (control.availableWidth - label.width) / 2) - compare(label.y, (control.availableHeight - label.height) / 2) + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) break; case Button.TextUnderIcon: - compare(iconImage.visible, true) - compare(label.visible, true) + verify(iconImage) + verify(textLabel) compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) - compare(label.x, (control.availableWidth - label.width) / 2) - verify(iconImage.y < label.y) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) break; case Button.TextBesideIcon: - compare(iconImage.visible, true) - compare(label.visible, true) + verify(iconImage) + verify(textLabel) if (control.mirrored) - verify(label.x < iconImage.x) + verify(textLabel.x < iconImage.x) else - verify(iconImage.x < label.x) + verify(iconImage.x < textLabel.x) compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) - compare(label.y, (control.availableHeight - label.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) break; } } diff --git a/tests/auto/controls/data/tst_toolbutton.qml b/tests/auto/controls/data/tst_toolbutton.qml index 58daf119..ed76db13 100644 --- a/tests/auto/controls/data/tst_toolbutton.qml +++ b/tests/auto/controls/data/tst_toolbutton.qml @@ -205,42 +205,38 @@ TestCase { verify(control) verify(control.icon.source.length > 0) - var iconImage = control.contentItem.icon - verify(iconImage) - verify(iconImage.hasOwnProperty("name")) - var label = control.contentItem.label - verify(label) - verify(label.hasOwnProperty("text")) + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") switch (control.display) { case ToolButton.IconOnly: - compare(iconImage.visible, true) - compare(label.visible, false) + verify(iconImage) + verify(!textLabel) compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) break; case ToolButton.TextOnly: - compare(iconImage.visible, false) - compare(label.visible, true) - compare(label.x, (control.availableWidth - label.width) / 2) - compare(label.y, (control.availableHeight - label.height) / 2) + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) break; case ToolButton.TextUnderIcon: - compare(iconImage.visible, true) - compare(label.visible, true) + verify(iconImage) + verify(textLabel) compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) - compare(label.x, (control.availableWidth - label.width) / 2) - verify(iconImage.y < label.y) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) break; case ToolButton.TextBesideIcon: - compare(iconImage.visible, true) - compare(label.visible, true) + verify(iconImage) + verify(textLabel) if (control.mirrored) - verify(label.x < iconImage.x) + verify(textLabel.x < iconImage.x) else - verify(iconImage.x < label.x) + verify(iconImage.x < textLabel.x) compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) - compare(label.y, (control.availableHeight - label.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) break; } } diff --git a/tests/auto/qquickiconlabel/data/iconlabel.qml b/tests/auto/qquickiconlabel/data/iconlabel.qml index e4edb970..7a1bafdf 100644 --- a/tests/auto/qquickiconlabel/data/iconlabel.qml +++ b/tests/auto/qquickiconlabel/data/iconlabel.qml @@ -52,16 +52,15 @@ import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Controls.impl 2.3 -Item { +AbstractButton { + id: button width: 200 height: 200 + text: "Some text" + icon.source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/images/check.png" IconLabel { - icon: Image { - source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/images/check.png" - } - label: Text { - text: "Some text" - } + icon: button.icon + text: button.text } } diff --git a/tests/auto/qquickiconlabel/data/spacingWithOnlyIcon.qml b/tests/auto/qquickiconlabel/data/spacingWithOnlyIcon.qml index ee1c9b73..858f84b2 100644 --- a/tests/auto/qquickiconlabel/data/spacingWithOnlyIcon.qml +++ b/tests/auto/qquickiconlabel/data/spacingWithOnlyIcon.qml @@ -52,16 +52,15 @@ import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Controls.impl 2.3 -Item { +AbstractButton { + id: button width: 200 height: 200 + icon.source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/images/check.png" IconLabel { spacing: 10 mirrored: true - - icon: Image { - source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/images/check.png" - } + icon: button.icon } } diff --git a/tests/auto/qquickiconlabel/data/spacingWithOnlyText.qml b/tests/auto/qquickiconlabel/data/spacingWithOnlyText.qml index e4d8259d..82eb5aee 100644 --- a/tests/auto/qquickiconlabel/data/spacingWithOnlyText.qml +++ b/tests/auto/qquickiconlabel/data/spacingWithOnlyText.qml @@ -58,9 +58,6 @@ Item { IconLabel { spacing: 10 - - label: Text { - text: "Some text" - } + text: "Some text" } } diff --git a/tests/auto/qquickiconlabel/tst_qquickiconlabel.cpp b/tests/auto/qquickiconlabel/tst_qquickiconlabel.cpp index e1cada68..9e7c6794 100644 --- a/tests/auto/qquickiconlabel/tst_qquickiconlabel.cpp +++ b/tests/auto/qquickiconlabel/tst_qquickiconlabel.cpp @@ -32,7 +32,9 @@ #include #include - +#include +#include +#include #include #include "../shared/util.h" @@ -118,7 +120,7 @@ void tst_qquickiconlabel::display() QQuickItem *rootItem = view.rootObject(); QVERIFY(rootItem); - QQuickIconLabel *label = qobject_cast(rootItem->childItems().first()); + QQuickIconLabel *label = rootItem->findChild(); QVERIFY(label); QCOMPARE(label->spacing(), 0.0); QCOMPARE(label->display(), QQuickIconLabel::TextBesideIcon); @@ -135,12 +137,6 @@ void tst_qquickiconlabel::display() QCOMPARE(label->height(), labelHeight); } - QQuickItem *icon = label->icon(); - QVERIFY(icon); - - QQuickItem *text = label->label(); - QVERIFY(text); - label->setMirrored(mirrored); QCOMPARE(label->isMirrored(), mirrored); @@ -156,61 +152,64 @@ void tst_qquickiconlabel::display() label->setDisplay(displayType); QCOMPARE(label->display(), displayType); + QQuickIconImage *icon = label->findChild(); + QQuickText *text = label->findChild(); + const qreal horizontalCenter = label->width() / 2; const qreal verticalCenter = label->height() / 2; switch (displayType) { case QQuickIconLabel::IconOnly: + QVERIFY(icon); + QVERIFY(!text); QCOMPARE(icon->x(), horizontalCenter - icon->width() / 2); QCOMPARE(icon->y(), verticalCenter - icon->height() / 2); QCOMPARE(icon->width(), icon->implicitWidth()); QCOMPARE(icon->height(), icon->implicitHeight()); - QCOMPARE(icon->isVisible(), true); - QCOMPARE(text->isVisible(), false); QCOMPARE(label->implicitWidth(), icon->implicitWidth() + horizontalPadding); QCOMPARE(label->implicitHeight(), icon->implicitHeight() + verticalPadding); break; case QQuickIconLabel::TextOnly: - QCOMPARE(icon->isVisible(), false); + QVERIFY(!icon); + QVERIFY(text); QCOMPARE(text->x(), horizontalCenter - text->width() / 2); QCOMPARE(text->y(), verticalCenter - text->height() / 2); QCOMPARE(text->width(), text->implicitWidth()); QCOMPARE(text->height(), text->implicitHeight()); - QCOMPARE(text->isVisible(), true); QCOMPARE(label->implicitWidth(), text->implicitWidth() + horizontalPadding); QCOMPARE(label->implicitHeight(), text->implicitHeight() + verticalPadding); break; case QQuickIconLabel::TextUnderIcon: { + QVERIFY(icon); + QVERIFY(text); const qreal combinedHeight = icon->height() + label->spacing() + text->height(); const qreal contentY = verticalCenter - combinedHeight / 2; QCOMPARE(icon->x(), horizontalCenter - icon->width() / 2); QCOMPARE(icon->y(), contentY); QCOMPARE(icon->width(), icon->implicitWidth()); QCOMPARE(icon->height(), icon->implicitHeight()); - QCOMPARE(icon->isVisible(), true); QCOMPARE(text->x(), horizontalCenter - text->width() / 2); QCOMPARE(text->y(), contentY + icon->height() + label->spacing()); QCOMPARE(text->width(), text->implicitWidth()); QCOMPARE(text->height(), text->implicitHeight()); - QCOMPARE(text->isVisible(), true); QCOMPARE(label->implicitWidth(), qMax(icon->implicitWidth(), text->implicitWidth()) + horizontalPadding); QCOMPARE(label->implicitHeight(), combinedHeight + verticalPadding); break; } case QQuickIconLabel::TextBesideIcon: default: + QVERIFY(icon); + QVERIFY(text); const qreal combinedWidth = icon->width() + label->spacing() + text->width(); const qreal contentX = horizontalCenter - combinedWidth / 2; QCOMPARE(icon->x(), contentX + (label->isMirrored() ? text->width() + label->spacing() : 0)); QCOMPARE(icon->y(), verticalCenter - icon->height() / 2); QCOMPARE(icon->width(), icon->implicitWidth()); QCOMPARE(icon->height(), icon->implicitHeight()); - QCOMPARE(icon->isVisible(), true); QCOMPARE(text->x(), contentX + (label->isMirrored() ? 0 : icon->width() + label->spacing())); QCOMPARE(text->y(), verticalCenter - text->height() / 2); QCOMPARE(text->width(), text->implicitWidth()); QCOMPARE(text->height(), text->implicitHeight()); - QCOMPARE(text->isVisible(), true); QCOMPARE(label->implicitWidth(), combinedWidth + horizontalPadding); QCOMPARE(label->implicitHeight(), qMax(icon->implicitHeight(), text->implicitHeight()) + verticalPadding); break; @@ -238,15 +237,15 @@ void tst_qquickiconlabel::spacingWithOneDelegate() QQuickItem *rootItem = view.rootObject(); QVERIFY(rootItem); - QQuickIconLabel *label = qobject_cast(rootItem->childItems().first()); + QQuickIconLabel *label = rootItem->findChild(); QVERIFY(label); QQuickItem *delegate = nullptr; if (label->icon()) { - QVERIFY(!label->label()); - delegate = label->icon(); + QVERIFY(!label->findChild()); + delegate = label->findChild(); } else { - QVERIFY(!label->icon()); - delegate = label->label(); + QVERIFY(!label->findChild()); + delegate = label->findChild(); } QVERIFY(delegate); @@ -264,16 +263,16 @@ void tst_qquickiconlabel::emptyIconSource() QQuickItem *rootItem = view.rootObject(); QVERIFY(rootItem); - QQuickIconLabel *label = qobject_cast(rootItem->childItems().first()); + QQuickIconLabel *label = rootItem->findChild(); QVERIFY(label); QCOMPARE(label->spacing(), 0.0); QCOMPARE(label->display(), QQuickIconLabel::TextBesideIcon); QCOMPARE(label->isMirrored(), false); - QQuickItem *icon = label->icon(); + QQuickItem *icon = label->findChild(); QVERIFY(icon); - QQuickItem *text = label->label(); + QQuickItem *text = label->findChild(); QVERIFY(text); qreal horizontalCenter = label->width() / 2; const qreal combinedWidth = icon->width() + text->width(); @@ -286,7 +285,8 @@ void tst_qquickiconlabel::emptyIconSource() label->setWidth(label->implicitWidth() + 200); label->setHeight(label->implicitWidth() + 100); QVERIFY(icon->property("source").isValid()); - QVERIFY(icon->setProperty("source", QUrl())); + label->icon()->setSource(QString()); + QVERIFY(!label->findChild()); horizontalCenter = label->width() / 2; QCOMPARE(text->x(), horizontalCenter - text->width() / 2); } -- cgit v1.2.3