diff --git a/init.lua b/init.lua index fa4a20c..a94ccd0 100644 --- a/init.lua +++ b/init.lua @@ -69,6 +69,7 @@ local state = (function() menu_open = nil, -- 0.3.0: nil | (e.g. "File") submenu_open = nil, -- 0.3.0: label of the open submenu item within menu_open modal_open = nil, -- 0.3.0: nil | (single-stack) + modal_text_input = "", -- 0.3.0: scratch buffer for modal text inputs show_layers_panel = true, -- 0.3.0: Window > Layers Panel toggle show_palette = true, -- 0.3.0: Window > Palette toggle mouse_cell = nil, -- {x, y} or nil if mouse off-map @@ -148,6 +149,15 @@ local state = (function() function M.close_modal() state.modal_open = nil end function M.get_modal_open() return state.modal_open end + -- 0.3.0: modal text-input buffer accessors + function M.get_modal_input() return state.modal_text_input end + function M.set_modal_input(s) state.modal_text_input = s end + function M.append_modal_input(s) state.modal_text_input = state.modal_text_input .. s end + function M.backspace_modal_input() + local s = state.modal_text_input + state.modal_text_input = s:sub(1, -2) + end + function M.set_menu_open(name) state.menu_open = name end function M.get_menu_open() return state.menu_open end function M.close_menu() @@ -210,6 +220,7 @@ local state = (function() state.menu_open = nil state.submenu_open = nil state.modal_open = nil + state.modal_text_input = "" state.show_layers_panel = true state.show_palette = true state.debug_overlay = false @@ -987,6 +998,129 @@ local ui = (function() end, } + -- 0.3.0: save_as — text input degraded (no poll_char API exposed to Lua); + -- filename is auto-generated as untitled-.map.json on Save. + MODALS.save_as = { + title = "Save As", + w = 360, + h = 140, + render = function(mx, my) + local screen_w, screen_h = engine.window.size() + local x = (screen_w - 360) / 2 + local y = (screen_h - 140) / 2 + engine.render.draw_rect(x, y, 360, 140, rgba(COL_MODAL_BG, 0xF0)) + engine.render.draw_rect_lines(x, y, 360, 140, rgba(COL_MODAL_BORDER, 0xFF)) + engine.render.draw_text("Save As", x + 12, y + 10, 14, rgba(COL_TEXT, 0xFF)) + engine.render.draw_text("Will save as:", + x + 12, y + 40, 11, rgba(COL_TEXT_MUTED, 0xFF)) + local preview = string.format("untitled-%d.map.json", os.time()) + engine.render.draw_rect(x + 12, y + 58, 336, 22, rgba(COL_BUTTON_BG, 0xFF)) + engine.render.draw_text(preview, x + 18, y + 62, 11, rgba(COL_TEXT_MUTED, 0xFF)) + engine.render.draw_rect(x + 200, y + 100, 70, 24, + rgba(COL_BUTTON_BG, 0xFF)) + engine.render.draw_rect_lines(x + 200, y + 100, 70, 24, + rgba(COL_BUTTON_BORDER, 0xFF)) + engine.render.draw_text("Save", x + 220, y + 106, 12, rgba(COL_TEXT, 0xFF)) + engine.render.draw_rect(x + 278, y + 100, 70, 24, + rgba(COL_BUTTON_BG, 0xFF)) + engine.render.draw_rect_lines(x + 278, y + 100, 70, 24, + rgba(COL_BUTTON_BORDER, 0xFF)) + engine.render.draw_text("Cancel", x + 292, y + 106, 12, rgba(COL_TEXT, 0xFF)) + end, + on_click = function(mx, my, button) + local screen_w, screen_h = engine.window.size() + local x = (screen_w - 360) / 2 + local y = (screen_h - 140) / 2 + if in_rect(mx, my, x + 200, y + 100, 70, 24) then + local name = string.format("untitled-%d.map.json", os.time()) + maps.save_to_disk(state.get_map_id(), "maps/" .. name) + return true + end + if in_rect(mx, my, x + 278, y + 100, 70, 24) then + return true + end + return false + end, + } + + -- 0.3.0: map_properties — read-only inspector (map id, size, atlas list). + MODALS.map_properties = { + title = "Map Properties", + w = 420, + h = 320, + render = function(mx, my) + local screen_w, screen_h = engine.window.size() + local x = (screen_w - 420) / 2 + local y = (screen_h - 320) / 2 + engine.render.draw_rect(x, y, 420, 320, rgba(COL_MODAL_BG, 0xF0)) + engine.render.draw_rect_lines(x, y, 420, 320, rgba(COL_MODAL_BORDER, 0xFF)) + engine.render.draw_text("Map Properties", x + 12, y + 10, 14, + rgba(COL_TEXT, 0xFF)) + local id = state.get_map_id() or "(none)" + engine.render.draw_text("ID: " .. id, x + 12, y + 40, 11, + rgba(COL_TEXT, 0xFF)) + local sz = maps.size() + local size_str = sz and (sz.w .. " x " .. sz.h) or "(unknown)" + engine.render.draw_text("Size: " .. size_str, x + 12, y + 60, 11, + rgba(COL_TEXT, 0xFF)) + local ac = maps.atlas_count() or 0 + engine.render.draw_text("Atlases: " .. tostring(ac), + x + 12, y + 80, 11, rgba(COL_TEXT, 0xFF)) + for i = 0, ac - 1 do + engine.render.draw_text(" [" .. i .. "] " .. (maps.atlas_id_at(i) or "?"), + x + 12, y + 100 + i * 16, 11, rgba(COL_TEXT_MUTED, 0xFF)) + end + engine.render.draw_rect(x + 340, y + 280, 70, 24, + rgba(COL_BUTTON_BG, 0xFF)) + engine.render.draw_rect_lines(x + 340, y + 280, 70, 24, + rgba(COL_BUTTON_BORDER, 0xFF)) + engine.render.draw_text("Close", x + 358, y + 286, 12, rgba(COL_TEXT, 0xFF)) + end, + on_click = function(mx, my, button) + local screen_w, screen_h = engine.window.size() + local x = (screen_w - 420) / 2 + local y = (screen_h - 320) / 2 + if in_rect(mx, my, x + 340, y + 280, 70, 24) then + return true + end + return false + end, + } + + -- 0.3.0: about — static text only. + MODALS.about = { + title = "About", + w = 320, + h = 200, + render = function(mx, my) + local screen_w, screen_h = engine.window.size() + local x = (screen_w - 320) / 2 + local y = (screen_h - 200) / 2 + engine.render.draw_rect(x, y, 320, 200, rgba(COL_MODAL_BG, 0xF0)) + engine.render.draw_rect_lines(x, y, 320, 200, rgba(COL_MODAL_BORDER, 0xFF)) + engine.render.draw_text("Sporel Map Editor", + x + 12, y + 14, 14, rgba(COL_TEXT, 0xFF)) + engine.render.draw_text("Module: map-editor v0.3.0", + x + 12, y + 44, 11, rgba(COL_TEXT, 0xFF)) + engine.render.draw_text("Maps lib: lib-core.maps v0.5.6", + x + 12, y + 62, 11, rgba(COL_TEXT, 0xFF)) + engine.render.draw_rect(x + 240, y + 160, 70, 24, + rgba(COL_BUTTON_BG, 0xFF)) + engine.render.draw_rect_lines(x + 240, y + 160, 70, 24, + rgba(COL_BUTTON_BORDER, 0xFF)) + engine.render.draw_text("Close", x + 258, y + 166, 12, rgba(COL_TEXT, 0xFF)) + end, + on_click = function(mx, my, button) + local screen_w, screen_h = engine.window.size() + local x = (screen_w - 320) / 2 + local y = (screen_h - 200) / 2 + if in_rect(mx, my, x + 240, y + 160, 70, 24) then + return true + end + return false + end, + } + -- ===================================================================== -- Drawing -- =====================================================================