feat: close button (X) in panel title bar

Renders an X glyph in the top-right of every panel's title bar; left-
click on it calls M.close(). Hit-test in _dispatch_event runs before
the widget-forward path so the click is consumed by the panel-frame
even when a widget would otherwise handle it. Pairs with the existing
ESC-close-pattern that lives at module level.
This commit is contained in:
Calic
2026-06-14 02:39:04 +02:00
parent b7b0ecb9f4
commit 9ed60d3877

View File

@@ -141,7 +141,35 @@ end
--- _dispatch_event(event): route a synthetic or real input event.
--- event = {kind="click", x, y, button="left"|"right"} or {kind="wheel", dy}
-- Close-button rect in the top-right of the title bar. Same math is used
-- by render() (draw the × glyph) and _dispatch_event (hit-test left-click).
local function close_button_rect(panel_x, panel_y, panel_w, padding, font_size_title)
local size = font_size_title + padding
return {
x = panel_x + panel_w - size - padding,
y = panel_y + padding,
w = size,
h = size,
}
end
local function _dispatch_event(event)
-- Close-button intercept (top-right ×): left-click closes the active panel
-- before the click is forwarded to the widget or context-menu.
if active and event.kind == "click" and event.button == "left" then
local screen_w, screen_h = get_screen_size()
local panel_w = screen_w * theme.panel_width_frac
local panel_h = screen_h * theme.panel_height_frac
local panel_x = (screen_w - panel_w) / 2
local panel_y = (screen_h - panel_h) / 2
local cb = close_button_rect(panel_x, panel_y, panel_w, theme.padding, theme.font_size_title)
if event.x >= cb.x and event.x < cb.x + cb.w
and event.y >= cb.y and event.y < cb.y + cb.h then
M.close()
return
end
end
-- Context-menu intercept: any click is consumed by the menu.
if ctx_menu and event.kind == "click" then
-- Hit-test rows
@@ -475,6 +503,14 @@ function M.render()
theme.font_size_title,
theme.text_color)
-- Close button (×) in top-right of title bar. Hit-tested in _dispatch_event.
local cb = close_button_rect(panel_x, panel_y, panel_w, padding, theme.font_size_title)
engine.render.draw_text("X",
cb.x + math.floor(cb.w / 4),
cb.y,
theme.font_size_title,
theme.text_color)
-- Content area (below title bar)
local title_area_h = theme.font_size_title + padding * 2
local content_bounds = {