Fix HiDPI rendering issues in the WindowsVista style

Fixing miscellaneous rendering issues to make the WindowsVista
style look good on High DPI displays:
- Fixed size/resolution of combo box arrows, and changed to native look.
- Fixed vanishing horizontal line in the frame of line edit widgets.
- Fixed gaps in combo box popup.
- Fixed size/resolution of arrow in push button menu.

Task-number: QTBUG-49374
Task-number: QTBUG-65237
Task-number: QTBUG-65238
Change-Id: If68c2fae7472def3c19636483af741ca8ed2c490
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
bb10
Andre de la Rocha 2017-12-01 16:36:58 +01:00
parent 0b2ebfd414
commit 5c60e4b8f9
2 changed files with 44 additions and 28 deletions

View File

@ -990,7 +990,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
TP_DROPDOWNBUTTON);
if (theme.isValid()) {
const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget);
const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1);
if (!size.isEmpty()) {
mbiw = qRound(size.width());
mbih = qRound(size.height());
@ -1513,7 +1513,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
if (d->transitionsEnabled() && canAnimate(option))
{
if (control == CC_ScrollBar || control == CC_SpinBox ) {
if (control == CC_ScrollBar || control == CC_SpinBox || control == CC_ComboBox) {
QObject *styleObject = option->styleObject; // Can be widget or qquickitem
@ -1643,12 +1643,28 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
} else {
if (sub & SC_ComboBoxFrame) {
QStyleOptionButton btn;
btn.QStyleOption::operator=(*option);
btn.rect = option->rect.adjusted(-1, -1, 1, 1);
if (sub & SC_ComboBoxArrow)
btn.features = QStyleOptionButton::HasMenu;
proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget);
XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme);
theme.rect = option->rect;
theme.partId = CP_READONLY;
if (!(cmb->state & State_Enabled))
theme.stateId = CBXS_DISABLED;
else if (cmb->state & State_Sunken || cmb->state & State_On)
theme.stateId = CBXS_PRESSED;
else if (cmb->state & State_MouseOver)
theme.stateId = CBXS_HOT;
else
theme.stateId = CBXS_NORMAL;
d->drawBackground(theme);
}
if (sub & SC_ComboBoxArrow) {
XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme);
theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
theme.partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
if (!(cmb->state & State_Enabled))
theme.stateId = CBXS_DISABLED;
else
theme.stateId = CBXS_NORMAL;
d->drawBackground(theme);
}
}
}
@ -2123,15 +2139,12 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
#if QT_CONFIG(combobox)
case CC_ComboBox:
if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
int x = cb->rect.x(),
y = cb->rect.y(),
wi = cb->rect.width(),
he = cb->rect.height();
int xpos = x;
int margin = cb->frame ? 3 : 0;
int bmarg = cb->frame ? 2 : 0;
int arrowButtonWidth = bmarg + 16;
xpos += wi - arrowButtonWidth;
const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height();
const int margin = cb->frame ? 3 : 0;
const int bmarg = cb->frame ? 2 : 0;
const int arrowWidth = qRound(QStyleHelper::dpiScaled(16));
const int arrowButtonWidth = bmarg + arrowWidth;
const int xpos = x + wi - arrowButtonWidth;
switch (subControl) {
case SC_ComboBoxFrame:
@ -2141,7 +2154,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
rect.setRect(xpos, y , arrowButtonWidth, he);
break;
case SC_ComboBoxEditField:
rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
rect.setRect(x + margin, y + margin, wi - 2 * margin - arrowWidth, he - 2 * margin);
break;
case SC_ComboBoxListBoxPopup:
rect = cb->rect;

View File

@ -887,6 +887,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
PROPERTYORIGIN origin = PO_NOTFOUND;
GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
GetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
borderSize *= additionalDevicePixelRatio;
// Clip away border region
if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
@ -996,7 +997,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
}
if (addBorderContentClipping)
painter->setClipRegion(extraClip, Qt::IntersectClip);
painter->setClipRegion(scaleRegion(extraClip, 1.0 / additionalDevicePixelRatio), Qt::IntersectClip);
if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
if (!haveCachedPixmap)
@ -1479,11 +1480,12 @@ case PE_Frame:
// GetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize);
// Inner white border
p->setPen(QPen(option->palette.base().color(), 1));
p->drawRect(option->rect.adjusted(1, 1, -2, -2));
p->setPen(QPen(option->palette.base().color(), 0));
p->drawRect(QRectF(option->rect).adjusted(QStyleHelper::dpiScaled(0.5), QStyleHelper::dpiScaled(0.5),
QStyleHelper::dpiScaled(-1), QStyleHelper::dpiScaled(-1)));
// Outer dark border
p->setPen(QPen(bordercolor, 1));
p->drawRect(option->rect.adjusted(0, 0, -1, -1));
p->setPen(QPen(bordercolor, 0));
p->drawRect(QRectF(option->rect).adjusted(0, 0, QStyleHelper::dpiScaled(-0.5), QStyleHelper::dpiScaled(-0.5)));
p->setPen(oldPen);
return;
} else if (fillType == BT_NONE) {
@ -3511,9 +3513,8 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl
case CC_ComboBox:
if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
int xpos = x;
xpos += wi - 1 - 16;
const int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16));
switch (subControl) {
case SC_ComboBoxFrame:
@ -3521,11 +3522,13 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl
break;
case SC_ComboBoxArrow:
rect = QRect(xpos, y+1, 16, he-2);
rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1)),
qRound(QStyleHelper::dpiScaled(16)), he - qRound(QStyleHelper::dpiScaled(2)));
break;
case SC_ComboBoxEditField:
rect = QRect(x+2, y+2, wi-3-16, he-4);
rect = QRect(x + qRound(QStyleHelper::dpiScaled(2)), y + qRound(QStyleHelper::dpiScaled(2)),
wi - qRound(QStyleHelper::dpiScaled(3 + 16)), he - qRound(QStyleHelper::dpiScaled(4)));
break;
case SC_ComboBoxListBoxPopup: