feat(launcher): launch button + dep-conflict modal
Detail-panel bottom-right Launch button: switches to the selected module via engine.switch_module if dep-check is clean, otherwise opens a modal listing conflicts with Cancel + 'Launch anyway'. The latter is greyed out unless engine.module.switch_module_supports_fallback is exposed (separate engine slice). FSM adds STATE_MODAL_CONFLICT with transitions to/from STATE_LIST via cancel/launch_anyway/esc. Generic panels/modal.lua takes a def-table (title/body/buttons) and returns the clicked button id from handle_click; reusable for future modals beyond the conflict case.
This commit is contained in:
30
init.lua
30
init.lua
@@ -15,6 +15,7 @@ end
|
||||
local list_panel = require_panel("list")
|
||||
local detail_panel = require_panel("detail")
|
||||
local carousel = require_panel("carousel")
|
||||
local modal_panel = require_panel("modal")
|
||||
|
||||
local STATE_LIST, STATE_QUIT, EXIT = fsm.STATE_LIST, fsm.STATE_QUIT_CONFIRM, fsm.EXIT
|
||||
local state = STATE_LIST
|
||||
@@ -339,6 +340,30 @@ function update(ctx, dt)
|
||||
|
||||
local mx, my = engine.input.get_mouse_pos()
|
||||
|
||||
-- L.7: Conflict-modal takes priority over STATE_LIST input. esc /
|
||||
-- Cancel close the modal back to STATE_LIST; "Launch anyway" stays
|
||||
-- a no-op until engine.module.switch_module_supports_fallback ships.
|
||||
if ctx_panels.modal_open == "conflict" then
|
||||
if input.was_action_pressed("ui_back") then
|
||||
ctx_panels.modal_open = nil
|
||||
state = fsm.next(state, "esc")
|
||||
elseif input.was_action_pressed("ui_click") then
|
||||
local id = modal_panel.handle_click(ctx_panels.modal_def, mx, my)
|
||||
if id == "cancel" then
|
||||
ctx_panels.modal_open = nil
|
||||
state = fsm.next(state, "cancel")
|
||||
elseif id == "launch_anyway" then
|
||||
local mid = ctx_panels.modal_def.module_id
|
||||
ctx_panels.modal_open = nil
|
||||
state = fsm.next(state, "launch_anyway")
|
||||
if engine.module.switch_module_supports_fallback then
|
||||
engine.switch_module(mid, { mode = "fallback" })
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if state == STATE_LIST then
|
||||
if input.was_action_pressed("ui_back") then
|
||||
state = fsm.next(state, "esc")
|
||||
@@ -370,6 +395,11 @@ function render(ctx)
|
||||
list_panel.render(ctx_panels)
|
||||
detail_panel.render(ctx_panels)
|
||||
|
||||
-- L.7: Conflict modal renders above the panels (backdrop dims them).
|
||||
if ctx_panels.modal_open == "conflict" then
|
||||
modal_panel.render(ctx_panels.modal_def, screen_w, screen_h)
|
||||
end
|
||||
|
||||
if state == STATE_QUIT then
|
||||
engine.render.draw_rect(0, 0, screen_w, screen_h, COLOR_DIM)
|
||||
local modal_w, modal_h = 360, 140
|
||||
|
||||
Reference in New Issue
Block a user