aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-18 18:41:31 +0200
committerDanilo M. <danix@danix.xyz>2026-09-18 18:41:31 +0200
commit7fddddcd39bb250cd2653e130c8f7899d2d3f19c (patch)
treeca427df07676563853fb7f25f6ce4eb14e63a25b /widgets
parent37cabe2fea2f86d481516aae6ddaeb14bac2e64f (diff)
downloadconky-theme-udt-7fddddcd39bb250cd2653e130c8f7899d2d3f19c.tar.gz
conky-theme-udt-7fddddcd39bb250cd2653e130c8f7899d2d3f19c.zip
refactor: unify card no-data face and fluid sizing
Extract card.notice so every cached card's no-data state is one fluid, theme-consistent face instead of a copy per widget, and delete the fixed-size card.label it replaces. Derive weather's arc geometry from its band (pad, curve room, sun dot, time labels) instead of fixed pixels, and cap the arc at a proportion of the card's width rather than 240px. Derive disks' bar-fallback height and its address type from the card's own label scale. Standardise the big-value factor to 1.0 across the fit_unit cards and document the big-value colour rule and the disks headline exception.
Diffstat (limited to 'widgets')
-rw-r--r--widgets/breaktimer.lua16
-rw-r--r--widgets/cache.lua15
-rw-r--r--widgets/calendar.lua20
-rw-r--r--widgets/disks.lua21
-rw-r--r--widgets/network.lua2
-rw-r--r--widgets/slackware.lua16
-rw-r--r--widgets/weather.lua46
7 files changed, 39 insertions, 97 deletions
diff --git a/widgets/breaktimer.lua b/widgets/breaktimer.lua
index 698be80..e6487b8 100644
--- a/widgets/breaktimer.lua
+++ b/widgets/breaktimer.lua
@@ -21,7 +21,7 @@ local M = {}
function M.draw(cr, rect, colors)
local inner = card.card(cr, rect, colors)
local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
- local LABEL_F, BIG_F, ROW_F = 0.30, 0.85, 0.32
+ local LABEL_F, BIG_F, ROW_F = 0.30, 1.0, 0.32
local bt = data.breaktimer_parse(data.slurp(CACHE) or '')
@@ -30,19 +30,7 @@ function M.draw(cr, rect, colors)
-- crash. A stopped daemon is NOT this case: the sampler still writes a cache,
-- with running no, which the card draws as 'fermo'.
if not bt then
- local S = clamp(inner.h * 0.94 / (1.78 + 2 * 0.72), 10, 72)
- S = math.min(S, card.fit_unit(cr, inner.w * 0.96, {
- { { 'BREAKTIMER', card.FONT_MONO, LABEL_F } },
- { { 'no breaktimer data', card.FONT_UI, 0.36 } },
- { { 'bin/breaktimer-sample.sh', card.FONT_MONO, ROW_F } },
- }, 100))
- card.font(cr, card.FONT_MONO, S * LABEL_F, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + S * LABEL_F, 'BREAKTIMER')
- card.font(cr, card.FONT_UI, S * 0.36, true)
- card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6, 'no breaktimer data')
- card.font(cr, card.FONT_MONO, S * ROW_F, false)
- card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6 + S * 0.72,
+ card.notice(cr, inner, colors, 'BREAKTIMER', 'no breaktimer data',
'bin/breaktimer-sample.sh')
return
end
diff --git a/widgets/cache.lua b/widgets/cache.lua
index af20347..3772458 100644
--- a/widgets/cache.lua
+++ b/widgets/cache.lua
@@ -22,20 +22,7 @@ function M.draw(cr, rect, colors)
local c = data.du_parse(data.slurp(CACHE) or '')
if not c then
- local S = clamp(inner.h * 0.94 / (1.78 + 2 * 0.72), 10, 72)
- S = math.min(S, card.fit_unit(cr, inner.w * 0.96, {
- { { 'CACHE', card.FONT_MONO, LABEL_F } },
- { { 'no cache data', card.FONT_UI, 0.36 } },
- { { 'bin/cache-sample.sh', card.FONT_MONO, ROW_F } },
- }, 100))
- card.font(cr, card.FONT_MONO, S * LABEL_F, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + S * LABEL_F, 'CACHE')
- card.font(cr, card.FONT_UI, S * 0.36, true)
- card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6, 'no cache data')
- card.font(cr, card.FONT_MONO, S * ROW_F, false)
- card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6 + S * 0.72,
- 'bin/cache-sample.sh')
+ card.notice(cr, inner, colors, 'CACHE', 'no cache data', 'bin/cache-sample.sh')
return
end
diff --git a/widgets/calendar.lua b/widgets/calendar.lua
index 6194447..b31e3b2 100644
--- a/widgets/calendar.lua
+++ b/widgets/calendar.lua
@@ -52,24 +52,6 @@ local function when(e)
return string.format('%02d/%02d %s', e.d, e.m, e.start or 'all day')
end
--- The failure face: the sampler has not run. Named, as the other cached cards
--- do, rather than a blank cell that cannot be told from a crashed widget.
-local function draw_empty(cr, inner, colors, label_f, note, hint)
- local S = clamp(inner.h * 0.94 / (1.78 + 2 * 0.72), 10, 72)
- S = math.min(S, card.fit_unit(cr, inner.w * 0.96, {
- { { 'CALENDAR', card.FONT_MONO, label_f } },
- { { note, card.FONT_UI, 0.36 } },
- { { hint, card.FONT_MONO, 0.32 } },
- }, 100))
- card.font(cr, card.FONT_MONO, S * label_f, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + S * label_f, 'CALENDAR')
- card.font(cr, card.FONT_UI, S * 0.36, true)
- card.text(cr, inner.x, inner.y + S + S * label_f * 2.6, note)
- card.font(cr, card.FONT_MONO, S * 0.32, false)
- card.text(cr, inner.x, inner.y + S + S * label_f * 2.6 + S * 0.72, hint)
-end
-
-- The legend: one coloured dot and name per calendar, along the card's bottom.
-- Wraps to a second line when the names do not fit, and drops any that still
-- do not: a legend spilling off the card is worse than a short one, since the
@@ -103,7 +85,7 @@ function M.draw(cr, rect, colors)
local cal = data.calendar_parse(data.slurp(CACHE) or '')
if not cal then
- draw_empty(cr, inner, colors, LABEL_F, 'no calendar data',
+ card.notice(cr, inner, colors, 'CALENDAR', 'no calendar data',
'bin/calendar-sample.sh')
return
end
diff --git a/widgets/disks.lua b/widgets/disks.lua
index 3b0f221..fa97b50 100644
--- a/widgets/disks.lua
+++ b/widgets/disks.lua
@@ -43,20 +43,16 @@ function M.draw(cr, rect, colors)
local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
local label_size = clamp(inner.w * 0.030, 10, 16)
- card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + label_size, 'DISKS')
-
local fs = data.df_parse(data.slurp(CACHE) or '')
if #fs == 0 then
- card.rgba(cr, colors.label)
- card.font(cr, card.FONT_UI, label_size * 1.2, true)
- card.text(cr, inner.x, inner.y + label_size * 3.4, 'no disk data')
- card.font(cr, card.FONT_MONO, label_size, false)
- card.text(cr, inner.x, inner.y + label_size * 5, 'bin/disks-sample.sh')
+ card.notice(cr, inner, colors, 'DISKS', 'no disk data', 'bin/disks-sample.sh')
return
end
+ card.font(cr, card.FONT_MONO, label_size, false)
+ card.rgba(cr, colors.label)
+ card.text(cr, inner.x, inner.y + label_size, 'DISKS')
+
local top = inner.y + label_size * 2.2
local avail_h = (inner.y + inner.h) - top
@@ -100,7 +96,9 @@ function M.draw(cr, rect, colors)
-- The address, inside the ring beneath the glyph. Only the NFS shares
-- have one; the local mounts are identified by their icon alone.
if sub then
- card.font(cr, card.FONT_MONO, clamp(r * 0.20, 9, 12), false)
+ -- Tied to the card's own label scale rather than a fixed px floor, so
+ -- every piece of small mono text on the card tracks the same size.
+ card.font(cr, card.FONT_MONO, clamp(r * 0.20, label_size * 0.7, label_size), false)
card.rgba(cr, colors.label)
local sw_ = card.measure(cr, sub)
card.text(cr, cx - sw_ / 2, cy + r * 0.55, sub)
@@ -129,6 +127,7 @@ function M.draw(cr, rect, colors)
end
else
local step = label_size * 2.6
+ local bar_h = clamp(label_size * 0.5, 4, 8)
local ey = top + label_size
for _, e in ipairs(fs) do
if ey + step > inner.y + inner.h then break end
@@ -143,7 +142,7 @@ function M.draw(cr, rect, colors)
card.rgba(cr, colour)
card.text_right(cr, inner.x + inner.w, ey,
string.format('%s / %s', card.human(e.used), card.human(e.size)))
- card.bar(cr, inner.x, ey + 6, inner.w, 6, e.pct / 100, colour, colors)
+ card.bar(cr, inner.x, ey + label_size * 0.5, inner.w, bar_h, e.pct / 100, colour, colors)
ey = ey + step
end
end
diff --git a/widgets/network.lua b/widgets/network.lua
index e0ff4cb..5d1a8ca 100644
--- a/widgets/network.lua
+++ b/widgets/network.lua
@@ -78,7 +78,7 @@ function M.draw(cr, rect, colors)
-- Fluid type, as every other card does: one base size S drives everything,
-- taken as the smaller of a height budget and a measured width fit.
- local LABEL_F, BIG_F, ROW_F = 0.30, 0.62, 0.30
+ local LABEL_F, BIG_F, ROW_F = 0.30, 1.0, 0.30
local groups = {
{ { 'NET', card.FONT_MONO, LABEL_F }, { '888.8M/s', card.FONT_HEAVY, BIG_F } },
{ { '\u{F0318} 192.000.000.000', card.FONT_MONO, ROW_F } },
diff --git a/widgets/slackware.lua b/widgets/slackware.lua
index 709438d..f9afb70 100644
--- a/widgets/slackware.lua
+++ b/widgets/slackware.lua
@@ -33,26 +33,14 @@ end
function M.draw(cr, rect, colors)
local inner = card.card(cr, rect, colors)
local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
- local LABEL_F, BIG_F, ROW_F = 0.30, 0.85, 0.32
+ local LABEL_F, BIG_F, ROW_F = 0.30, 1.0, 0.32
local kv = data.kv_parse(data.slurp(CACHE) or '')
-- No cache at all: the sampler has not run. Name it, as the cache card does,
-- rather than leaving a blank cell that is indistinguishable from a crash.
if not kv.version then
- local S = clamp(inner.h * 0.94 / (1.78 + 2 * 0.72), 10, 72)
- S = math.min(S, card.fit_unit(cr, inner.w * 0.96, {
- { { 'SLACKWARE', card.FONT_MONO, LABEL_F } },
- { { 'no slackware data', card.FONT_UI, 0.36 } },
- { { 'bin/slackware-sample.sh', card.FONT_MONO, ROW_F } },
- }, 100))
- card.font(cr, card.FONT_MONO, S * LABEL_F, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + S * LABEL_F, 'SLACKWARE')
- card.font(cr, card.FONT_UI, S * 0.36, true)
- card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6, 'no slackware data')
- card.font(cr, card.FONT_MONO, S * ROW_F, false)
- card.text(cr, inner.x, inner.y + S + S * LABEL_F * 2.6 + S * 0.72,
+ card.notice(cr, inner, colors, 'SLACKWARE', 'no slackware data',
'bin/slackware-sample.sh')
return
end
diff --git a/widgets/weather.lua b/widgets/weather.lua
index f50c6f1..a0c7b3a 100644
--- a/widgets/weather.lua
+++ b/widgets/weather.lua
@@ -12,34 +12,28 @@ local M = {}
local CACHE = (os.getenv('XDG_CACHE_HOME') or (os.getenv('HOME') .. '/.cache'))
.. '/udt/weather.json'
--- Draw the card chrome with a message in it. Used for every no-data state, so
--- the dashboard keeps its shape instead of showing an empty cell, which is
--- indistinguishable from a crashed widget.
-local function draw_notice(cr, inner, colors, line1, line2)
- card.font(cr, card.FONT_UI, 15, true)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + 24, line1)
- card.font(cr, card.FONT_MONO, 12, false)
- card.text(cr, inner.x, inner.y + 48, line2)
-end
-
-- The daylight arc: a curve, its baseline, the sun, and the two times.
--
-- The dot is placed by evaluating the curve at t rather than by computing a
-- point on a circle: the curve IS the path, so evaluating it keeps the dot on
-- the arc if the control points are ever adjusted.
local function draw_arc(cr, x, y, w, h, colors, w_data, now)
- local pad = 4
+ -- Every dimension derives from the band, not fixed pixels: the time labels
+ -- take a fraction of the height, the curve's room is what they leave, and the
+ -- dot and edge pad follow the same proportions so the arc composes at any
+ -- size the cell gives it.
+ local label_h = math.max(10, math.min(16, h * 0.16))
+ local pad = math.max(4, w * 0.012)
local x0, x1 = x + pad, x + w - pad
-- Room under the curve for the time labels.
- local base = y + h - 20
- local top = y + 6
+ local base = y + h - label_h * 1.5
+ local top = y + h * 0.08
-- Cubic Bezier control points, chosen so the curve peaks near the middle at
-- about two thirds of the band height.
local p0 = { x0, base }
- local c1 = { x0 + (x1 - x0) * 0.22, top - 10 }
- local c2 = { x1 - (x1 - x0) * 0.22, top - 10 }
+ local c1 = { x0 + (x1 - x0) * 0.22, top - h * 0.14 }
+ local c2 = { x1 - (x1 - x0) * 0.22, top - h * 0.14 }
local p3 = { x1, base }
-- The baseline: the horizon the sun rises from and sets into.
@@ -70,13 +64,13 @@ local function draw_arc(cr, x, y, w, h, colors, w_data, now)
-- At night the dot is parked at an end, so it takes the dim colour: a bright
-- dot sitting on the horizon would read as a sun that is still up.
card.rgba(cr, day and colors.body or colors.label, 1)
- cairo_arc(cr, sx, sy, 5, 0, math.pi * 2)
+ cairo_arc(cr, sx, sy, math.max(3, math.min(9, h * 0.045)), 0, math.pi * 2)
cairo_fill(cr)
-- The times, each behind its own glyph, at the ends of the arc.
- card.font(cr, card.FONT_MONO, 12, false)
+ card.font(cr, card.FONT_MONO, label_h, false)
card.rgba(cr, colors.label)
- local ty = y + h - 2
+ local ty = y + h - label_h * 0.15
card.text(cr, x0, ty,
weather.ICON.sunrise .. ' ' .. os.date('%H:%M', w_data.sunrise))
card.text_right(cr, x1, ty,
@@ -97,12 +91,13 @@ function M.draw(cr, rect, colors)
-- draw (every update_interval), since this whole branch reruns each
-- frame until a fetch succeeds.
local envf = io.open(os.getenv('HOME') .. '/.config/udt/weather.env', 'r')
- if envf then
- envf:close()
- draw_notice(cr, inner, colors, 'no weather data', 'waiting for first fetch')
+ local hint = 'waiting for first fetch'
+ if not envf then
+ hint = 'set ~/.config/udt/weather.env'
else
- draw_notice(cr, inner, colors, 'no weather data', 'set ~/.config/udt/weather.env')
+ envf:close()
end
+ card.notice(cr, inner, colors, 'WEATHER', 'no weather data', hint)
return
end
@@ -194,7 +189,10 @@ function M.draw(cr, rect, colors)
-- This is what lets one widget sit in a 2x2 or a 2x3 cell unchanged.
local bottom = inner.y + inner.h
local arc_y = sy + row_step * 0.6
- local arc_h = math.min(bottom - arc_y, inner.h * 0.34, 240)
+ -- The cap is a proportion of the card's width, not a fixed 240px: an arch
+ -- taller than about 0.6 of its own width reads as a cathedral door rather
+ -- than a day's arc, and the ceiling has to follow a card that is resized.
+ local arc_h = math.min(bottom - arc_y, inner.h * 0.34, inner.w * 0.6)
if arc_h >= 70 then
draw_arc(cr, inner.x, arc_y, inner.w, arc_h, colors, w, now)
end