aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-18 14:36:07 +0200
committerDanilo M. <danix@danix.xyz>2026-10-18 14:36:07 +0200
commitb492fbb4011cc7890b6b218553809e247f506b71 (patch)
tree056bd7b01b2a09368f15d028c1e1c41d67a33171 /widgets
parentc72ee8bce374294eca0c14c3f0db142fad40c360 (diff)
downloadconky-theme-udt-b492fbb4011cc7890b6b218553809e247f506b71.tar.gz
conky-theme-udt-b492fbb4011cc7890b6b218553809e247f506b71.zip
feat(sky): sun, moon and daylight-arc card adapted from Conky-Mirage
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Diffstat (limited to 'widgets')
-rw-r--r--widgets/sky.lua85
1 files changed, 85 insertions, 0 deletions
diff --git a/widgets/sky.lua b/widgets/sky.lua
new file mode 100644
index 0000000..aa0ad43
--- /dev/null
+++ b/widgets/sky.lua
@@ -0,0 +1,85 @@
+-- Sky: sunrise, sunset, day length and the moon, over the daylight arc.
+--
+-- Adapted from the Conky-Mirage theme's sky tile by alexsson-xexpanderx
+-- (see lib/weather.lua). The arc is the one the old weather card drew, minus
+-- its time labels: the rows carry the times now.
+
+local card = require 'lib.card'
+local data = require 'lib.data'
+local weather = require 'lib.weather'
+
+local M = {}
+
+-- 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, rise, set, now)
+ local pad = math.max(4, w * 0.012)
+ local x0, x1 = x + pad, x + w - pad
+ local base = y + h - pad
+ local top = y + h * 0.08
+
+ -- Cubic Bezier control points, chosen so the curve peaks near the middle.
+ local p0 = { x0, base }
+ 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 horizon the sun rises from and sets into.
+ card.rgba(cr, colors.rule, 0.6)
+ cairo_set_line_width(cr, 1)
+ cairo_move_to(cr, x0, base)
+ cairo_line_to(cr, x1, base)
+ cairo_stroke(cr)
+
+ card.rgba(cr, colors.rule, 0.9)
+ cairo_set_line_width(cr, 1.5)
+ cairo_move_to(cr, p0[1], p0[2])
+ cairo_curve_to(cr, c1[1], c1[2], c2[1], c2[2], p3[1], p3[2])
+ cairo_stroke(cr)
+
+ local t = weather.sun_t(now, rise, set) or 0
+ local function bez(a, b, c, d)
+ local u = 1 - t
+ return u * u * u * a + 3 * u * u * t * b + 3 * u * t * t * c + t * t * t * d
+ end
+ -- At night the dot is parked at an end, so it takes the dim colour: a bright
+ -- dot on the horizon would read as a sun that is still up.
+ card.rgba(cr, weather.is_day(now, rise, set) and colors.body or colors.label)
+ cairo_new_path(cr)
+ cairo_arc(cr, bez(p0[1], c1[1], c2[1], p3[1]), bez(p0[2], c1[2], c2[2], p3[2]),
+ math.max(3, math.min(9, h * 0.045)), 0, math.pi * 2)
+ cairo_fill(cr)
+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, 'SKY', 'no weather data', 'bin/weather-fetch.sh')
+ return
+ end
+
+ local now = os.time()
+ local rise, set = w.sun.rise, w.sun.set
+ local phase, lit = weather.moon(now)
+ local rows = {
+ { 'SUNRISE', os.date('%H:%M', rise) },
+ { 'SUNSET', os.date('%H:%M', set) },
+ { 'DAYLIGHT', weather.duration(set - rise) },
+ { 'MOON', weather.num(lit * 100, '%') },
+ }
+ local y = card.standard(cr, inner, colors, {
+ icon = card.ICON.sky, title = 'SKY',
+ big = weather.moon_icon(phase), big_font = card.FONT_MONO,
+ big_color = colors.heading, rows = rows, share = 0.65,
+ })
+
+ -- An arch taller than about 0.6 of its width reads as a door, not a day.
+ local arc_h = math.min(inner.y + inner.h - y, inner.w * 0.6)
+ if arc_h >= 50 then
+ draw_arc(cr, inner.x, inner.y + inner.h - arc_h, inner.w, arc_h, colors, rise, set, now)
+ end
+end
+
+return M