1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
-- 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
|