Theme: Implement QIcon::On state for new themes

The spec for the new themes defines that pressed toolbar and mode
buttons have a stronger color. Defined is the change from
Token_Text_Muted to Token_Text_Default.

Themes which define another color than Token_Text_Muted for icons (it is
the case for all other existing themes), are not affected by all of
this.

This change leads Utils::Icon to create an QIcon::On version of icons
using the above mentioned color change. The actual painting of the new
QIcon::On state is also implemeted for FancyToolBar and in
ManhattanStyle.

Fixes: QTCREATORBUG-31826
Change-Id: Ib57f1cbc14839cba6303220128f589883c990b9e
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Alessandro Portale
2024-10-15 12:31:09 +02:00
parent 9669ff4537
commit 538d9f3c3e
9 changed files with 62 additions and 18 deletions

View File

@@ -146,6 +146,25 @@ Icon::Icon(const FilePath &imageFileName)
{
}
using OptMasksAndColors = std::optional<MasksAndColors>;
OptMasksAndColors highlightMasksAndColors(const MasksAndColors &defaultState,
const QList<IconMaskAndColor> &masks)
{
MasksAndColors highlighted = defaultState;
bool colorsReplaced = false;
int index = 0;
for (const IconMaskAndColor &mask : masks) {
const Theme::Color highlight = Theme::highlightFor(mask.second);
if (highlight != mask.second) {
highlighted[index].second = creatorColor(highlight);
colorsReplaced = true;
continue;
}
++index;
}
return colorsReplaced ? std::make_optional(highlighted) : std::nullopt;
}
QIcon Icon::icon() const
{
if (m_iconSourceList.isEmpty())
@@ -163,10 +182,20 @@ QIcon Icon::icon() const
for (int dpr = 1; dpr <= maxDpr; dpr++) {
const MasksAndColors masks = masksAndColors(m_iconSourceList, dpr);
const QPixmap combinedMask = Utils::combinedMask(masks, m_style);
m_lastIcon.addPixmap(masksToIcon(masks, combinedMask, m_style));
m_lastIcon.addPixmap(masksToIcon(masks, combinedMask, m_style), QIcon::Normal, QIcon::Off);
const QColor disabledColor = creatorColor(Theme::IconsDisabledColor);
m_lastIcon.addPixmap(maskToColorAndAlpha(combinedMask, disabledColor), QIcon::Disabled);
const QPixmap disabledIcon = maskToColorAndAlpha(combinedMask, disabledColor);
if (const OptMasksAndColors activeMasks =
highlightMasksAndColors(masks, m_iconSourceList);
activeMasks.has_value()) {
const QPixmap activePixmap = masksToIcon(activeMasks.value(),
combinedMask, m_style);
m_lastIcon.addPixmap(activePixmap, QIcon::Active, QIcon::On);
m_lastIcon.addPixmap(disabledIcon, QIcon::Disabled, QIcon::On);
m_lastIcon.addPixmap(disabledIcon, QIcon::Disabled, QIcon::Off);
} else {
m_lastIcon.addPixmap(disabledIcon, QIcon::Disabled);
}
}
return m_lastIcon;
}

View File

@@ -542,7 +542,8 @@ QPixmap StyleHelper::disabledSideBarIcon(const QPixmap &enabledicon)
// Draws a cached pixmap with shadow
void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
QPainter *p, QIcon::Mode iconMode, int dipRadius, const QColor &color, const QPoint &dipOffset)
QPainter *p, QIcon::Mode iconMode, QIcon::State iconState,
int dipRadius, const QColor &color, const QPoint &dipOffset)
{
QPixmap cache;
const qreal devicePixelRatio = p->device()->devicePixelRatioF();
@@ -555,7 +556,7 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
// return a high-dpi pixmap, which will in that case have a devicePixelRatio
// different than 1. The shadow drawing caluculations are done in device
// pixels.
QPixmap px = icon.pixmap(rect.size(), devicePixelRatio, iconMode);
QPixmap px = icon.pixmap(rect.size(), devicePixelRatio, iconMode, iconState);
int radius = int(dipRadius * devicePixelRatio);
QPoint offset = dipOffset * devicePixelRatio;
cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));

View File

@@ -152,7 +152,8 @@ QTCREATOR_UTILS_EXPORT bool usePixmapCache();
QTCREATOR_UTILS_EXPORT QPixmap disabledSideBarIcon(const QPixmap &enabledicon);
QTCREATOR_UTILS_EXPORT void drawIconWithShadow(const QIcon &icon, const QRect &rect, QPainter *p,
QIcon::Mode iconMode, int dipRadius = 3,
QIcon::Mode iconMode, QIcon::State iconState,
int dipRadius = 3,
const QColor &color = QColor(0, 0, 0, 130),
const QPoint &dipOffset = QPoint(1, -2));
QTCREATOR_UTILS_EXPORT void drawCornerImage(const QImage &img, QPainter *painter, const QRect &rect,

View File

@@ -392,6 +392,15 @@ expected_str<Theme::Color> Theme::colorToken(const QString &tokenName,
return result;
}
Theme::Color Theme::highlightFor(Color role)
{
QTC_ASSERT(creatorTheme(), return role);
static const QMap<QRgb, Theme::Color> map = {
{ creatorColor(Theme::Token_Text_Muted).rgba(), Theme::Token_Text_Default},
};
return map.value(creatorColor(role).rgba(), role);
}
QPalette Theme::initialPalette()
{
if (!m_initialPalette) {

View File

@@ -561,6 +561,7 @@ public:
static void setHelpMenu(QMenu *menu);
static expected_str<Color> colorToken(const QString &token, TokenFlags flags = {});
static Color highlightFor(Color role);
protected:
Theme(Theme *originTheme, QObject *parent = nullptr);

View File

@@ -193,7 +193,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
centerRect.adjust(0, lineHeight + 4, 0, -lineHeight * 2 - 4);
iconRect.moveCenter(centerRect.center());
StyleHelper::drawIconWithShadow(icon(), iconRect, &painter, iconMode);
StyleHelper::drawIconWithShadow(icon(), iconRect, &painter, iconMode, QIcon::Off);
painter.setFont(normalFont);
QPoint textOffset = centerRect.center()
@@ -243,7 +243,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
} else {
iconRect.moveCenter(rect().center());
StyleHelper::drawIconWithShadow(icon(), iconRect, &painter, iconMode);
StyleHelper::drawIconWithShadow(icon(), iconRect, &painter, iconMode, QIcon::Off);
}
// pop up arrow next to icon

View File

@@ -97,7 +97,7 @@ void FancyTabBar::paintEvent(QPaintEvent *event)
if (!m_tabs.at(i)->visible)
continue;
if (i != currentIndex())
paintTab(&p, i, visibleIndex);
paintTab(&p, i, visibleIndex, QIcon::Off);
else
visibleCurrentIndex = visibleIndex;
++visibleIndex;
@@ -105,7 +105,7 @@ void FancyTabBar::paintEvent(QPaintEvent *event)
// paint active tab last, since it overlaps the neighbors
if (currentIndex() != -1)
paintTab(&p, currentIndex(), visibleCurrentIndex);
paintTab(&p, currentIndex(), visibleCurrentIndex, QIcon::On);
}
// Handle hover events for mouse fade ins
@@ -295,7 +295,7 @@ static void paintHighlight(QPainter *painter, const QRect &rect)
}
static void paintIcon(QPainter *painter, const QRect &rect,
const QIcon &icon,
const QIcon &icon, QIcon::State iconState,
bool enabled, bool selected)
{
painter->save();
@@ -306,12 +306,12 @@ static void paintIcon(QPainter *painter, const QRect &rect,
iconRect = iconRect.intersected(rect);
if (!enabled && !creatorTheme()->flag(Theme::FlatToolBars))
painter->setOpacity(0.7);
StyleHelper::drawIconWithShadow(icon, iconRect, painter, iconMode);
StyleHelper::drawIconWithShadow(icon, iconRect, painter, iconMode, iconState);
painter->restore();
}
static void paintIconAndText(QPainter *painter, const QRect &rect,
const QIcon &icon, const QString &text,
const QIcon &icon, QIcon::State iconState, const QString &text,
bool enabled, bool selected)
{
painter->save();
@@ -330,7 +330,7 @@ static void paintIconAndText(QPainter *painter, const QRect &rect,
iconRect = iconRect.intersected(tabIconRect);
if (!enabled && !creatorTheme()->flag(Theme::FlatToolBars))
painter->setOpacity(0.7);
StyleHelper::drawIconWithShadow(icon, iconRect, painter, iconMode);
StyleHelper::drawIconWithShadow(icon, iconRect, painter, iconMode, iconState);
}
painter->setOpacity(1.0); //FIXME: was 0.7 before?
@@ -353,7 +353,8 @@ static void paintIconAndText(QPainter *painter, const QRect &rect,
painter->restore();
}
void FancyTabBar::paintTab(QPainter *painter, int tabIndex, int visibleIndex) const
void FancyTabBar::paintTab(QPainter *painter, int tabIndex, int visibleIndex,
QIcon::State iconState) const
{
if (!validIndex(tabIndex)) {
qWarning("invalid index");
@@ -387,9 +388,9 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex, int visibleIndex) co
}
if (m_iconsOnly)
paintIcon(painter, rect, tab->icon, enabled, selected);
paintIcon(painter, rect, tab->icon, iconState, enabled, selected);
else
paintIconAndText(painter, rect, tab->icon, tab->text, enabled, selected);
paintIconAndText(painter, rect, tab->icon, iconState, tab->text, enabled, selected);
if (selected && creatorTheme()->flag(Theme::FlatToolBars))
paintHighlight(painter, rect);

View File

@@ -63,7 +63,7 @@ public:
bool event(QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void paintTab(QPainter *painter, int tabIndex, int visibleIndex) const;
void paintTab(QPainter *painter, int tabIndex, int visibleIndex, QIcon::State iconState) const;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void enterEvent(QEnterEvent *event) override;

View File

@@ -1161,6 +1161,8 @@ void ManhattanStyle::drawComplexControl(ComplexControl control, const QStyleOpti
int fw = pixelMetric(PM_DefaultFrameWidth, option, widget);
label.rect = button.adjusted(fw, fw, -fw, -fw);
if (toolbutton->state.testAnyFlags(State_Sunken))
label.state.setFlag(State_On);
drawControl(CE_ToolButtonLabel, &label, painter, widget);
if (toolbutton->subControls & SC_ToolButtonMenu) {