-- icons.lua — inline status-icon primitives for the launcher. -- -- The engine ships text + rect bindings; no sprites, no draw_circle yet, -- so every icon is composed from draw_rect + draw_text. Each helper -- returns the rect it occupied so the caller can stash it for hit-tests -- (tooltip + update-badge click). local M = {} M.SPINNER_COLOR = 0xC0C0C0FF M.WARN_COLOR = 0xFFD000FF M.UPDATE_COLOR = 0x4090FFFF M.ERROR_COLOR = 0xFF4040FF M.LOCAL_COLOR = 0x707070FF -- muted gray for "local-only" repos M.ICON_W = 16 M.ICON_H = 16 local SPINNER_GLYPHS = { "|", "/", "-", "\\" } -- Spinner: rotating ASCII glyph cycled at ~7.5 Hz at 60 fps (every 8 -- frames). Returns its bounding rect so the caller can hit-test for -- tooltip ("checking for updates..."). function M.draw_spinner(x, y, frame) local glyph = SPINNER_GLYPHS[(math.floor(frame / 8) % 4) + 1] engine.render.draw_text(glyph, x + 4, y, 12, M.SPINNER_COLOR) return { x = x, y = y, w = M.ICON_W, h = M.ICON_H } end -- Warn: yellow square with "!" centered. function M.draw_warn(x, y) engine.render.draw_rect(x, y, M.ICON_W, M.ICON_H, M.WARN_COLOR) engine.render.draw_text("!", x + 5, y, 14, 0x000000FF) return { x = x, y = y, w = M.ICON_W, h = M.ICON_H } end -- Update badge: blue pill "^v0.5.5". Width depends on the version -- string; returned rect carries the dynamic width so callers can do -- right-to-left layout and click-hit-tests. function M.draw_update_badge(x, y, version_str) local label = "^" .. version_str local tw, _ = engine.render.measure_text(label, 12) local w = tw + 10 engine.render.draw_rect(x, y, w, M.ICON_H, M.UPDATE_COLOR) engine.render.draw_text(label, x + 5, y + 1, 12, 0xFFFFFFFF) return { x = x, y = y, w = w, h = M.ICON_H } end -- Error: red square with white "!" — same shape as warn but different -- color so colorblind users still see the shape difference via the -- background tint contrast. function M.draw_error(x, y) engine.render.draw_rect(x, y, M.ICON_W, M.ICON_H, M.ERROR_COLOR) engine.render.draw_text("!", x + 5, y, 14, 0xFFFFFFFF) return { x = x, y = y, w = M.ICON_W, h = M.ICON_H } end -- Local-only: muted-gray pill with "L" — module exists in the local -- install but the remote returns 404 even with credentials, so the -- update channel doesn't apply. Informational, not a warning. function M.draw_local(x, y) engine.render.draw_rect(x, y, M.ICON_W, M.ICON_H, M.LOCAL_COLOR) engine.render.draw_text("L", x + 5, y, 12, 0xFFFFFFFF) return { x = x, y = y, w = M.ICON_W, h = M.ICON_H } end -- Tooltip: small dark panel anchored to the right of (mx, my). -- Centered vertically on the cursor. Clamped to screen via the -- screen-size args. function M.draw_tooltip(mx, my, text, screen_w, screen_h) if not text or text == "" then return end local tw, th = engine.render.measure_text(text, 12) local pad_x, pad_y = 6, 3 local w, h = tw + 2 * pad_x, th + 2 * pad_y local x = mx + 14 local y = my - h / 2 if x + w > screen_w then x = mx - w - 8 end if y < 0 then y = 0 end if y + h > screen_h then y = screen_h - h end engine.render.draw_rect(x, y, w, h, 0x202020E0) engine.render.draw_text(text, x + pad_x, y + pad_y, 12, 0xFFFFFFFF) end return M