refactor: icons follow builders pattern

Also add icon size() shorthand
And builder scale()
This commit is contained in:
2 * r + 2 * t 2026-04-21 18:17:03 +10:00
parent 6573a62fc5
commit c4539d6960
30 changed files with 81 additions and 42 deletions

View file

@ -16,7 +16,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
animate: true animate: true
text: root.icon text: root.icon
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 3).weight(Font.Bold).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(3).weight(Font.Bold).build()
} }
StyledText { StyledText {

View file

@ -7,5 +7,5 @@ StyledText {
property int grade: Colours.light ? 0 : -25 property int grade: Colours.light ? 0 : -25
property font fontStyle: Tokens.font.icon.small property font fontStyle: Tokens.font.icon.small
font: Tokens.font.icon.builder.size(fontStyle.pointSize).weight(fontStyle.weight).fill(fill.toFixed(1)).grade(grade).build() font: Tokens.font.icon.size(fontStyle.pointSize).weight(fontStyle.weight).fill(fill.toFixed(1)).grade(grade).build()
} }

View file

@ -61,7 +61,7 @@ StyledRect {
fill: root.toggled ? 1 : 0 fill: root.toggled ? 1 : 0
text: root.icon text: root.icon
color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`] color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`]
fontStyle: Tokens.font.icon.builder.size(root.iconSize).build() fontStyle: Tokens.font.icon.size(root.iconSize).build()
Behavior on fill { Behavior on fill {
Anim {} Anim {}

View file

@ -59,7 +59,7 @@ Item {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: "scan_delete" text: "scan_delete"
color: Colours.palette.m3outline color: Colours.palette.m3outline
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 2).weight(Font.Medium).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).weight(Font.Medium).build()
} }
StyledText { StyledText {

View file

@ -48,7 +48,7 @@ Item {
MaterialIcon { MaterialIcon {
text: "sentiment_stressed" text: "sentiment_stressed"
color: Colours.palette.m3onSurfaceVariant color: Colours.palette.m3onSurfaceVariant
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 5).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(5).build()
} }
Column { Column {

View file

@ -29,6 +29,6 @@ Item {
text: "power_settings_new" text: "power_settings_new"
color: Colours.palette.m3error color: Colours.palette.m3error
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.medium.pointSize).weight(Font.Bold).build() fontStyle: Tokens.font.icon.builders.small.weight(Font.Bold).build()
} }
} }

View file

@ -177,7 +177,7 @@ ColumnLayout {
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: "lock" text: "lock"
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 2).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).build()
} }
StyledText { StyledText {

View file

@ -23,7 +23,7 @@ Item {
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: root.icon text: root.icon
fontStyle: Tokens.font.icon.builder.size(84).weight(Font.Bold).build() fontStyle: Tokens.font.icon.size(84).weight(Font.Bold).build()
} }
StyledText { StyledText {

View file

@ -149,7 +149,7 @@ Item {
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: "lock" text: "lock"
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 2).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).build()
} }
StyledText { StyledText {

View file

@ -41,7 +41,7 @@ StyledRect {
text: "lyrics" text: "lyrics"
fill: 1 fill: 1
color: Colours.palette.m3primary color: Colours.palette.m3primary
fontStyle: Tokens.font.icon.builder.size(Tokens.spacing.large).build() fontStyle: Tokens.font.icon.size(Tokens.spacing.large).build()
} }
Rectangle { Rectangle {

View file

@ -173,7 +173,7 @@ Item {
grade: 200 grade: 200
text: "art_track" text: "art_track"
color: Colours.palette.m3onSurfaceVariant color: Colours.palette.m3onSurfaceVariant
fontStyle: Tokens.font.icon.builder.size((parent.width * 0.4) || 1).build() fontStyle: Tokens.font.icon.size((parent.width * 0.4) || 1).build()
} }
Image { Image {
@ -267,7 +267,7 @@ Item {
PlayerControl { PlayerControl {
type: IconButton.Text type: IconButton.Text
icon: Players.active?.shuffle ? "shuffle_on" : "shuffle" icon: Players.active?.shuffle ? "shuffle_on" : "shuffle"
font: Tokens.font.icon.builder.size(Math.round(Tokens.font.icon.large.pointSize)).build() font: Tokens.font.icon.size(Math.round(Tokens.font.icon.large.pointSize)).build()
disabled: !Players.active?.shuffleSupported disabled: !Players.active?.shuffleSupported
onClicked: Players.active.shuffle = !Players.active?.shuffle onClicked: Players.active.shuffle = !Players.active?.shuffle
} }
@ -275,7 +275,7 @@ Item {
PlayerControl { PlayerControl {
type: IconButton.Text type: IconButton.Text
icon: "skip_previous" icon: "skip_previous"
font: Tokens.font.icon.builder.size(Math.round(Tokens.font.icon.large.pointSize * 1.5)).build() font: Tokens.font.icon.builders.large.scale(1.5).build()
disabled: !Players.active?.canGoPrevious disabled: !Players.active?.canGoPrevious
onClicked: Players.active?.previous() onClicked: Players.active?.previous()
} }
@ -286,7 +286,7 @@ Item {
toggle: true toggle: true
padding: Tokens.padding.extraSmall / 2 padding: Tokens.padding.extraSmall / 2
checked: Players.active?.isPlaying ?? false checked: Players.active?.isPlaying ?? false
font: Tokens.font.icon.builder.size(Math.round(Tokens.font.icon.large.pointSize * 1.5)).build() font: Tokens.font.icon.builders.large.scale(1.5).build()
disabled: !Players.active?.canTogglePlaying disabled: !Players.active?.canTogglePlaying
onClicked: Players.active?.togglePlaying() onClicked: Players.active?.togglePlaying()
} }
@ -294,7 +294,7 @@ Item {
PlayerControl { PlayerControl {
type: IconButton.Text type: IconButton.Text
icon: "skip_next" icon: "skip_next"
font: Tokens.font.icon.builder.size(Math.round(Tokens.font.icon.large.pointSize * 1.5)).build() font: Tokens.font.icon.builders.large.scale(1.5).build()
disabled: !Players.active?.canGoNext disabled: !Players.active?.canGoNext
onClicked: Players.active?.next() onClicked: Players.active?.next()
} }
@ -302,7 +302,7 @@ Item {
PlayerControl { PlayerControl {
type: IconButton.Text type: IconButton.Text
icon: "lyrics" icon: "lyrics"
font: Tokens.font.icon.builder.size(Math.round(Tokens.font.icon.large.pointSize)).build() font: Tokens.font.icon.size(Math.round(Tokens.font.icon.large.pointSize)).build()
onClicked: root.lyricMenuOpen = !root.lyricMenuOpen onClicked: root.lyricMenuOpen = !root.lyricMenuOpen
} }
} }

View file

@ -37,7 +37,7 @@ Item {
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: "tune" text: "tune"
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 2).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).build()
color: Colours.palette.m3onSurfaceVariant color: Colours.palette.m3onSurfaceVariant
} }
@ -287,7 +287,7 @@ Item {
text: parent.icon text: parent.icon
fill: 1 fill: 1
color: parent.accentColor color: parent.accentColor
fontStyle: Tokens.font.icon.builder.size(Tokens.spacing.large).build() fontStyle: Tokens.font.icon.size(Tokens.spacing.large).build()
} }
StyledText { StyledText {

View file

@ -79,7 +79,7 @@ Item {
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
text: Weather.icon text: Weather.icon
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 3).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(3).build()
color: Colours.palette.m3secondary color: Colours.palette.m3secondary
animate: true animate: true
} }

View file

@ -61,7 +61,7 @@ CustomMouseArea {
anchors.centerIn: parent anchors.centerIn: parent
text: "chevron_left" text: "chevron_left"
color: Colours.palette.m3tertiary color: Colours.palette.m3tertiary
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.medium.pointSize).weight(Font.Bold).build() fontStyle: Tokens.font.icon.size(Tokens.font.icon.medium.pointSize).weight(Font.Bold).build()
} }
} }
@ -118,7 +118,7 @@ CustomMouseArea {
anchors.centerIn: parent anchors.centerIn: parent
text: "chevron_right" text: "chevron_right"
color: Colours.palette.m3tertiary color: Colours.palette.m3tertiary
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.medium.pointSize).weight(Font.Bold).build() fontStyle: Tokens.font.icon.size(Tokens.font.icon.medium.pointSize).weight(Font.Bold).build()
} }
} }
} }

View file

@ -98,7 +98,7 @@ Item {
grade: 200 grade: 200
text: "art_track" text: "art_track"
color: Colours.palette.m3onSurfaceVariant color: Colours.palette.m3onSurfaceVariant
fontStyle: Tokens.font.icon.builder.size((parent.width * 0.4) || 1).build() fontStyle: Tokens.font.icon.size((parent.width * 0.4) || 1).build()
} }
Image { Image {

View file

@ -21,7 +21,7 @@ Item {
animate: true animate: true
text: Weather.icon text: Weather.icon
color: Colours.palette.m3secondary color: Colours.palette.m3secondary
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 2).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).build()
} }
Column { Column {

View file

@ -29,7 +29,7 @@ Row {
text: "person" text: "person"
fill: 1 fill: 1
grade: 200 grade: 200
fontStyle: Tokens.font.icon.builder.size(Math.floor(info.implicitHeight / 2) || 1).build() fontStyle: Tokens.font.icon.size(Math.floor(info.implicitHeight / 2) || 1).build()
visible: pfp.status !== Image.Ready visible: pfp.status !== Image.Ready
} }

View file

@ -58,7 +58,7 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
text: "image" text: "image"
color: Colours.tPalette.m3outline color: Colours.tPalette.m3outline
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 2).weight(Font.DemiBold).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).weight(Font.DemiBold).build()
} }
CachingImage { CachingImage {

View file

@ -87,7 +87,7 @@ ColumnLayout {
text: "person" text: "person"
color: Colours.palette.m3onSurfaceVariant color: Colours.palette.m3onSurfaceVariant
fontStyle: Tokens.font.icon.builder.size(Math.floor(root.centerWidth / 4)).build() fontStyle: Tokens.font.icon.size(Math.floor(root.centerWidth / 4)).build()
visible: pfp.status !== Image.Ready visible: pfp.status !== Image.Ready
} }
@ -194,7 +194,7 @@ ColumnLayout {
anchors.centerIn: parent anchors.centerIn: parent
text: "arrow_forward" text: "arrow_forward"
color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.large.pointSize).weight(Font.Medium).build() fontStyle: Tokens.font.icon.size(Tokens.font.icon.large.pointSize).weight(Font.Medium).build()
} }
} }
} }

View file

@ -207,7 +207,7 @@ WlSessionLockSurface {
anchors.centerIn: parent anchors.centerIn: parent
text: "lock" text: "lock"
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 4).weight(Font.Bold).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(4).weight(Font.Bold).build()
rotation: 180 rotation: 180
} }

View file

@ -80,7 +80,7 @@ GridLayout {
anchors.centerIn: parent anchors.centerIn: parent
text: res.icon text: res.icon
color: res.colour color: res.colour
fontStyle: Tokens.font.icon.builder.size((circ.arcRadius * 0.7) || 1).weight(Font.DemiBold).build() fontStyle: Tokens.font.icon.size((circ.arcRadius * 0.7) || 1).weight(Font.DemiBold).build()
} }
Behavior on value { Behavior on value {

View file

@ -41,7 +41,7 @@ ColumnLayout {
animate: true animate: true
text: Weather.icon text: Weather.icon
color: Colours.palette.m3secondary color: Colours.palette.m3secondary
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 2.5).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(2.5).build()
} }
ColumnLayout { ColumnLayout {
@ -150,7 +150,7 @@ ColumnLayout {
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: forecastHour.modelData?.icon ?? "cloud_alert" text: forecastHour.modelData?.icon ?? "cloud_alert"
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 1.5).weight(Font.Medium).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(1.5).weight(Font.Medium).build()
} }
StyledText { StyledText {

View file

@ -125,7 +125,7 @@ Column {
text: button.icon text: button.icon
color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize).weight(Font.Medium).build() fontStyle: Tokens.font.icon.size(Tokens.font.icon.extraLarge.pointSize).weight(Font.Medium).build()
} }
} }
} }

View file

@ -183,7 +183,7 @@ Item {
icon: "clear_all" icon: "clear_all"
radius: Tokens.rounding.large radius: Tokens.rounding.large
padding: Tokens.padding.medium padding: Tokens.padding.medium
font: Tokens.font.icon.builder.size(Math.round(Tokens.font.icon.large.pointSize * 1.2)).build() font: Tokens.font.icon.builders.large.scale(1.2).build()
onClicked: clearTimer.start() onClicked: clearTimer.start()
Elevation { Elevation {

View file

@ -84,7 +84,7 @@ StyledRect {
return Colours.palette.m3onError; return Colours.palette.m3onError;
return Colours.palette.m3onSurfaceVariant; return Colours.palette.m3onSurfaceVariant;
} }
fontStyle: Tokens.font.icon.builder.size(Math.round(Tokens.font.icon.large.pointSize * 1.2)).build() fontStyle: Tokens.font.icon.builders.large.scale(1.2).build()
} }
} }

View file

@ -44,7 +44,7 @@ Item {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: "web_asset_off" text: "web_asset_off"
color: Colours.palette.m3outline color: Colours.palette.m3outline
fontStyle: Tokens.font.icon.builder.size(Tokens.font.icon.extraLarge.pointSize * 3).build() fontStyle: Tokens.font.icon.builders.extraLarge.scale(3).build()
} }
StyledText { StyledText {

View file

@ -79,6 +79,14 @@ FontBuilders* FontStyle::builders() const {
// IconFontStyle // IconFontStyle
IconFontStyle::IconFontStyle(QObject* parent)
: FontStyleBase(parent)
, m_builders(new IconFontBuilders(this, this)) {}
FontBuilder IconFontStyle::size(int pointSize) {
return FontBuilder(m_small).size(pointSize);
}
void IconFontStyle::bind(IconFontStyleConfig* cfg) { void IconFontStyle::bind(IconFontStyleConfig* cfg) {
if (m_cfg == cfg) if (m_cfg == cfg)
return; return;
@ -99,8 +107,8 @@ QFont IconFontStyle::extraLarge() const {
return m_extraLarge; return m_extraLarge;
} }
FontBuilder IconFontStyle::builder() const { IconFontBuilders* IconFontStyle::builders() const {
return FontBuilder(m_large); return m_builders;
} }
void IconFontStyle::rebuild() { void IconFontStyle::rebuild() {
@ -138,6 +146,15 @@ FontBuilder FontBuilders::small() const {
return FontBuilder(m_style->small()); return FontBuilder(m_style->small());
} }
// IconFontBuilders
IconFontBuilders::IconFontBuilders(const IconFontStyle* style, QObject* parent)
: FontBuilders(style, parent) {}
FontBuilder IconFontBuilders::extraLarge() const {
return FontBuilder(static_cast<const IconFontStyle*>(m_style)->extraLarge());
}
// FontTokens // FontTokens
FontTokens::FontTokens(QObject* parent) FontTokens::FontTokens(QObject* parent)

View file

@ -11,6 +11,7 @@ class FontConfig;
class FontStyleConfig; class FontStyleConfig;
class IconFontStyleConfig; class IconFontStyleConfig;
class FontStyleBase; class FontStyleBase;
class IconFontStyle;
class FontBuilders : public QObject { class FontBuilders : public QObject {
Q_OBJECT Q_OBJECT
@ -30,10 +31,22 @@ public:
signals: signals:
void buildersChanged(); void buildersChanged();
private: protected:
const FontStyleBase* m_style; const FontStyleBase* m_style;
}; };
class IconFontBuilders : public FontBuilders {
Q_OBJECT
QML_ANONYMOUS
Q_PROPERTY(caelestia::config::FontBuilder extraLarge READ extraLarge NOTIFY buildersChanged FINAL)
public:
explicit IconFontBuilders(const IconFontStyle* style, QObject* parent = nullptr);
[[nodiscard]] FontBuilder extraLarge() const;
};
class FontStyleBase : public QObject { class FontStyleBase : public QObject {
Q_OBJECT Q_OBJECT
@ -85,22 +98,24 @@ class IconFontStyle : public FontStyleBase {
QML_ANONYMOUS QML_ANONYMOUS
Q_PROPERTY(QFont extraLarge READ extraLarge NOTIFY fontsChanged FINAL) Q_PROPERTY(QFont extraLarge READ extraLarge NOTIFY fontsChanged FINAL)
Q_PROPERTY(caelestia::config::FontBuilder builder READ builder NOTIFY fontsChanged FINAL) Q_PROPERTY(caelestia::config::IconFontBuilders* builders READ builders CONSTANT FINAL)
public: public:
explicit IconFontStyle(QObject* parent = nullptr) explicit IconFontStyle(QObject* parent = nullptr);
: FontStyleBase(parent) {}
Q_INVOKABLE FontBuilder size(int pointSize);
void bind(IconFontStyleConfig* cfg); void bind(IconFontStyleConfig* cfg);
[[nodiscard]] QFont extraLarge() const; [[nodiscard]] QFont extraLarge() const;
[[nodiscard]] FontBuilder builder() const; [[nodiscard]] IconFontBuilders* builders() const;
protected: protected:
void rebuild() override; void rebuild() override;
private: private:
QFont m_extraLarge; QFont m_extraLarge;
IconFontBuilders* m_builders;
}; };
class FontTokens : public QObject { class FontTokens : public QObject {

View file

@ -71,4 +71,8 @@ FontBuilder FontBuilder::width(float value) {
return vaxis("wdth", value); return vaxis("wdth", value);
} }
FontBuilder FontBuilder::scale(qreal factor) {
return size(static_cast<int>(m_font.pointSize() * factor));
}
} // namespace caelestia::config } // namespace caelestia::config

View file

@ -29,6 +29,9 @@ public:
[[nodiscard]] Q_INVOKABLE FontBuilder grade(float value); [[nodiscard]] Q_INVOKABLE FontBuilder grade(float value);
[[nodiscard]] Q_INVOKABLE FontBuilder width(float value); [[nodiscard]] Q_INVOKABLE FontBuilder width(float value);
// Operations
[[nodiscard]] Q_INVOKABLE FontBuilder scale(qreal factor);
private: private:
QFont m_font; QFont m_font;
}; };