mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-09 03:23:24 -08:00
[Icons] Rewrite the icon role docs in plain language
Address review: drop the AI-cadence prose from the IconStyle/IconTint and treatment headers, use ///< for the enum member docs, and move theme_icon.cpp's anonymous namespace above the IconTint definitions. No behavior change.
This commit is contained in:
parent
92b94c4ed7
commit
44ac98885a
6 changed files with 87 additions and 96 deletions
|
|
@ -48,8 +48,8 @@ Q_ENUM_NS(Role)
|
||||||
* define one.
|
* define one.
|
||||||
*
|
*
|
||||||
* Accent roles return an invalid QColor because ThemeManager derives them from
|
* Accent roles return an invalid QColor because ThemeManager derives them from
|
||||||
* the palette highlight. Semantic roles return an opaque, scheme-appropriate
|
* the palette highlight. Semantic roles return an opaque default that suits the
|
||||||
* default so a theme written before the role existed still renders it sensibly.
|
* scheme, so themes written before the role existed still render it.
|
||||||
*/
|
*/
|
||||||
QColor defaultAppColor(AppColor::Role role, bool dark);
|
QColor defaultAppColor(AppColor::Role role, bool dark);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,45 +28,6 @@
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
IconTint::IconTint(QPalette::ColorRole role) : paletteRole(role)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
IconTint::IconTint(AppColor::Role role) : source(Source::AppColor), appRole(role)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor IconTint::resolve(QIcon::Mode mode) const
|
|
||||||
{
|
|
||||||
if (source == Source::AppColor) {
|
|
||||||
// A disabled control must not keep signalling its semantic color.
|
|
||||||
if (mode == QIcon::Disabled) {
|
|
||||||
return qApp->palette().color(QPalette::Disabled, QPalette::WindowText);
|
|
||||||
}
|
|
||||||
// The three treatments paint the same tone: a line glyph, a badge disc
|
|
||||||
// and a sticker fill must not disagree on how saturated the role is.
|
|
||||||
// The fill treatments apply this floor themselves, so this only changes
|
|
||||||
// the line path, and only for the desaturated dark-scheme tones.
|
|
||||||
const QColor color = ThemeIconFill::saturated(themeManager->appColor(appRole));
|
|
||||||
if (mode != QIcon::Selected) {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
// Selected rows paint their icon on the highlight colour. Keep the
|
|
||||||
// semantic tint when it stays legible there; otherwise the glyph would
|
|
||||||
// vanish into the selection.
|
|
||||||
constexpr double MIN_SELECTED_CONTRAST = 3.0;
|
|
||||||
const QColor highlight = qApp->palette().color(QPalette::Active, QPalette::Highlight);
|
|
||||||
return ThemeIconBadge::contrastRatio(color, highlight) >= MIN_SELECTED_CONTRAST
|
|
||||||
? color
|
|
||||||
: qApp->palette().color(QPalette::Active, QPalette::HighlightedText);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QPalette::ColorGroup group = mode == QIcon::Disabled ? QPalette::Disabled : QPalette::Active;
|
|
||||||
const QPalette::ColorRole effective =
|
|
||||||
mode == QIcon::Selected && paletteRole == QPalette::WindowText ? QPalette::HighlightedText : paletteRole;
|
|
||||||
return qApp->palette().color(group, effective);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -354,6 +315,45 @@ private:
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
IconTint::IconTint(QPalette::ColorRole role) : paletteRole(role)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IconTint::IconTint(AppColor::Role role) : source(Source::AppColor), appRole(role)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor IconTint::resolve(QIcon::Mode mode) const
|
||||||
|
{
|
||||||
|
if (source == Source::AppColor) {
|
||||||
|
// A disabled control must not keep signalling its semantic color.
|
||||||
|
if (mode == QIcon::Disabled) {
|
||||||
|
return qApp->palette().color(QPalette::Disabled, QPalette::WindowText);
|
||||||
|
}
|
||||||
|
// The three treatments paint the same tone: a line glyph, a badge disc
|
||||||
|
// and a sticker fill must not disagree on how saturated the role is.
|
||||||
|
// The fill treatments apply this floor themselves, so this only changes
|
||||||
|
// the line path, and only for the desaturated dark-scheme tones.
|
||||||
|
const QColor color = ThemeIconFill::saturated(themeManager->appColor(appRole));
|
||||||
|
if (mode != QIcon::Selected) {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
// Selected rows paint their icon on the highlight colour. Keep the
|
||||||
|
// semantic tint when it stays legible there; otherwise the glyph would
|
||||||
|
// vanish into the selection.
|
||||||
|
constexpr double MIN_SELECTED_CONTRAST = 3.0;
|
||||||
|
const QColor highlight = qApp->palette().color(QPalette::Active, QPalette::Highlight);
|
||||||
|
return ThemeIconBadge::contrastRatio(color, highlight) >= MIN_SELECTED_CONTRAST
|
||||||
|
? color
|
||||||
|
: qApp->palette().color(QPalette::Active, QPalette::HighlightedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QPalette::ColorGroup group = mode == QIcon::Disabled ? QPalette::Disabled : QPalette::Active;
|
||||||
|
const QPalette::ColorRole effective =
|
||||||
|
mode == QIcon::Selected && paletteRole == QPalette::WindowText ? QPalette::HighlightedText : paletteRole;
|
||||||
|
return qApp->palette().color(group, effective);
|
||||||
|
}
|
||||||
|
|
||||||
QIcon loadThemedIcon(QStringView prefix, IconTint tint, IconStyle style)
|
QIcon loadThemedIcon(QStringView prefix, IconTint tint, IconStyle style)
|
||||||
{
|
{
|
||||||
return QIcon(new ThemeSvgIconEngine(prefix.toString(), tint, style));
|
return QIcon(new ThemeSvgIconEngine(prefix.toString(), tint, style));
|
||||||
|
|
|
||||||
|
|
@ -19,22 +19,21 @@
|
||||||
/**
|
/**
|
||||||
* @brief Selects how a `currentColor` glyph is painted.
|
* @brief Selects how a `currentColor` glyph is painted.
|
||||||
*
|
*
|
||||||
* Style is a treatment, not a color: the tint still decides the tone, and the
|
* The tint decides the tone. The style decides how much shape carries it.
|
||||||
* style decides how much shape carries that tone.
|
|
||||||
*
|
*
|
||||||
* Line is the default and the behavior every caller had before the axis
|
* Line is the default and matches what every caller did before this axis
|
||||||
* existed: the recolored glyph alone, at the author's stroke weight. It stays
|
* existed: the recolored glyph alone, at the author's stroke weight. Use it for
|
||||||
* the right choice for navigation, menu and toolbar glyphs, where a row of
|
* navigation, menu and toolbar glyphs, where a row of badges would compete with
|
||||||
* badges would outshout the content.
|
* the content.
|
||||||
*
|
*
|
||||||
* Badge reproduces the pre-#7595 ready/not-ready art: a filled disc, a dark ring
|
* Badge reproduces the pre-#7595 ready/not-ready art: a filled disc, a dark ring
|
||||||
* and a contrast glyph derived from the tone. It costs attention as a filled
|
* and a contrast glyph derived from the tone. A filled shape draws more
|
||||||
* shape, so it is opt-in per call site and it is not a generic semantic
|
* attention than a line, so it is opt-in per call site. It was made for the
|
||||||
* treatment: the add/remove/delete icons were filled glyphs with an outline and
|
* ready/not-ready icons. The add/remove/delete icons were filled glyphs with an
|
||||||
* no disc, so badging them would invent a look the UI never had. Authored art
|
* outline and no disc, so badging them would produce art the UI never had.
|
||||||
* that carries its own colors is never badged; it falls back to the asset path.
|
* Authored art that carries its own colors is never badged and falls back to the
|
||||||
* Disabled icons also fall back to the line glyph, because a filled disc at full
|
* asset path. Disabled icons fall back to the line glyph too, because a filled
|
||||||
* mass does not read as unavailable.
|
* disc at full mass does not read as unavailable.
|
||||||
*
|
*
|
||||||
* Sticker reproduces the other half of the pre-#7595 set: the filled add, remove
|
* Sticker reproduces the other half of the pre-#7595 set: the filled add, remove
|
||||||
* and delete glyphs, painted with a tone gradient and a dark outline and no
|
* and delete glyphs, painted with a tone gradient and a dark outline and no
|
||||||
|
|
@ -42,9 +41,9 @@
|
||||||
*/
|
*/
|
||||||
enum class IconStyle
|
enum class IconStyle
|
||||||
{
|
{
|
||||||
Line, // the recolored glyph alone
|
Line, ///< the recolored glyph alone
|
||||||
Badge, // filled disc + dark ring + contrast glyph
|
Badge, ///< filled disc + dark ring + contrast glyph
|
||||||
Sticker, // filled glyph + dark outline, no disc
|
Sticker, ///< filled glyph + dark outline, no disc
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -52,7 +51,7 @@ enum class IconStyle
|
||||||
*
|
*
|
||||||
* A palette role follows Qt's structural palette. An application color carries
|
* A palette role follows Qt's structural palette. An application color carries
|
||||||
* meaning that QPalette cannot express, such as positive and negative states.
|
* meaning that QPalette cannot express, such as positive and negative states.
|
||||||
* Callers pick the role by intent; the theme owns the concrete value.
|
* Callers choose the role. The active theme supplies the value.
|
||||||
*/
|
*/
|
||||||
class IconTint
|
class IconTint
|
||||||
{
|
{
|
||||||
|
|
@ -64,12 +63,11 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Resolves the concrete color for an icon mode.
|
* @brief Resolves the concrete color for an icon mode.
|
||||||
*
|
*
|
||||||
* Disabled application colors resolve to the disabled foreground so an
|
* A disabled application color resolves to the disabled foreground, so an
|
||||||
* unavailable control does not keep signalling its semantic color. Selected
|
* unavailable control does not keep its semantic color. A selected palette
|
||||||
* palette colors keep the existing WindowText -> HighlightedText swap.
|
* color keeps the WindowText -> HighlightedText swap. Application colors go
|
||||||
* Application colors pass through the filled treatments' saturation floor,
|
* through the saturation floor shared by the filled treatments, so a line
|
||||||
* so a line glyph, a badge disc and a sticker fill carry the same tone
|
* glyph, a badge disc and a sticker fill carry the same tone.
|
||||||
* instead of a pale line beside a saturated shape.
|
|
||||||
*/
|
*/
|
||||||
QColor resolve(QIcon::Mode mode) const;
|
QColor resolve(QIcon::Mode mode) const;
|
||||||
|
|
||||||
|
|
@ -98,8 +96,7 @@ private:
|
||||||
* extension (for example `icons/search`), matching themePixmap().
|
* extension (for example `icons/search`), matching themePixmap().
|
||||||
* @param tint Color that replaces the sentinel: a palette role or a semantic
|
* @param tint Color that replaces the sentinel: a palette role or a semantic
|
||||||
* application color. Defaults to WindowText.
|
* application color. Defaults to WindowText.
|
||||||
* @param style Treatment of the glyph: a line, or one of the filled treatments
|
* @param style Treatment of the glyph: Line, Badge or Sticker. Defaults to Line.
|
||||||
* that keep the pre-migration art reading. Defaults to Line.
|
|
||||||
* @return An icon that follows the application palette.
|
* @return An icon that follows the application palette.
|
||||||
*/
|
*/
|
||||||
QIcon loadThemedIcon(QStringView prefix, IconTint tint = {}, IconStyle style = IconStyle::Line);
|
QIcon loadThemedIcon(QStringView prefix, IconTint tint = {}, IconStyle style = IconStyle::Line);
|
||||||
|
|
@ -115,9 +112,8 @@ QIcon loadThemedIcon(QStringView prefix, IconTint tint = {}, IconStyle style = I
|
||||||
* @param tint Color that replaces the sentinel: a palette role or a semantic
|
* @param tint Color that replaces the sentinel: a palette role or a semantic
|
||||||
* application color. Defaults to WindowText.
|
* application color. Defaults to WindowText.
|
||||||
* @param size Pixel size to render at; an empty size uses the SVG's intrinsic size.
|
* @param size Pixel size to render at; an empty size uses the SVG's intrinsic size.
|
||||||
* @param style Treatment of the glyph: a line, or one of the filled treatments.
|
* @param style Treatment of the glyph: Line, Badge or Sticker. A treatment on a
|
||||||
* A treatment on a non-sentinel asset stays null, like the line
|
* non-sentinel asset stays null, like the line path.
|
||||||
* path.
|
|
||||||
* @return The recolored pixmap, or a null pixmap when the asset is not a
|
* @return The recolored pixmap, or a null pixmap when the asset is not a
|
||||||
* sentinel-carrying SVG.
|
* sentinel-carrying SVG.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,16 @@
|
||||||
/**
|
/**
|
||||||
* @brief Paints the badge treatment of a `currentColor` glyph.
|
* @brief Paints the badge treatment of a `currentColor` glyph.
|
||||||
*
|
*
|
||||||
* A tint alone can say "positive" or "negative", but a 2px line at 16px reads as
|
* A tint alone changes the color of a 2px line, but the UI drew ready and
|
||||||
* a different thing from the filled badge art the UI used before the one-glyph
|
* not-ready states as a filled badge before the one-glyph cutover. The badge
|
||||||
* cutover. The badge treatment keeps that shape: a filled disc, a dark ring, and
|
* treatment keeps that shape: a filled disc, a dark ring and a contrast glyph,
|
||||||
* a contrast glyph, all derived from the one tone the tint resolves to. So the
|
* all derived from the tone the tint resolves to. The theme still owns the
|
||||||
* theme still owns the color, and callers only choose between a line and a
|
* color. Callers only choose between a line and a badge.
|
||||||
* badge.
|
|
||||||
*
|
*
|
||||||
* The trade-off is fidelity against contrast. A badge is a small picture: it
|
* A badge survives a busy toolbar and a tinted row better than a hairline, and
|
||||||
* survives a busy toolbar and a tinted row better than a hairline, and it can
|
* its glyph can be light or dark regardless of the surrounding text. The cost is
|
||||||
* carry a light or dark glyph independent of the surrounding text. In exchange
|
* more attention per control, and the glyph color follows the scheme it is drawn
|
||||||
* it costs more pixels of attention per control, and its glyph color follows the
|
* for instead of the window's text color.
|
||||||
* scheme it is drawn for rather than the window's text color, so it is
|
|
||||||
* deliberately not the palette's foreground.
|
|
||||||
*
|
*
|
||||||
* Everything here works in device pixels. The icon engine renders at the
|
* Everything here works in device pixels. The icon engine renders at the
|
||||||
* device-pixel size it already computed and sets the pixmap's device pixel ratio
|
* device-pixel size it already computed and sets the pixmap's device pixel ratio
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,15 @@
|
||||||
/**
|
/**
|
||||||
* @brief Picks the two colors of a filled treatment's vertical gradient.
|
* @brief Picks the two colors of a filled treatment's vertical gradient.
|
||||||
*
|
*
|
||||||
* The pre-#7595 icons were filled with a lighter top over a darker bottom, and
|
* The pre-#7595 icons were filled with a lighter top over a darker bottom. The
|
||||||
* the semantic tones are tuned for text rather than for filling a whole shape:
|
* semantic tones are tuned for text, not for filling a whole shape; the
|
||||||
* the dark-scheme tones especially are deliberately desaturated, which reads
|
* dark-scheme tones in particular are desaturated and read washed out once a
|
||||||
* washed out once a disc or a glyph carries them. The badge and the sticker
|
* disc or a glyph carries them. The badge and the sticker share one fill rule so
|
||||||
* therefore share one fill rule, so the two sit next to each other with the same
|
* they sit next to each other with the same green or red.
|
||||||
* green or red.
|
|
||||||
*
|
*
|
||||||
* The rule needs no scheme switch of its own: a tone whose value is already high
|
* The rule needs no scheme switch: a tone whose value is already high is a
|
||||||
* is a dark-scheme tone, and its gradient is pulled down instead of up, because
|
* dark-scheme tone, so its gradient is pulled down. Filling a shape with a tone
|
||||||
* filling a shape with a tone that light is what reads pale.
|
* that light is what reads pale.
|
||||||
*/
|
*/
|
||||||
namespace ThemeIconFill
|
namespace ThemeIconFill
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,14 @@
|
||||||
* @brief Paints the sticker treatment of a `currentColor` glyph.
|
* @brief Paints the sticker treatment of a `currentColor` glyph.
|
||||||
*
|
*
|
||||||
* The pre-#7595 add, remove and delete icons were filled shapes with a black
|
* The pre-#7595 add, remove and delete icons were filled shapes with a black
|
||||||
* outline, not discs. A tint alone cannot bring that back: it produces a
|
* outline and no disc. A tint alone cannot reproduce that: it produces a
|
||||||
* hairline, and a badge disc would be a different icon language. The sticker
|
* hairline, and a badge disc is a different icon language. The sticker
|
||||||
* treatment rebuilds the look from the same sentinel art by drawing the glyph
|
* treatment rebuilds the look from the same sentinel art by drawing the glyph
|
||||||
* twice, once with a dark outline and once with a vertical tone gradient on top.
|
* twice, once with a dark outline and once with a vertical tone gradient on top.
|
||||||
*
|
*
|
||||||
* The trade-off is weight against crispness. A sticker is louder than a line,
|
* A sticker is louder than a line, which suits an add or a destructive action.
|
||||||
* which is what an add or a destructive action wants, but it needs a size where
|
* It needs a size where the tone band is at least two device pixels wide.
|
||||||
* the tone band is at least two device pixels wide. Callers opt in; navigation
|
* Callers opt in. Navigation and menus keep the line treatment.
|
||||||
* and menus keep the line treatment.
|
|
||||||
*
|
*
|
||||||
* Everything here works in device pixels, like the badge treatment: the engine
|
* Everything here works in device pixels, like the badge treatment: the engine
|
||||||
* renders at the size it already computed and attaches the device pixel ratio
|
* renders at the size it already computed and attaches the device pixel ratio
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue