Fusion: draw DPI-scaled arrows
Replace the "hard-coded" fusion_arrow.png with qt_fusion_draw_arrow() that scales appropriately on high DPI screens. Task-number: QTBUG-40277 Change-Id: I2c4a134de757a39d7744977bd41accff69810521 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
edcc71be87
commit
63d08003cf
Binary file not shown.
Before Width: | Height: | Size: 295 B |
@ -190,55 +190,6 @@ static QColor mergedColors(const QColor &colorA, const QColor &colorB, int facto
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static QPixmap colorizedImage(const QString &fileName, const QColor &color, int rotation = 0) {
|
||||
|
||||
QString pixmapName = QLatin1String("$qt_ia-") % fileName % HexString<uint>(color.rgba()) % QString::number(rotation);
|
||||
QPixmap pixmap;
|
||||
if (!QPixmapCache::find(pixmapName, pixmap)) {
|
||||
QImage image(fileName);
|
||||
|
||||
if (image.format() != QImage::Format_ARGB32_Premultiplied)
|
||||
image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
int width = image.width();
|
||||
int height = image.height();
|
||||
int source = color.rgba();
|
||||
|
||||
unsigned char sourceRed = qRed(source);
|
||||
unsigned char sourceGreen = qGreen(source);
|
||||
unsigned char sourceBlue = qBlue(source);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
QRgb *data = (QRgb*) image.scanLine(y);
|
||||
for (int x = 0 ; x < width ; x++) {
|
||||
QRgb col = data[x];
|
||||
unsigned int colorDiff = (qBlue(col) - qRed(col));
|
||||
unsigned char gray = qGreen(col);
|
||||
unsigned char red = gray + qt_div_255(sourceRed * colorDiff);
|
||||
unsigned char green = gray + qt_div_255(sourceGreen * colorDiff);
|
||||
unsigned char blue = gray + qt_div_255(sourceBlue * colorDiff);
|
||||
unsigned char alpha = qt_div_255(qAlpha(col) * qAlpha(source));
|
||||
data[x] = qRgba(std::min(alpha, red),
|
||||
std::min(alpha, green),
|
||||
std::min(alpha, blue),
|
||||
alpha);
|
||||
}
|
||||
}
|
||||
if (rotation != 0) {
|
||||
QTransform transform;
|
||||
transform.translate(-image.width()/2, -image.height()/2);
|
||||
transform.rotate(rotation);
|
||||
transform.translate(image.width()/2, image.height()/2);
|
||||
image = image.transformed(transform);
|
||||
}
|
||||
|
||||
pixmap = QPixmap::fromImage(image);
|
||||
QPixmapCache::insert(pixmapName, pixmap);
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
// The default button and handle gradient
|
||||
static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown)
|
||||
{
|
||||
@ -276,6 +227,59 @@ static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseC
|
||||
return gradient;
|
||||
}
|
||||
|
||||
static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QStyleOption *option, const QRect &rect, const QColor &color)
|
||||
{
|
||||
const int arrowWidth = QStyleHelper::dpiScaled(14);
|
||||
const int arrowHeight = QStyleHelper::dpiScaled(8);
|
||||
|
||||
const int arrowMax = qMin(arrowHeight, arrowWidth);
|
||||
const int rectMax = qMin(rect.height(), rect.width());
|
||||
const int size = qMin(arrowMax, rectMax);
|
||||
|
||||
QPixmap cachePixmap;
|
||||
QString cacheKey = QStyleHelper::uniqueName(QLatin1String("fusion-arrow"), option, rect.size())
|
||||
% HexString<uint>(type)
|
||||
% HexString<uint>(color.rgba());
|
||||
if (!QPixmapCache::find(cacheKey, cachePixmap)) {
|
||||
cachePixmap = styleCachePixmap(rect.size());
|
||||
cachePixmap.fill(Qt::transparent);
|
||||
QPainter cachePainter(&cachePixmap);
|
||||
|
||||
QRectF arrowRect;
|
||||
arrowRect.setWidth(size);
|
||||
arrowRect.setHeight(arrowHeight * size / arrowWidth);
|
||||
if (type == Qt::LeftArrow || type == Qt::RightArrow)
|
||||
arrowRect = arrowRect.transposed();
|
||||
arrowRect.moveTo((rect.width() - arrowRect.width()) / 2.0,
|
||||
(rect.height() - arrowRect.height()) / 2.0);
|
||||
|
||||
QPolygonF triangle;
|
||||
triangle.reserve(3);
|
||||
switch (type) {
|
||||
case Qt::DownArrow:
|
||||
triangle << arrowRect.topLeft() << arrowRect.topRight() << QPointF(arrowRect.center().x(), arrowRect.bottom());
|
||||
break;
|
||||
case Qt::RightArrow:
|
||||
triangle << arrowRect.topLeft() << arrowRect.bottomLeft() << QPointF(arrowRect.right(), arrowRect.center().y());
|
||||
break;
|
||||
case Qt::LeftArrow:
|
||||
triangle << arrowRect.topRight() << arrowRect.bottomRight() << QPointF(arrowRect.left(), arrowRect.center().y());
|
||||
break;
|
||||
default:
|
||||
triangle << arrowRect.bottomLeft() << arrowRect.bottomRight() << QPointF(arrowRect.center().x(), arrowRect.top());
|
||||
break;
|
||||
}
|
||||
|
||||
cachePainter.setPen(Qt::NoPen);
|
||||
cachePainter.setBrush(color);
|
||||
cachePainter.setRenderHint(QPainter::Antialiasing);
|
||||
cachePainter.drawPolygon(triangle);
|
||||
|
||||
QPixmapCache::insert(cacheKey, cachePixmap);
|
||||
}
|
||||
|
||||
painter->drawPixmap(rect, cachePixmap);
|
||||
}
|
||||
|
||||
static void qt_fusion_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
|
||||
{
|
||||
@ -513,43 +517,22 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
|
||||
if (option->rect.width() <= 1 || option->rect.height() <= 1)
|
||||
break;
|
||||
QColor arrowColor = option->palette.foreground().color();
|
||||
QPixmap arrow;
|
||||
int rotation = 0;
|
||||
arrowColor.setAlpha(160);
|
||||
Qt::ArrowType arrow = Qt::UpArrow;
|
||||
switch (elem) {
|
||||
case PE_IndicatorArrowDown:
|
||||
rotation = 180;
|
||||
arrow = Qt::DownArrow;
|
||||
break;
|
||||
case PE_IndicatorArrowRight:
|
||||
rotation = 90;
|
||||
arrow = Qt::RightArrow;
|
||||
break;
|
||||
case PE_IndicatorArrowLeft:
|
||||
rotation = -90;
|
||||
arrow = Qt::LeftArrow;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation);
|
||||
if (arrow.isNull())
|
||||
break;
|
||||
|
||||
QRect rect = option->rect;
|
||||
QRect arrowRect;
|
||||
int imageMax = qMin(arrow.height(), arrow.width());
|
||||
int rectMax = qMin(rect.height(), rect.width());
|
||||
int size = qMin(imageMax, rectMax);
|
||||
|
||||
arrowRect.setWidth(size);
|
||||
arrowRect.setHeight(size);
|
||||
if (arrow.width() > arrow.height())
|
||||
arrowRect.setHeight(arrow.height() * size / arrow.width());
|
||||
else
|
||||
arrowRect.setWidth(arrow.width() * size / arrow.height());
|
||||
|
||||
arrowRect.moveTopLeft(rect.center() - arrowRect.center());
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->drawPixmap(arrowRect, arrow);
|
||||
painter->restore();
|
||||
qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor);
|
||||
}
|
||||
break;
|
||||
case PE_IndicatorViewItemCheck:
|
||||
@ -563,29 +546,23 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
|
||||
case PE_IndicatorHeaderArrow:
|
||||
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
|
||||
QRect r = header->rect;
|
||||
QPixmap arrow;
|
||||
QColor arrowColor = header->palette.foreground().color();
|
||||
QPoint offset = QPoint(0, -1);
|
||||
arrowColor.setAlpha(180);
|
||||
QPoint offset = QPoint(0, -2);
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
if (header->sortIndicator & QStyleOptionHeader::SortUp) {
|
||||
arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor);
|
||||
qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
|
||||
} else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
|
||||
arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180);
|
||||
qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
|
||||
}
|
||||
#else
|
||||
if (header->sortIndicator & QStyleOptionHeader::SortUp) {
|
||||
arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180);
|
||||
qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
|
||||
} else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
|
||||
arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor);
|
||||
qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!arrow.isNull()) {
|
||||
r.setSize(QSize(arrow.width()/2, arrow.height()/2));
|
||||
r.moveCenter(header->rect.center());
|
||||
painter->drawPixmap(r.translated(offset), arrow);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PE_IndicatorButtonDropDown:
|
||||
@ -2039,7 +2016,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
QRect r = rect.adjusted(0, 1, 0, -1);
|
||||
QPainter cachePainter(&cache);
|
||||
QColor arrowColor = spinBox->palette.foreground().color();
|
||||
arrowColor.setAlpha(220);
|
||||
arrowColor.setAlpha(160);
|
||||
|
||||
bool isEnabled = (spinBox->state & State_Enabled);
|
||||
bool hover = isEnabled && (spinBox->state & State_MouseOver);
|
||||
@ -2150,23 +2127,10 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
|
||||
} else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows){
|
||||
// arrows
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
QPixmap upArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"),
|
||||
(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
|
||||
|
||||
QRectF upArrowRect = QRectF(upRect.center().x() - upArrow.width() / 4.0 + 1.0,
|
||||
upRect.center().y() - upArrow.height() / 4.0 + 1.0,
|
||||
upArrow.width() / 2.0, upArrow.height() / 2.0);
|
||||
|
||||
cachePainter.drawPixmap(upArrowRect, upArrow, QRectF(QPointF(0.0, 0.0), upArrow.size()));
|
||||
|
||||
QPixmap downArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"),
|
||||
(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor, 180);
|
||||
QRectF downArrowRect = QRectF(downRect.center().x() - downArrow.width() / 4.0 + 1.0,
|
||||
downRect.center().y() - downArrow.height() / 4.0 + 1.0,
|
||||
downArrow.width() / 2.0, downArrow.height() / 2.0);
|
||||
cachePainter.drawPixmap(downArrowRect, downArrow, QRectF(QPointF(0.0, 0.0), downArrow.size()));
|
||||
qt_fusion_draw_arrow(Qt::UpArrow, &cachePainter, option, upRect.adjusted(0, 0, 0, 1),
|
||||
(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
|
||||
qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downRect,
|
||||
(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor);
|
||||
}
|
||||
|
||||
cachePainter.end();
|
||||
@ -2403,8 +2367,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver);
|
||||
bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken);
|
||||
qt_fusion_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken);
|
||||
QPixmap arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), textColor);
|
||||
painter->drawPixmap(shadeButtonRect.adjusted(5, 7, -5, -7), arrow);
|
||||
qt_fusion_draw_arrow(Qt::UpArrow, painter, option, shadeButtonRect.adjusted(5, 7, -5, -7), textColor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2415,8 +2378,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver);
|
||||
bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken);
|
||||
qt_fusion_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken);
|
||||
QPixmap arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), textColor, 180);
|
||||
painter->drawPixmap(unshadeButtonRect.adjusted(5, 7, -5, -7), arrow);
|
||||
qt_fusion_draw_arrow(Qt::DownArrow, painter, option, unshadeButtonRect.adjusted(5, 7, -5, -7), textColor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2544,7 +2506,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
alphaOutline.setAlpha(180);
|
||||
|
||||
QColor arrowColor = option->palette.foreground().color();
|
||||
arrowColor.setAlpha(220);
|
||||
arrowColor.setAlpha(160);
|
||||
|
||||
const QColor bgColor = QStyleHelper::backgroundColor(option->palette, widget);
|
||||
const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
|
||||
@ -2688,20 +2650,16 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
painter->drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
|
||||
}
|
||||
|
||||
QRect upRect = scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, horizontal ? -2 : -1, horizontal ? -1 : -2);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->setPen(d->innerContrastLine());
|
||||
painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0 , horizontal ? -2 : -1, horizontal ? -1 : -2));
|
||||
painter->drawRect(upRect);
|
||||
|
||||
// Arrows
|
||||
int rotation = 0;
|
||||
Qt::ArrowType arrowType = Qt::UpArrow;
|
||||
if (option->state & State_Horizontal)
|
||||
rotation = option->direction == Qt::LeftToRight ? -90 : 90;
|
||||
QRect upRect = scrollBarSubLine.translated(horizontal ? -2 : -1, 0);
|
||||
QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation);
|
||||
painter->drawPixmap(QRectF(upRect.center().x() - arrowPixmap.width() / 4.0 + 2.0,
|
||||
upRect.center().y() - arrowPixmap.height() / 4.0 + 1.0,
|
||||
arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0),
|
||||
arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size()));
|
||||
arrowType = option->direction == Qt::LeftToRight ? Qt::LeftArrow : Qt::RightArrow;
|
||||
qt_fusion_draw_arrow(arrowType, painter, option, upRect, arrowColor);
|
||||
}
|
||||
|
||||
// The AddLine (down/right) button
|
||||
@ -2729,19 +2687,15 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
painter->drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
|
||||
}
|
||||
|
||||
QRect downRect = scrollBarAddLine.adjusted(1, 1, -1, -1);
|
||||
painter->setPen(d->innerContrastLine());
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRect(scrollBarAddLine.adjusted(1, 1, -1, -1));
|
||||
painter->drawRect(downRect);
|
||||
|
||||
int rotation = 180;
|
||||
Qt::ArrowType arrowType = Qt::DownArrow;
|
||||
if (option->state & State_Horizontal)
|
||||
rotation = option->direction == Qt::LeftToRight ? 90 : -90;
|
||||
QRect downRect = scrollBarAddLine.translated(-1, 1);
|
||||
QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation);
|
||||
painter->drawPixmap(QRectF(downRect.center().x() - arrowPixmap.width() / 4.0 + 2.0,
|
||||
downRect.center().y() - arrowPixmap.height() / 4.0,
|
||||
arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0),
|
||||
arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size()));
|
||||
arrowType = option->direction == Qt::LeftToRight ? Qt::RightArrow : Qt::LeftArrow;
|
||||
qt_fusion_draw_arrow(arrowType, painter, option, downRect, arrowColor);
|
||||
}
|
||||
|
||||
}
|
||||
@ -2831,12 +2785,8 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
|
||||
if (comboBox->subControls & SC_ComboBoxArrow) {
|
||||
// Draw the up/down arrow
|
||||
QColor arrowColor = option->palette.buttonText().color();
|
||||
arrowColor.setAlpha(220);
|
||||
QPixmap downArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180);
|
||||
cachePainter.drawPixmap(QRectF(downArrowRect.center().x() - downArrow.width() / 4.0 + 1.0,
|
||||
downArrowRect.center().y() - downArrow.height() / 4.0 + 1.0,
|
||||
downArrow.width() / 2.0, downArrow.height() / 2.0),
|
||||
downArrow, QRectF(QPointF(0.0, 0.0), downArrow.size()));
|
||||
arrowColor.setAlpha(160);
|
||||
qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downArrowRect, arrowColor);
|
||||
}
|
||||
cachePainter.end();
|
||||
QPixmapCache::insert(pixmapName, cache);
|
||||
@ -3528,8 +3478,8 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom
|
||||
switch (subControl) {
|
||||
case SC_ComboBoxArrow:
|
||||
rect = visualRect(option->direction, option->rect, rect);
|
||||
rect.setRect(rect.right() - 18, rect.top() - 2,
|
||||
19, rect.height() + 4);
|
||||
rect.setRect(rect.right() - QStyleHelper::dpiScaled(18), rect.top() - 2,
|
||||
QStyleHelper::dpiScaled(19), rect.height() + 4);
|
||||
rect = visualRect(option->direction, option->rect, rect);
|
||||
break;
|
||||
case SC_ComboBoxEditField: {
|
||||
|
@ -128,7 +128,6 @@
|
||||
<file>images/media-volume-16.png</file>
|
||||
<file>images/media-volume-muted-16.png</file>
|
||||
<file>images/fusion_groupbox.png</file>
|
||||
<file>images/fusion_arrow.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qt-project.org/styles/macstyle">
|
||||
<file>images/closedock-16.png</file>
|
||||
|
Loading…
Reference in New Issue
Block a user