diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-17 12:21:39 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-17 12:21:39 +0200 |
| commit | a2a06d5d3e5b4b2352b0b327aa5d558b48174ab9 (patch) | |
| tree | 7d8933f3a2c9bf950acfc5514dc5d799c09f5874 | |
| parent | 9a479e198142a486413270c0e5dec8ed4405e023 (diff) | |
| download | conky-theme-udt-a2a06d5d3e5b4b2352b0b327aa5d558b48174ab9.tar.gz conky-theme-udt-a2a06d5d3e5b4b2352b0b327aa5d558b48174ab9.zip | |
feat: add bar, vbar, ring and threshold primitives
| -rw-r--r-- | lib/card.lua | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/card.lua b/lib/card.lua index 3352c4b..8e04e0b 100644 --- a/lib/card.lua +++ b/lib/card.lua @@ -123,4 +123,95 @@ function M.label(cr, x, y, s, colors) M.text(cr, x, y, s:upper()) end +-- Colour for a value against two thresholds. +-- +-- One function so all four system cards agree on the rule instead of each +-- re-deriving it, and so "what counts as busy" is stated in a single place. +-- `v`, `warn` and `crit` share whatever unit the caller is using: percent for +-- a filesystem, degrees for a sensor. +function M.threshold(v, warn, crit, colors) + if type(v) ~= 'number' then return colors.label end + if v >= crit then return colors.critical end + if v >= warn then return colors.warning end + return colors.ok +end + +-- A horizontal bar: a dim full-width track with a filled portion over it. +-- +-- frac is clamped rather than trusted: a filesystem at 100% and a load that +-- briefly computes above 1.0 must not draw past the track. +function M.bar(cr, x, y, w, h, frac, colour, colors) + frac = tonumber(frac) or 0 + if frac < 0 then frac = 0 elseif frac > 1 then frac = 1 end + + M.rgba(cr, colors.rule, 0.5) + M.rounded_path(cr, x, y, w, h, h / 2) + cairo_fill(cr) + + if frac > 0 then + M.rgba(cr, colour, 1) + M.rounded_path(cr, x, y, math.max(w * frac, h), h, h / 2) + cairo_fill(cr) + end +end + +-- A vertical bar, rising from its baseline. The equaliser's element. +function M.vbar(cr, x, base_y, w, max_h, frac, colour, colors) + frac = tonumber(frac) or 0 + if frac < 0 then frac = 0 elseif frac > 1 then frac = 1 end + + M.rgba(cr, colors.rule, 0.5) + cairo_rectangle(cr, x, base_y - max_h, w, max_h) + cairo_fill(cr) + + local h = max_h * frac + if h > 0 then + M.rgba(cr, colour, 1) + cairo_rectangle(cr, x, base_y - h, w, h) + cairo_fill(cr) + end +end + +-- A ring gauge, after idea2.png: a dim full circle with an arc over it +-- covering `frac`, leaving the centre free for a glyph. +-- +-- The arc starts at twelve o'clock and sweeps clockwise, which is what reads +-- as a gauge. Cairo's zero angle is at three o'clock and it sweeps clockwise +-- already, so the start is offset by -pi/2 rather than the direction being +-- reversed. +function M.ring(cr, cx, cy, r, frac, colour, colors, width) + frac = tonumber(frac) or 0 + if frac < 0 then frac = 0 elseif frac > 1 then frac = 1 end + width = width or math.max(3, r * 0.18) + + cairo_set_line_width(cr, width) + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND) + + M.rgba(cr, colors.rule, 0.5) + cairo_arc(cr, cx, cy, r, 0, math.pi * 2) + cairo_stroke(cr) + + if frac > 0 then + M.rgba(cr, colour, 1) + cairo_arc(cr, cx, cy, r, -math.pi / 2, -math.pi / 2 + math.pi * 2 * frac) + cairo_stroke(cr) + end + -- Leave the cap as it was found: a later stroke inheriting ROUND would get + -- visibly rounded ends on the card's hairlines. + cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT) +end + +-- Bytes to a short human string: 1181116006 -> '1.1G'. +-- The card formats its own numbers because the samplers pass raw bytes. +function M.human(bytes) + local n = tonumber(bytes) + if not n then return '--' end + local units = { 'B', 'K', 'M', 'G', 'T', 'P' } + local i = 1 + while n >= 1024 and i < #units do n = n / 1024; i = i + 1 end + if i == 1 then return string.format('%d%s', n, units[i]) end + if n >= 100 then return string.format('%.0f%s', n, units[i]) end + return string.format('%.1f%s', n, units[i]) +end + return M |
