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 }
} }
+66 -22
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
spacing: 0
// ── Main label (weather + cpu/mem) ────────────────────────────────────
PlasmaComponents.Label {
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: implicitWidth + 16 Layout.preferredWidth: implicitWidth + 16
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
textFormat: Text.RichText textFormat: Text.RichText
text: { text: {
// CPU temp is red when above threshold
var hot = root.cpuTempRaw > 0 && root.cpuTempRaw >= root.cpuTempThreshold var hot = root.cpuTempRaw > 0 && root.cpuTempRaw >= root.cpuTempThreshold
var sp = "\u00a0\u00a0\u00a0\u00a0"
var div = "\u00a0\u00a0\u2502\u00a0\u00a0"
// Weather section
var s = root.weatherIcon + "\u00a0\u00a0" + root.temperature + "°" + (root.fahrenheit ? "F" : "C") var s = root.weatherIcon + "\u00a0\u00a0" + root.temperature + "°" + (root.fahrenheit ? "F" : "C")
if (root.showCondition && root.weatherCondition !== "") if (root.showCondition && root.weatherCondition !== "")
s += " " + root.weatherCondition s += " " + root.weatherCondition
// CPU + Memory stats
var cpuMem = [] var cpuMem = []
if (root.showCpuTemp) { if (root.showCpuTemp) {
var tempStr = "\uf2c8\u00a0\u00a0" + root.cpuTempDisplay var tempStr = root.ic.cpuTemp + "\u00a0\u00a0" + root.cpuTempDisplay
cpuMem.push(hot ? "<font color='#ff5555'>" + tempStr + "</font>" : tempStr) cpuMem.push(hot ? "<font color='#ff5555'>" + tempStr + "</font>" : tempStr)
} }
if (root.showCpuUsage) if (root.showCpuUsage)
cpuMem.push("\uf2db\u00a0\u00a0" + (root.cpuUsage >= 0 ? padPct(root.cpuUsage) : "\u00a0--")) cpuMem.push(root.ic.cpu + "\u00a0\u00a0" + (root.cpuUsage >= 0 ? padPct(root.cpuUsage) : "\u00a0--"))
if (root.showMemory) if (root.showMemory)
cpuMem.push("\ue266\u00a0\u00a0" + (root.memUsage >= 0 ? padPct(root.memUsage) : "\u00a0--")) cpuMem.push(root.ic.mem + "\u00a0\u00a0" + (root.memUsage >= 0 ? padPct(root.memUsage) : "\u00a0--"))
var sp = "\u00a0\u00a0\u00a0\u00a0"
var div = "\u00a0\u00a0\u2502\u00a0\u00a0"
if (cpuMem.length > 0) s += div + cpuMem.join(sp) if (cpuMem.length > 0) s += div + cpuMem.join(sp)
if (root.showNetwork) s += div
// Network stats return s
if (root.showNetwork) }
s += div + "\uf0ac" + sp + "\uf063\u00a0\u00a0" + formatNetSpeed(root.netDown) + sp + "\uf062\u00a0\u00a0" + formatNetSpeed(root.netUp) }
return s + " " // ── Network ───────────────────────────────────────────────────────────
// 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"
}
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)
}
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.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)
} }
} }