-- 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 and d.max then lo, hi = math.min(lo, d.min, d.max), math.max(hi, d.min, 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) local name = weather.clock(d.t, '%a') card.text(cr, x, by, i == 1 and 'TODAY' or (name == '--' and name or name:upper())) card.rgba(cr, colors.highlight) card.font(cr, card.FONT_MONO, size * 1.4, false) card.text(cr, gx, by, weather.icon(d.code, true)) card.font(cr, card.FONT_MONO, size, false) 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