QFusionStyle: fix the checkbox rendering in low DPI settings

Fixed some regression of checkbox's size brought in by c9f68a5.

Using qreal and QRectF to avoid the round error accumulation
of sizes in low dpi situations.

Tweaked the look of the check mark.

Task-number: QTBUG-66343
Change-Id: I8f68144f60437907701021bb43ee736dfcb7241f
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Yulong Bai 2018-02-13 16:33:32 +01:00
parent 2a80c04d3b
commit ea21b36836

View File

@ -763,7 +763,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->drawRect(rect);
QColor checkMarkColor = option->palette.text().color().darker(120);
const int checkMarkPadding = 1 + rect.width() * 0.2; // at least one pixel padding
const qreal checkMarkPadding = 1 + rect.width() * 0.13; // at least one pixel padding
if (checkbox->state & State_NoChange) {
gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft());
@ -775,20 +775,23 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->setPen(QPen(checkMarkColor, 1));
painter->setBrush(gradient);
painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding));
} else if (checkbox->state & State_On) {
qreal penWidth = QStyleHelper::dpiScaled(1.8);
penWidth = qMax(penWidth , 0.18 * rect.height());
penWidth = qMin(penWidth , 0.30 * rect.height());
qreal penWidth = QStyleHelper::dpiScaled(1.5);
penWidth = qMax(penWidth , 0.13 * rect.height());
penWidth = qMin(penWidth , 0.20 * rect.height());
QPen checkPen = QPen(checkMarkColor, penWidth);
checkMarkColor.setAlpha(210);
painter->setPen(QPen(checkMarkColor, penWidth));
painter->translate(dpiScaled(-0.8), dpiScaled(0.5));
painter->setPen(checkPen);
painter->setBrush(Qt::NoBrush);
painter->translate(-0.8, 0.5);
// Draw checkmark
QPainterPath path;
path.moveTo(1.33 * checkMarkPadding, rect.height() / 2.0);
path.lineTo(rect.width() / 2.0, rect.height() - checkMarkPadding);
path.lineTo(rect.width() - checkMarkPadding * 0.92, checkMarkPadding);
const qreal rectHeight = rect.height(); // assuming height equals width
path.moveTo(checkMarkPadding + rectHeight * 0.11, rectHeight * 0.47);
path.lineTo(rectHeight * 0.5, rectHeight - checkMarkPadding);
path.lineTo(rectHeight - checkMarkPadding, checkMarkPadding);
painter->drawPath(path.translated(rect.topLeft()));
}
}
@ -1559,8 +1562,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
bool ignoreCheckMark = false;
const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
int checkcol = qMax(menuItem->rect.height() * 0.7,
qMax(menuItem->maxIconWidth * 1.0, dpiScaled(17))); // icon checkbox's highlihgt column width
int checkcol = qMax(menuItem->rect.height() * 0.79,
qMax(menuItem->maxIconWidth * 1.0, dpiScaled(21))); // icon checkbox's highlihgt column width
if (
#if QT_CONFIG(combobox)
qobject_cast<const QComboBox*>(widget) ||
@ -1569,10 +1572,12 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
if (!ignoreCheckMark) {
// Check
const int boxMargin = dpiScaled(4);
const int boxWidth = checkcol - 2 * boxMargin;
QRect checkRect(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
// Check, using qreal and QRectF to avoid error accumulation
const qreal boxMargin = dpiScaled(3.5);
const qreal boxWidth = checkcol - 2 * boxMargin;
QRectF checkRectF(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
QRect checkRect = checkRectF.toRect();
checkRect.setWidth(checkRect.height()); // avoid .toRect() round error results in non-perfect square
checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
if (checkable) {
if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {