Add QQuickIconLabel::alignment

The contents of menu items and item delegates must be aligned to
the left in left-to-right UIs, or to the right in right-to-left UIs.

Change-Id: Ib4064f6a8162306d446189cadebb80e12d3cd35d
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
This commit is contained in:
J-P Nurmi 2017-04-10 14:54:37 +02:00
parent b7a95c2fd1
commit a6be134c9d
3 changed files with 76 additions and 29 deletions

View File

@ -37,6 +37,7 @@
#include "qquickiconlabel_p.h" #include "qquickiconlabel_p.h"
#include "qquickiconlabel_p_p.h" #include "qquickiconlabel_p_p.h"
#include <QtGui/private/qguiapplication_p.h>
#include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickitem_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -45,6 +46,7 @@ QQuickIconLabelPrivate::QQuickIconLabelPrivate()
: icon(nullptr), : icon(nullptr),
label(nullptr), label(nullptr),
display(QQuickIconLabel::TextBesideIcon), display(QQuickIconLabel::TextBesideIcon),
alignment(Qt::AlignCenter),
spacing(0), spacing(0),
mirrored(false), mirrored(false),
topPadding(0), topPadding(0),
@ -71,25 +73,42 @@ void QQuickIconLabelPrivate::updateImplicitSize()
q->setImplicitSize(implicitWidth, implicitHeight); q->setImplicitSize(implicitWidth, implicitHeight);
} }
// adapted from QStyle::alignedRect()
static QRectF alignedRect(bool mirrored, Qt::Alignment alignment, const QSizeF &size, const QRectF &rectangle)
{
alignment = QGuiApplicationPrivate::visualAlignment(mirrored ? Qt::RightToLeft : Qt::LeftToRight, alignment);
qreal x = rectangle.x();
qreal y = rectangle.y();
const qreal w = size.width();
const qreal h = size.height();
if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
y += rectangle.height() / 2 - h / 2;
else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
y += rectangle.height() - h;
if ((alignment & Qt::AlignRight) == Qt::AlignRight)
x += rectangle.width() - w;
else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
x += rectangle.width() / 2 - w / 2;
return QRectF(x, y, w, h);
}
void QQuickIconLabelPrivate::layout() void QQuickIconLabelPrivate::layout()
{ {
if (!componentComplete) if (!componentComplete)
return; return;
const qreal horizontalPadding = leftPadding + rightPadding; const qreal availableWidth = width - leftPadding - rightPadding;
const qreal verticalPadding = topPadding + bottomPadding; const qreal availableHeight = height - topPadding - bottomPadding;
const qreal availableWidth = width - horizontalPadding;
const qreal availableHeight = height - verticalPadding;
const qreal horizontalCenter = width / 2;
const qreal verticalCenter = height / 2;
switch (display) { switch (display) {
case QQuickIconLabel::IconOnly: case QQuickIconLabel::IconOnly:
if (icon) { if (icon) {
icon->setSize(QSizeF(qMin(icon->implicitWidth(), availableWidth), const QRectF iconRect = alignedRect(mirrored, alignment,
qMin(icon->implicitHeight(), availableHeight))); QSizeF(qMin(icon->implicitWidth(), availableWidth),
icon->setPosition(QPointF(horizontalCenter - icon->width() / 2, qMin(icon->implicitHeight(), availableHeight)),
verticalCenter - icon->height() / 2)); QRectF(leftPadding, topPadding, availableWidth, availableHeight));
icon->setSize(iconRect.size());
icon->setPosition(iconRect.topLeft());
icon->setVisible(true); icon->setVisible(true);
} }
if (label) if (label)
@ -97,10 +116,12 @@ void QQuickIconLabelPrivate::layout()
break; break;
case QQuickIconLabel::TextOnly: case QQuickIconLabel::TextOnly:
if (label) { if (label) {
label->setSize(QSizeF(qMin(label->implicitWidth(), availableWidth), const QRectF textRect = alignedRect(mirrored, alignment,
qMin(label->implicitHeight(), availableHeight))); QSizeF(qMin(label->implicitWidth(), availableWidth),
label->setPosition(QPointF(horizontalCenter - label->width() / 2, qMin(label->implicitHeight(), availableHeight)),
verticalCenter - label->height() / 2)); QRectF(leftPadding, topPadding, availableWidth, availableHeight));
label->setSize(textRect.size());
label->setPosition(textRect.topLeft());
label->setVisible(true); label->setVisible(true);
} }
if (icon) if (icon)
@ -109,32 +130,34 @@ void QQuickIconLabelPrivate::layout()
case QQuickIconLabel::TextBesideIcon: case QQuickIconLabel::TextBesideIcon:
default: default:
// Work out the sizes first, as the positions depend on them. // Work out the sizes first, as the positions depend on them.
qreal iconWidth = 0; QSizeF iconSize(0, 0);
qreal textWidth = 0; QSizeF textSize(0, 0);
if (icon) { if (icon) {
icon->setSize(QSizeF(qMin(icon->implicitWidth(), availableWidth), iconSize.setWidth(qMin(icon->implicitWidth(), availableWidth));
qMin(icon->implicitHeight(), availableHeight))); iconSize.setHeight(qMin(icon->implicitHeight(), availableHeight));
iconWidth = icon->width();
} }
qreal effectiveSpacing = 0; qreal effectiveSpacing = 0;
if (label) { if (label) {
if (iconWidth > 0) if (!iconSize.isEmpty())
effectiveSpacing = spacing; effectiveSpacing = spacing;
label->setSize(QSizeF(qMin(label->implicitWidth(), availableWidth - iconWidth - effectiveSpacing), textSize.setWidth(qMin(label->implicitWidth(), availableWidth - iconSize.width() - effectiveSpacing));
qMin(label->implicitHeight(), availableHeight))); textSize.setHeight(qMin(label->implicitHeight(), availableHeight));
textWidth = label->width();
} }
const qreal combinedWidth = iconWidth + effectiveSpacing + textWidth; const QRectF combinedRect = alignedRect(mirrored, alignment,
const qreal contentX = horizontalCenter - combinedWidth / 2; QSizeF(iconSize.width() + effectiveSpacing + textSize.width(),
qMax(iconSize.height(), textSize.height())),
QRectF(leftPadding, topPadding, availableWidth, availableHeight));
if (icon) { if (icon) {
icon->setPosition(QPointF(mirrored ? contentX + combinedWidth - iconWidth : contentX, const QRectF iconRect = alignedRect(mirrored, Qt::AlignLeft | Qt::AlignVCenter, iconSize, combinedRect);
verticalCenter - icon->height() / 2)); icon->setSize(iconRect.size());
icon->setPosition(iconRect.topLeft());
icon->setVisible(true); icon->setVisible(true);
} }
if (label) { if (label) {
label->setPosition(QPointF(mirrored ? contentX : contentX + combinedWidth - label->width(), const QRectF textRect = alignedRect(mirrored, Qt::AlignRight | Qt::AlignVCenter, textSize, combinedRect);
verticalCenter - label->height() / 2)); label->setSize(textRect.size());
label->setPosition(textRect.topLeft());
label->setVisible(true); label->setVisible(true);
} }
break; break;
@ -294,6 +317,25 @@ void QQuickIconLabel::setMirrored(bool mirrored)
d->layout(); d->layout();
} }
Qt::Alignment QQuickIconLabel::alignment() const
{
Q_D(const QQuickIconLabel);
return d->alignment;
}
void QQuickIconLabel::setAlignment(Qt::Alignment alignment)
{
Q_D(QQuickIconLabel);
const int valign = alignment & Qt::AlignVertical_Mask;
const int halign = alignment & Qt::AlignHorizontal_Mask;
const uint align = (valign ? valign : Qt::AlignVCenter) | (halign ? halign : Qt::AlignHCenter);
if (d->alignment == align)
return;
d->alignment = static_cast<Qt::Alignment>(align);
d->layout();
}
qreal QQuickIconLabel::topPadding() const qreal QQuickIconLabel::topPadding() const
{ {
Q_D(const QQuickIconLabel); Q_D(const QQuickIconLabel);

View File

@ -63,6 +63,7 @@ class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickIconLabel : public QQuickItem
Q_PROPERTY(Display display READ display WRITE setDisplay FINAL) Q_PROPERTY(Display display READ display WRITE setDisplay FINAL)
Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing FINAL) Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing FINAL)
Q_PROPERTY(bool mirrored READ isMirrored WRITE setMirrored FINAL) Q_PROPERTY(bool mirrored READ isMirrored WRITE setMirrored FINAL)
Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment FINAL)
Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding FINAL) Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding FINAL)
Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding FINAL) Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding FINAL)
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding FINAL) Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding FINAL)
@ -95,6 +96,9 @@ public:
bool isMirrored() const; bool isMirrored() const;
void setMirrored(bool mirrored); void setMirrored(bool mirrored);
Qt::Alignment alignment() const;
void setAlignment(Qt::Alignment alignment);
qreal topPadding() const; qreal topPadding() const;
void setTopPadding(qreal padding); void setTopPadding(qreal padding);
void resetTopPadding(); void resetTopPadding();

View File

@ -77,6 +77,7 @@ public:
QQuickItem *icon; QQuickItem *icon;
QQuickItem *label; QQuickItem *label;
QQuickIconLabel::Display display; QQuickIconLabel::Display display;
Qt::Alignment alignment;
qreal spacing; qreal spacing;
bool mirrored; bool mirrored;
qreal topPadding; qreal topPadding;