QPushButton: fix icon + text layouting in RTL mode

The fusion style did not properly handle the text layouting for a
QPushButton in RTL mode. Also the menu indicator was not adjusted in
this case.
Fix it by calling the base class implementation as QCommonStyle does it
mostly right. Since Fusion does not handle State_On or State_Sunken but
QCommonStyle does, explicitly mask them out.

Fixes: QTBUG-80083
Change-Id: Ide7bf997b4f4a5b61fcb8ea4a1a152122daef1e2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
bb10
Christian Ehrlicher 2019-11-27 19:51:11 +01:00
parent 485e4a8f0b
commit 46d21a3b34
2 changed files with 15 additions and 64 deletions

View File

@ -1363,7 +1363,6 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
if (!button->icon.isNull()) {
//Center both icon and text
QRect iconRect;
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
if (mode == QIcon::Normal && button->state & State_HasFocus)
mode = QIcon::Active;
@ -1372,28 +1371,29 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
state = QIcon::On;
QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state);
int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
int labelWidth = pixmapWidth;
int labelHeight = pixmapHeight;
int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
if (!button->text.isEmpty())
if (!button->text.isEmpty()) {
int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
labelWidth += (textWidth + iconSpacing);
}
iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
textRect.y() + (textRect.height() - labelHeight) / 2,
pixmapWidth, pixmapHeight);
QRect iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
textRect.y() + (textRect.height() - labelHeight) / 2,
pixmapWidth, pixmapHeight);
iconRect = visualRect(button->direction, textRect, iconRect);
tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
if (button->direction == Qt::RightToLeft)
if (button->direction == Qt::RightToLeft) {
tf |= Qt::AlignRight;
textRect.setRight(iconRect.left() - iconSpacing);
else
} else {
tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
}
if (button->state & (State_On | State_Sunken))
iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),

View File

@ -1770,59 +1770,10 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
break;
case CE_PushButtonLabel:
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
QRect ir = button->rect;
uint tf = Qt::AlignVCenter;
if (styleHint(SH_UnderlineShortcut, button, widget))
tf |= Qt::TextShowMnemonic;
else
tf |= Qt::TextHideMnemonic;
if (!button->icon.isNull()) {
//Center both icon and text
QPoint point;
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal
: QIcon::Disabled;
if (mode == QIcon::Normal && button->state & State_HasFocus)
mode = QIcon::Active;
QIcon::State state = QIcon::Off;
if (button->state & State_On)
state = QIcon::On;
QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state);
int w = pixmap.width() / pixmap.devicePixelRatio();
int h = pixmap.height() / pixmap.devicePixelRatio();
if (!button->text.isEmpty())
w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 2;
point = QPoint(ir.x() + ir.width() / 2 - w / 2,
ir.y() + ir.height() / 2 - h / 2);
w = pixmap.width() / pixmap.devicePixelRatio();
if (button->direction == Qt::RightToLeft)
point.rx() += w;
painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap);
if (button->direction == Qt::RightToLeft)
ir.translate(-point.x() - 2, 0);
else
ir.translate(point.x() + w, 0);
// left-align text if there is
if (!button->text.isEmpty())
tf |= Qt::AlignLeft;
} else {
tf |= Qt::AlignHCenter;
}
if (button->features & QStyleOptionButton::HasMenu)
ir = ir.adjusted(0, 0, -proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
proxy()->drawItemText(painter, ir, tf, button->palette, (button->state & State_Enabled),
button->text, QPalette::ButtonText);
QStyleOptionButton b(*button);
// no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
b.state &= ~(State_On | State_Sunken);
QCommonStyle::drawControl(element, &b, painter, widget);
}
break;
case CE_MenuBarEmptyArea: