feat: make nerd font optional

Move hardcodedd nerd fonts codepoints into a table. The default behavior
is still nerdFont. There is no general icon for network so drop the icon
in favor of the very clear up and down arrows.
This commit is contained in:
Cory Todd
2026-03-24 22:01:54 -07:00
parent 948c79fb59
commit 80f7716f21
3 changed files with 94 additions and 36 deletions
+3
View File
@@ -44,5 +44,8 @@
<entry name="showNetwork" type="Bool"> <entry name="showNetwork" type="Bool">
<default>true</default> <default>true</default>
</entry> </entry>
<entry name="useNerdFont" type="Bool">
<default>true</default>
</entry>
</group> </group>
</kcfg> </kcfg>
+11
View File
@@ -19,6 +19,7 @@ Item {
property bool cfg_showCpuUsage: true property bool cfg_showCpuUsage: true
property bool cfg_showMemory: true property bool cfg_showMemory: true
property bool cfg_showNetwork: true property bool cfg_showNetwork: true
property bool cfg_useNerdFont: true
component SectionHeader: ColumnLayout { component SectionHeader: ColumnLayout {
property string title: "" property string title: ""
@@ -205,6 +206,16 @@ Item {
} }
} }
// ── APPEARANCE ────────────────────────────────────────────────────────
SectionHeader { title: "APPEARANCE" }
QQC2.CheckBox {
text: "Use Nerd Font icons (disable for plain Unicode fallback)"
checked: cfg_useNerdFont
onToggled: cfg_useNerdFont = checked
}
Item { Layout.fillHeight: true; Layout.minimumHeight: 16 } Item { Layout.fillHeight: true; Layout.minimumHeight: 16 }
} }
+80 -36
View File
@@ -21,9 +21,21 @@ PlasmoidItem {
property bool showCpuUsage: Plasmoid.configuration.showCpuUsage !== false property bool showCpuUsage: Plasmoid.configuration.showCpuUsage !== false
property bool showMemory: Plasmoid.configuration.showMemory !== false property bool showMemory: Plasmoid.configuration.showMemory !== false
property bool showNetwork: Plasmoid.configuration.showNetwork !== false property bool showNetwork: Plasmoid.configuration.showNetwork !== false
property bool useNerdFont: Plasmoid.configuration.useNerdFont !== false
readonly property var ic: useNerdFont ? ({
cpuTemp: "\uf2c8", cpu: "\uf2db", mem: "\ue266",
down: "\uf063", up: "\uf062",
weather: { clear: "\ue30d", cloudy: "\ue312", fog: "\ue313", rain: "\ue318", snow: "\ue31a", storm: "\ue32e" }
}) : ({
cpuTemp: "\u0394", cpu: "\u2394", mem: "\u2630",
down: "\u2193", up: "\u2191",
weather: { clear: "\u2600\ufe0e", cloudy: "\u2601\ufe0e", fog: "\u2248", rain: "\u2602\ufe0e", snow: "\u2744\ufe0e", storm: "\u2607" }
})
// ── Live state ──────────────────────────────────────────────────────────── // ── Live state ────────────────────────────────────────────────────────────
property string weatherIcon: "" property int weatherCode: -1 // -1 = not yet fetched; computed binding keeps weatherIcon reactive to icon set changes
property string weatherIcon: weatherCode >= 0 ? iconForCode(weatherCode) : ""
property string temperature: "--" property string temperature: "--"
property string weatherCondition: "" property string weatherCondition: ""
property int cpuTempRaw: -1 property int cpuTempRaw: -1
@@ -54,54 +66,86 @@ PlasmoidItem {
// ── Panel display ───────────────────────────────────────────────────────── // ── Panel display ─────────────────────────────────────────────────────────
preferredRepresentation: fullRepresentation preferredRepresentation: fullRepresentation
fullRepresentation: PlasmaComponents.Label { fullRepresentation: RowLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: implicitWidth + 16 spacing: 0
verticalAlignment: Text.AlignVCenter
textFormat: Text.RichText
text: { // ── Main label (weather + cpu/mem) ────────────────────────────────────
// CPU temp is red when above threshold PlasmaComponents.Label {
var hot = root.cpuTempRaw > 0 && root.cpuTempRaw >= root.cpuTempThreshold Layout.fillHeight: true
Layout.preferredWidth: implicitWidth + 16
verticalAlignment: Text.AlignVCenter
textFormat: Text.RichText
// Weather section text: {
var s = root.weatherIcon + "\u00a0\u00a0" + root.temperature + "°" + (root.fahrenheit ? "F" : "C") var hot = root.cpuTempRaw > 0 && root.cpuTempRaw >= root.cpuTempThreshold
if (root.showCondition && root.weatherCondition !== "") var sp = "\u00a0\u00a0\u00a0\u00a0"
s += " " + root.weatherCondition var div = "\u00a0\u00a0\u2502\u00a0\u00a0"
// CPU + Memory stats var s = root.weatherIcon + "\u00a0\u00a0" + root.temperature + "°" + (root.fahrenheit ? "F" : "C")
var cpuMem = [] if (root.showCondition && root.weatherCondition !== "")
if (root.showCpuTemp) { s += " " + root.weatherCondition
var tempStr = "\uf2c8\u00a0\u00a0" + root.cpuTempDisplay
cpuMem.push(hot ? "<font color='#ff5555'>" + tempStr + "</font>" : tempStr) var cpuMem = []
if (root.showCpuTemp) {
var tempStr = root.ic.cpuTemp + "\u00a0\u00a0" + root.cpuTempDisplay
cpuMem.push(hot ? "<font color='#ff5555'>" + tempStr + "</font>" : tempStr)
}
if (root.showCpuUsage)
cpuMem.push(root.ic.cpu + "\u00a0\u00a0" + (root.cpuUsage >= 0 ? padPct(root.cpuUsage) : "\u00a0--"))
if (root.showMemory)
cpuMem.push(root.ic.mem + "\u00a0\u00a0" + (root.memUsage >= 0 ? padPct(root.memUsage) : "\u00a0--"))
if (cpuMem.length > 0) s += div + cpuMem.join(sp)
if (root.showNetwork) s += div
return s
} }
if (root.showCpuUsage) }
cpuMem.push("\uf2db\u00a0\u00a0" + (root.cpuUsage >= 0 ? padPct(root.cpuUsage) : "\u00a0--"))
if (root.showMemory)
cpuMem.push("\ue266\u00a0\u00a0" + (root.memUsage >= 0 ? padPct(root.memUsage) : "\u00a0--"))
var sp = "\u00a0\u00a0\u00a0\u00a0" // ── Network ───────────────────────────────────────────────────────────
var div = "\u00a0\u00a0\u2502\u00a0\u00a0" // A hidden reference label measures the pixel width of the widest
// possible value. Both visible labels are pinned to that exact width
// (min = preferred = max) so content changes never affect their size.
PlasmaComponents.Label {
id: netRef
visible: false
font.family: "monospace"
text: "000 MB/s"
}
if (cpuMem.length > 0) s += div + cpuMem.join(sp) PlasmaComponents.Label {
visible: root.showNetwork
font.family: "monospace"
Layout.fillHeight: true
Layout.minimumWidth: netRef.implicitWidth
Layout.preferredWidth: netRef.implicitWidth
Layout.maximumWidth: netRef.implicitWidth
verticalAlignment: Text.AlignVCenter
text: root.ic.down + " " + formatNetSpeed(root.netDown)
}
// Network stats PlasmaComponents.Label {
if (root.showNetwork) visible: root.showNetwork
s += div + "\uf0ac" + sp + "\uf063\u00a0\u00a0" + formatNetSpeed(root.netDown) + sp + "\uf062\u00a0\u00a0" + formatNetSpeed(root.netUp) font.family: "monospace"
Layout.fillHeight: true
return s + " " Layout.minimumWidth: netRef.implicitWidth
Layout.preferredWidth: netRef.implicitWidth
Layout.maximumWidth: netRef.implicitWidth
verticalAlignment: Text.AlignVCenter
text: " " + root.ic.up + " " + formatNetSpeed(root.netUp) + " "
} }
} }
// ── Weather ─────────────────────────────────────────────────────────────── // ── Weather ───────────────────────────────────────────────────────────────
function iconForCode(code) { function iconForCode(code) {
if (code === 0) return "\ue30d" if (code === 0) return ic.weather.clear
if (code <= 3) return "\ue312" if (code <= 3) return ic.weather.cloudy
if (code === 45 || code === 48) return "\ue313" if (code === 45 || code === 48) return ic.weather.fog
if ([51,53,55,61,63,65].indexOf(code) >= 0) return "\ue318" if ([51,53,55,61,63,65].indexOf(code) >= 0) return ic.weather.rain
if ([71,73,75].indexOf(code) >= 0) return "\ue31a" if ([71,73,75].indexOf(code) >= 0) return ic.weather.snow
return "\ue32e" return ic.weather.storm
} }
function conditionForCode(code) { function conditionForCode(code) {
@@ -132,7 +176,7 @@ PlasmoidItem {
if (req.readyState === XMLHttpRequest.DONE && req.status === 200) { if (req.readyState === XMLHttpRequest.DONE && req.status === 200) {
var cw = JSON.parse(req.responseText).current_weather var cw = JSON.parse(req.responseText).current_weather
root.temperature = Math.round(cw.temperature).toString() root.temperature = Math.round(cw.temperature).toString()
root.weatherIcon = root.iconForCode(cw.weathercode) root.weatherCode = cw.weathercode
root.weatherCondition = root.conditionForCode(cw.weathercode) root.weatherCondition = root.conditionForCode(cw.weathercode)
} }
} }