aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-04-11 16:42:12 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-04-11 18:33:32 +0000
commit53a101f35b76ccea0e8a6bd00055259811df41d1 (patch)
treea757b336e9c63ec0d4e8a79c06341c7c33451806
parent4503d45b93721e516e949419f3b9c6b796a7c13e (diff)
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 <jpnurmi@qt.io>
-rw-r--r--src/imports/controls/Button.qml22
-rw-r--r--src/imports/controls/ToolButton.qml17
-rw-r--r--src/imports/controls/material/Button.qml21
-rw-r--r--src/imports/controls/material/ToolButton.qml19
-rw-r--r--src/imports/controls/universal/Button.qml18
-rw-r--r--src/imports/controls/universal/ToolButton.qml18
-rw-r--r--src/quickcontrols2/qquickiconlabel.cpp295
-rw-r--r--src/quickcontrols2/qquickiconlabel_p.h21
-rw-r--r--src/quickcontrols2/qquickiconlabel_p_p.h30
-rw-r--r--tests/auto/controls/data/tst_button.qml47
-rw-r--r--tests/auto/controls/data/tst_toolbutton.qml38
-rw-r--r--tests/auto/qquickiconlabel/data/iconlabel.qml13
-rw-r--r--tests/auto/qquickiconlabel/data/spacingWithOnlyIcon.qml9
-rw-r--r--tests/auto/qquickiconlabel/data/spacingWithOnlyText.qml5
-rw-r--r--tests/auto/qquickiconlabel/tst_qquickiconlabel.cpp50
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 <QtGui/private/qguiapplication_p.h>
#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquicktext_p.h>
+#include <QtQuickTemplates2/private/qquickicon_p.h>
QT_BEGIN_NAMESPACE
+static void beginClass(QQuickItem *item)
+{
+ if (QQmlParserStatus *parserStatus = qobject_cast<QQmlParserStatus *>(item))
+ parserStatus->classBegin();
+}
+
+static void completeComponent(QQuickItem *item)
+{
+ if (QQmlParserStatus *parserStatus = qobject_cast<QQmlParserStatus *>(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 <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
-
+#include <QtQuick/private/qquicktext_p.h>
+#include <QtQuickTemplates2/private/qquickicon_p.h>
+#include <QtQuickControls2/private/qquickiconimage_p.h>
#include <QtQuickControls2/private/qquickiconlabel_p.h>
#include "../shared/util.h"
@@ -118,7 +120,7 @@ void tst_qquickiconlabel::display()
QQuickItem *rootItem = view.rootObject();
QVERIFY(rootItem);
- QQuickIconLabel *label = qobject_cast<QQuickIconLabel*>(rootItem->childItems().first());
+ QQuickIconLabel *label = rootItem->findChild<QQuickIconLabel *>();
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<QQuickIconImage *>();
+ QQuickText *text = label->findChild<QQuickText *>();
+
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<QQuickIconLabel*>(rootItem->childItems().first());
+ QQuickIconLabel *label = rootItem->findChild<QQuickIconLabel *>();
QVERIFY(label);
QQuickItem *delegate = nullptr;
if (label->icon()) {
- QVERIFY(!label->label());
- delegate = label->icon();
+ QVERIFY(!label->findChild<QQuickText *>());
+ delegate = label->findChild<QQuickIconImage *>();
} else {
- QVERIFY(!label->icon());
- delegate = label->label();
+ QVERIFY(!label->findChild<QQuickIconImage *>());
+ delegate = label->findChild<QQuickText *>();
}
QVERIFY(delegate);
@@ -264,16 +263,16 @@ void tst_qquickiconlabel::emptyIconSource()
QQuickItem *rootItem = view.rootObject();
QVERIFY(rootItem);
- QQuickIconLabel *label = qobject_cast<QQuickIconLabel*>(rootItem->childItems().first());
+ QQuickIconLabel *label = rootItem->findChild<QQuickIconLabel *>();
QVERIFY(label);
QCOMPARE(label->spacing(), 0.0);
QCOMPARE(label->display(), QQuickIconLabel::TextBesideIcon);
QCOMPARE(label->isMirrored(), false);
- QQuickItem *icon = label->icon();
+ QQuickItem *icon = label->findChild<QQuickIconImage *>();
QVERIFY(icon);
- QQuickItem *text = label->label();
+ QQuickItem *text = label->findChild<QQuickText *>();
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<QQuickIconImage *>());
horizontalCenter = label->width() / 2;
QCOMPARE(text->x(), horizontalCenter - text->width() / 2);
}