QMacStyle: Fix inactive combo box appearance in 10.10

As usual, HITheme is not helping, and renders inactive controls
as disabled. Also, given the design changes in Yosemite, we can't
just desaturate the active pixmap and render it. In this case, we
render the inactive control and enhance it, making very close to
the expected result. The pixel-exact version would be to render
a plain push button, and then add the combo box arrows. However,
these arrows would need to be created (and updated) since there
seems to be no more API to render them.

Task-number: QTBUG-40833
Change-Id: If1bc366c0bc83123972fabebbc8beeb9f071e7a1
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
Gabriel de Dietrich 2014-08-27 19:23:23 +02:00
parent 2113bdee5d
commit 0c9ae66082

View File

@ -1335,7 +1335,7 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem
bdi->adornment = kThemeAdornmentFocus; bdi->adornment = kThemeAdornmentFocus;
if (combo->activeSubControls & QStyle::SC_ComboBoxArrow) if (combo->activeSubControls & QStyle::SC_ComboBoxArrow)
bdi->state = kThemeStatePressed; bdi->state = kThemeStatePressed;
else if (tds == kThemeStateInactive) else if (tds == kThemeStateInactive && QSysInfo::MacintoshVersion <= QSysInfo::MV_10_9)
bdi->state = kThemeStateActive; bdi->state = kThemeStateActive;
else else
bdi->state = tds; bdi->state = tds;
@ -1744,6 +1744,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
const bool combo = opt->type == QStyleOption::SO_ComboBox; const bool combo = opt->type == QStyleOption::SO_ComboBox;
const bool button = opt->type == QStyleOption::SO_Button; const bool button = opt->type == QStyleOption::SO_Button;
const bool pressed = bdi->state == kThemeStatePressed; const bool pressed = bdi->state == kThemeStatePressed;
const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9;
if (button && pressed) { if (button && pressed) {
if (bdi->kind == kThemePushButton) { if (bdi->kind == kThemePushButton) {
@ -1788,7 +1789,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
if (!combo && !button && bdi->value == kThemeButtonOff) { if (!combo && !button && bdi->value == kThemeButtonOff) {
pm = activePixmap; pm = activePixmap;
} else if (combo || button) { } else if ((combo && !usingYosemiteOrLater) || button) {
QImage image = activePixmap.toImage(); QImage image = activePixmap.toImage();
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
@ -1815,6 +1816,30 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
} }
} }
pm = QPixmap::fromImage(image); pm = QPixmap::fromImage(image);
} else if (combo && usingYosemiteOrLater) {
QImage image = activePixmap.toImage();
for (int y = 0; y < height; ++y) {
QRgb *scanLine = reinterpret_cast<QRgb *>(image.scanLine(y));
for (int x = 0; x < width; ++x) {
QRgb &pixel = scanLine[x];
int gray = qRed(pixel); // We know the image is grayscale
int alpha = qAlpha(pixel);
if (gray == 128 && alpha == 128) {
pixel = qRgba(255, 255, 255, 255);
} else if (alpha == 0) {
pixel = 0;
} else {
bool belowThreshold = (alpha * gray) / 255 + 255 - alpha < 128;
gray = belowThreshold ? 0 : 2 * gray - 255;
alpha = belowThreshold ? 0 : 2 * alpha - 255;
pixel = qRgba(gray, gray, gray, alpha);
}
}
}
pm = QPixmap::fromImage(image);
} else { } else {
QImage activeImage = activePixmap.toImage(); QImage activeImage = activePixmap.toImage();
QImage colorlessImage; QImage colorlessImage;