diff options
Diffstat (limited to 'widgets/weather.lua')
| -rw-r--r-- | widgets/weather.lua | 46 |
1 files changed, 22 insertions, 24 deletions
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 |
