diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-17 09:16:58 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-17 09:16:58 +0200 |
| commit | af64aed9b49c727d6b4050f3534115cead314f1d (patch) | |
| tree | f085ad2769bd1583e85b941c43dd13d362f0b89c | |
| parent | 2bdb74a1cbd4b33216d94713de1f1b3c81f631e2 (diff) | |
| download | conky-theme-udt-af64aed9b49c727d6b4050f3534115cead314f1d.tar.gz conky-theme-udt-af64aed9b49c727d6b4050f3534115cead314f1d.zip | |
fix: size the weather card to its content
The first draft placed every band at a fixed pixel offset and let the
arc absorb whatever height was left. In a 1x2 cell on this monitor that
is 794px of arc: a cathedral arch under a fifth of a card of content,
nothing like the mockup it was shaped after.
Three changes, all visible in an offscreen render of the real widget:
- Type sizes and band offsets scale with the rect, within clamps, so the
proportions hold on the 1920 monitor as well as this one.
- The arc gets a bounded band that follows the stats instead of being
pinned to the bottom, so no dead strip opens between them.
- The layout gives the widget a 1x1 cell. Its content is about 350px
tall and a full-height cell cannot be filled without inventing data.
Found before restarting conky by loading conky's own cairo bindings
standalone and rendering the widget to a PNG, which is a far tighter
loop than install, restart, switch workspace, screenshot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| -rw-r--r-- | dashboard.lua | 5 | ||||
| -rw-r--r-- | docs/superpowers/plans/2026-09-17-weather-widget.md | 11 | ||||
| -rw-r--r-- | widgets/weather.lua | 62 |
3 files changed, 57 insertions, 21 deletions
diff --git a/dashboard.lua b/dashboard.lua index dfd19ff..f5e74f3 100644 --- a/dashboard.lua +++ b/dashboard.lua @@ -20,7 +20,10 @@ local COLS, ROWS = 4, 2 local layout = { { widget = 'clock', col = 1, row = 1, w = 1, h = 2 }, - { widget = 'weather', col = 2, row = 1, w = 1, h = 2 }, + -- 1x1, not 1x2: the card's content is about 350px tall, so a full-height + -- cell left a dead band down its middle. A single-row cell is as tall as + -- what it holds. + { widget = 'weather', col = 2, row = 1, w = 1, h = 1 }, } -- ========================================================================== diff --git a/docs/superpowers/plans/2026-09-17-weather-widget.md b/docs/superpowers/plans/2026-09-17-weather-widget.md index 01cd767..14bf11f 100644 --- a/docs/superpowers/plans/2026-09-17-weather-widget.md +++ b/docs/superpowers/plans/2026-09-17-weather-widget.md @@ -1065,7 +1065,10 @@ In `dashboard.lua`, replace the `layout` table: ```lua local layout = { { widget = 'clock', col = 1, row = 1, w = 1, h = 2 }, - { widget = 'weather', col = 2, row = 1, w = 1, h = 2 }, + -- 1x1, not 1x2: the card's content is about 350px tall, so a full-height + -- cell left a dead band down its middle. A single-row cell is as tall as + -- what it holds. + { widget = 'weather', col = 2, row = 1, w = 1, h = 1 }, } ``` @@ -1182,7 +1185,11 @@ with a dot between the two times. Compare against `idea1.png`. Likely first-pass problems, each fixed in `widgets/weather.lua` and re-screenshotted: - Text overflowing the card's right edge: reduce the font size or shorten the label. -- The arc cramped or overlapping the stats: adjust the `ry2 + 10` offset. +- The arc cramped or overlapping the stats: adjust the offsets in `draw()`. +- Proportions wrong in the other direction, which is what actually happened: + the first draft let the arc absorb all leftover height and drew a 794px + arch. The widget now scales its type to the rect and bounds the arc band, + and the layout gives it a 1x1 cell. - The sun dot off the curve: the Bezier evaluation and the drawn curve have diverged, which means the control points differ between them. diff --git a/widgets/weather.lua b/widgets/weather.lua index 8a3b72d..9431b0c 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -106,36 +106,54 @@ function M.draw(cr, rect, colors) return end + -- The card is much taller than idea1's, so the bands are placed against the + -- rect rather than at fixed offsets: content sits in a block at the top, the + -- arc gets a bounded band pinned to the bottom, and the slack falls between + -- them. Letting the arc take all the leftover height instead drew a 794px + -- cathedral arch on this monitor, with the content crammed into the top + -- fifth. Scaled, not fixed, so the 1920 monitor gets the same proportions. local y = inner.y + -- Type sizes scale with the card, within limits that keep them legible on a + -- small cell and stop them ballooning on a tall one. + local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end + local temp_size = clamp(inner.h * 0.075, 34, 60) + local glyph_size = clamp(temp_size * 0.80, 26, 46) + local label_size = clamp(inner.h * 0.014, 10, 14) + local desc_size = clamp(inner.h * 0.017, 12, 17) + local row_size = clamp(inner.h * 0.016, 11, 15) + local row_step = row_size * 1.9 + -- Header: condition glyph, then the temperature with the city beneath it. local glyph = weather.icon(w.id, now, w.sunrise, w.sunset) - card.font(cr, card.FONT_MONO, 36, false) + card.font(cr, card.FONT_MONO, glyph_size, false) card.rgba(cr, colors.highlight) - card.text(cr, inner.x, y + 34, glyph) - local gx = inner.x + card.advance(cr, glyph) + 14 + local gy = y + glyph_size * 0.95 + card.text(cr, inner.x, gy, glyph) + local gx = inner.x + card.advance(cr, glyph) + glyph_size * 0.4 - card.font(cr, card.FONT_HEAVY, 44, false) + card.font(cr, card.FONT_HEAVY, temp_size, false) card.rgba(cr, colors.body) - card.text(cr, gx, y + 38, string.format('%d\u{00B0}', math.floor(w.temp + 0.5))) + card.text(cr, gx, y + temp_size * 0.86, string.format('%d\u{00B0}', math.floor(w.temp + 0.5))) - card.font(cr, card.FONT_MONO, 11, false) + card.font(cr, card.FONT_MONO, label_size, false) card.rgba(cr, colors.label) local city = (w.city or ''):upper() if weather.is_stale(w.dt, now) then city = city .. ' stale ' .. weather.age_str(w.dt, now) end - card.text(cr, gx, y + 56, city) + card.text(cr, gx, y + temp_size * 1.28, city) -- Condition, in OWM's own words, first letter capitalised. - card.font(cr, card.FONT_UI, 13, false) + card.font(cr, card.FONT_UI, desc_size, false) card.rgba(cr, colors.body) local desc = w.description or '' desc = desc:sub(1, 1):upper() .. desc:sub(2) - card.text(cr, inner.x, y + 84, desc) + local dy = y + temp_size * 1.95 + card.text(cr, inner.x, dy, desc) -- Rule. - local ry = y + 100 + local ry = dy + desc_size * 1.4 card.rgba(cr, colors.rule, 0.8) cairo_set_line_width(cr, 1) cairo_move_to(cr, inner.x, ry) @@ -152,26 +170,34 @@ function M.draw(cr, rect, colors) { 'HUMIDITY', w.humidity and (w.humidity .. '%') or '--' }, { 'WIND', wind_txt }, } - local sy = ry + 22 + local sy = ry + row_step for _, row in ipairs(rows) do - card.font(cr, card.FONT_MONO, 11, false) + card.font(cr, card.FONT_MONO, row_size, false) card.rgba(cr, colors.label) card.text(cr, inner.x, sy, row[1]) card.rgba(cr, colors.value) card.text_right(cr, inner.x + inner.w, sy, row[2]) - sy = sy + 20 + sy = sy + row_step end - -- Rule. - local ry2 = sy + 2 + -- The arc follows the stats rather than being pinned to the bottom, and + -- takes the smaller of its natural height and whatever remains. Pinning it + -- low left a dead band between the stats and the curve; the layout gives + -- this widget a cell sized to its content, so the drawing should end where + -- the content does. + local bottom = inner.y + inner.h + local arc_h = clamp(inner.h * 0.30, 90, 190) + local arc_y = math.min(sy + row_step * 0.6, bottom - arc_h) + + -- Rule above the arc, riding with it rather than with the stats: it reads as + -- the arc band's top edge, and the gap left by a tall card falls here. + local ry2 = arc_y - 14 card.rgba(cr, colors.rule, 0.8) cairo_move_to(cr, inner.x, ry2) cairo_line_to(cr, inner.x + inner.w, ry2) cairo_stroke(cr) - -- The arc fills whatever height is left. - draw_arc(cr, inner.x, ry2 + 10, inner.w, (inner.y + inner.h) - (ry2 + 10), - colors, w, now) + draw_arc(cr, inner.x, arc_y, inner.w, arc_h, colors, w, now) end return M |
