From 1352c9b06d497bc2a342a4d7acbbef9fbfcd6767 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sun, 18 Oct 2026 14:34:04 +0200 Subject: feat(week): seven-day range-bar card adapted from Conky-Mirage Co-Authored-By: Claude Sonnet 5.5 --- widgets/week.lua | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 widgets/week.lua (limited to 'widgets') diff --git a/widgets/week.lua b/widgets/week.lua new file mode 100644 index 0000000..262121f --- /dev/null +++ b/widgets/week.lua @@ -0,0 +1,74 @@ +-- Week: seven days of glyph and min-to-max range bar. +-- +-- Adapted from the Conky-Mirage theme's week tile by alexsson-xexpanderx +-- (see lib/weather.lua). Each bar sits on the week's overall min..max scale, +-- so a warm day reads as a bar further right, not just a longer one. + +local card = require 'lib.card' +local data = require 'lib.data' +local weather = require 'lib.weather' + +local M = {} + +local function draw_days(cr, x, y, w, h, colors, days, S) + local n = #days + if n == 0 then return end + local step = h / n + local size = math.min(S * 0.32, step * 0.55) + if size < 8 then return end + + local lo, hi = math.huge, -math.huge + for _, d in ipairs(days) do + if d.min then lo = math.min(lo, d.min) end + if d.max then hi = math.max(hi, d.max) end + end + local span = (hi > lo) and (hi - lo) or 1 + -- Columns as fractions of the width: day | glyph | min | bar | max. + local gx, minx = x + w * 0.20, x + w * 0.42 + local bx0, bx1 = x + w * 0.46, x + w * 0.84 + local function bx(t) return bx0 + (bx1 - bx0) * (t - lo) / span end + + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND) + for i, d in ipairs(days) do + local by = y + step * (i - 0.5) + size * 0.35 -- baseline, centred in the row + card.font(cr, card.FONT_MONO, size, false) + card.rgba(cr, colors.label) + card.text(cr, x, by, i == 1 and 'TODAY' + or (d.t and os.date('%a', d.t):upper() or '--')) + card.rgba(cr, colors.highlight) + card.text(cr, gx, by, weather.icon(d.code, true)) + card.rgba(cr, colors.value) + card.text_right(cr, minx, by, weather.deg(d.min)) + card.text_right(cr, x + w, by, weather.deg(d.max)) + + -- The track spans the week; the fill is this day. + local my = by - size * 0.35 + cairo_set_line_width(cr, size * 0.35) + card.rgba(cr, colors.rule, 0.35) + cairo_move_to(cr, bx0, my) + cairo_line_to(cr, bx1, my) + cairo_stroke(cr) + if d.min and d.max then + card.rgba(cr, colors.highlight) + cairo_move_to(cr, bx(d.min), my) + cairo_line_to(cr, bx(d.max), my) + cairo_stroke(cr) + end + end + cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT) +end + +function M.draw(cr, rect, colors) + local inner = card.card(cr, rect, colors) + local w = weather.parse(data.slurp(weather.CACHE)) + if not w then + card.notice(cr, inner, colors, 'WEEK', 'no weather data', 'bin/weather-fetch.sh') + return + end + local y, S = card.standard(cr, inner, colors, { + icon = card.ICON.week, title = 'WEEK', share = 0.25, + }) + draw_days(cr, inner.x, y, inner.w, inner.y + inner.h - y, colors, w.days, S) +end + +return M -- cgit v1.2.3