diff options
Diffstat (limited to 'widgets/breaktimer.lua')
| -rw-r--r-- | widgets/breaktimer.lua | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/widgets/breaktimer.lua b/widgets/breaktimer.lua new file mode 100644 index 0000000..698be80 --- /dev/null +++ b/widgets/breaktimer.lua @@ -0,0 +1,91 @@ +-- Breaktimer: the phase of breaktimer.sh and the time left in it. +-- +-- Everything comes from a cache file written by bin/breaktimer-sample.sh: +-- conky's Lua cannot run a process, so it can neither call `kill -0` to learn +-- whether the daemon is alive nor ask breaktimer.sh itself. The sampler owns +-- that; this card owns only how the state looks. +-- +-- The countdown is the big value, coloured by phase: green for a work block, +-- blue during a micro-pause, purple during a long one, yellow when paused, and +-- the dim label colour when the clock is frozen. That is the same phase-to- +-- colour language the old Waybar module used, mapped onto the palette roles. + +local card = require 'lib.card' +local data = require 'lib.data' + +local CACHE = (os.getenv('XDG_CACHE_HOME') or (os.getenv('HOME') .. '/.cache')) + .. '/udt/breaktimer.txt' + +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 bt = data.breaktimer_parse(data.slurp(CACHE) or '') + + -- No cache at all: the sampler has not run. Name it, as the slackware card + -- does, rather than leaving a blank cell that is indistinguishable from a + -- 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, + 'bin/breaktimer-sample.sh') + return + end + + local rows = { + { 'PHASE', bt.phase_label }, + { 'NEXT', bt.next }, + } + + -- Fluid type: the height budget grows the content to fill the cell, the + -- measured width fit pulls it back where the phase label would overrun. + local groups = { + { { 'BREAKTIMER', card.FONT_MONO, LABEL_F }, + { bt.countdown, card.FONT_HEAVY, BIG_F } }, + } + for _, r in ipairs(rows) do + groups[#groups + 1] = { { r[1], card.FONT_MONO, ROW_F }, + { tostring(r[2]), card.FONT_MONO, ROW_F } } + end + local S = clamp(math.min(inner.h * 0.94 / (1.5 + #rows * 0.66), + card.fit_unit(cr, inner.w * 0.96, groups, 100)), 10, 72) + local label_size = S * LABEL_F + local row_size = S * ROW_F + + card.font(cr, card.FONT_HEAVY, S * BIG_F, false) + card.rgba(cr, colors[bt.role] or colors.value) + card.text_right(cr, inner.x + inner.w, inner.y + S * BIG_F, bt.countdown) + + card.font(cr, card.FONT_MONO, label_size, false) + card.rgba(cr, colors.label) + card.text(cr, inner.x, inner.y + label_size, 'BREAKTIMER') + + local ey = inner.y + S * BIG_F + row_size * 1.6 + local step = row_size * 2.0 + card.font(cr, card.FONT_MONO, row_size, false) + for _, r in ipairs(rows) do + if ey + step > inner.y + inner.h then break end + card.rgba(cr, colors.label) + card.text(cr, inner.x, ey, r[1]) + card.rgba(cr, colors.value) + card.text_right(cr, inner.x + inner.w, ey, tostring(r[2])) + ey = ey + step + end +end + +return M |
