feat(map-editor): dropdown click dispatch

Routes clicks on dropdown items to their per-type handler:
action.fire, open_modal for modal items, toggle.fire for toggles.
Disabled items absorb without closing; separators are inert.
Clicks outside the open dropdown close the menu and fall through to
canvas handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Calic
2026-06-01 19:51:58 +02:00
parent 2c3015685c
commit b5afe35df8

View File

@@ -698,6 +698,23 @@ local ui = (function()
end end
end end
local function fire_item(it)
if item_is_disabled(it) then return false end -- absorbed, no close
if it.type == "action" then
if it.fire then it.fire() end
return true -- close menu
elseif it.type == "modal" then
if it.modal_id then state.open_modal(it.modal_id) end
return true
elseif it.type == "toggle" then
if it.fire then it.fire() end
return true
elseif it.type == "submenu" then
return false -- handled separately
end
return false
end
local function draw_menu_bar(mx, my) local function draw_menu_bar(mx, my)
local screen_w = engine.window.size() local screen_w = engine.window.size()
engine.render.draw_rect(0, 0, screen_w, MENU_BAR_H, rgba(COL_TOOLBAR_BG, 0xFF)) engine.render.draw_rect(0, 0, screen_w, MENU_BAR_H, rgba(COL_TOOLBAR_BG, 0xFF))
@@ -1116,10 +1133,33 @@ local ui = (function()
end end
end end
-- Click anywhere outside the menu bar closes any open dropdown -- Dropdown items
if state.get_menu_open() and my >= MENU_BAR_H then local open_name = state.get_menu_open()
if open_name then
for _, cat in ipairs(menu_bar_categories_layout()) do
if cat.name == open_name then
local dd = dropdown_layout(cat)
if in_rect(mx, my, dd.x, dd.y, dd.w, dd.h) then
if button == "left" then
for _, row in ipairs(dd.rows) do
if in_rect(mx, my, row.x, row.y, row.w, row.h) then
if row.item.type ~= "separator" then
if fire_item(row.item) then
state.close_menu()
end
end
return true
end
end
end
return true -- empty area inside dropdown, absorbed
end
break
end
end
-- Click outside the dropdown closes it (no return — fall through so
-- the click can also hit other UI like canvas).
state.close_menu() state.close_menu()
-- Fall through (do not return) so the click can hit something else.
end end
-- Top toolbar buttons -- Top toolbar buttons