From 3891d424713d11fe4ae1e0d32b60fc66ae53ffdd Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 21 Oct 2021 07:44:34 +1100 Subject: frontend: Beter provision for plugins with multiple menu levels. Make it possible for a plugin to specify which item should be selected on repopulate. Also allowed plugins to specify the UI heading flag for menu items. Updated input macro plugin to select sane items when changing menus. Other plugins not updated yet, but may be at some point in the future. --- plugins/inputmacro/inputmacro_menu.lua | 57 +++++++++++++++++++++++++++++----- src/frontend/mame/luaengine.cpp | 14 +++++---- src/frontend/mame/luaengine.h | 8 ++--- src/frontend/mame/ui/inputmap.cpp | 4 +-- src/frontend/mame/ui/pluginopt.cpp | 20 ++++++++---- 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/plugins/inputmacro/inputmacro_menu.lua b/plugins/inputmacro/inputmacro_menu.lua index 24b963a91e9..8b62148ab67 100644 --- a/plugins/inputmacro/inputmacro_menu.lua +++ b/plugins/inputmacro/inputmacro_menu.lua @@ -8,6 +8,8 @@ local MENU_TYPES = { MACROS = 0, ADD = 1, EDIT = 2, INPUT = 3 } local macros local menu_stack +local macros_start_macro -- really for the macros menu, but has to be declared local before edit menu functions + -- Helpers @@ -46,6 +48,7 @@ end -- Input menu local input_action +local input_start_field local input_choices local input_item_first_choice local input_item_cancel @@ -119,21 +122,29 @@ function populate_input() end input_item_first_choice = #items + 1 + local selection = input_item_first_choice for index, field in ipairs(input_choices) do items[#items + 1] = { _p('input-name', field.name), '', '' } + if input_start_field and (field.port.tag == input_start_field.port.tag) and (field.mask == input_start_field.mask) and (field.type == input_start_field.type) then + selection = #items + input_start_field = nil + end end + input_start_field = nil items[#items + 1] = { '---', '', '' } items[#items + 1] = { _p('plugin-inputmacro', 'Cancel'), '', '' } input_item_cancel = #items - return items + return items, selection end -- Add/edit menus local edit_current_macro +local edit_start_selection +local edit_start_step local edit_insert_position local edit_name_buffer local edit_items @@ -287,6 +298,8 @@ local function handle_edit_items(index, event) inputs[command.input].port = field.port inputs[command.input].field = field end + input_start_field = inputs[command.input].field + edit_start_selection = index table.insert(menu_stack, MENU_TYPES.INPUT) return true elseif event == 'clear' then @@ -304,6 +317,7 @@ local function handle_edit_items(index, event) port = field.port, field = field } end + edit_start_selection = index table.insert(menu_stack, MENU_TYPES.INPUT) return true end @@ -318,6 +332,10 @@ local function handle_edit_items(index, event) if edit_insert_position > command.step then edit_insert_position = edit_insert_position - 1 end + edit_start_step = command.step + if edit_start_step > #edit_current_macro.steps then + edit_start_step = edit_start_step - 1 + end return true end elseif command.action == 'addstep' then @@ -336,8 +354,10 @@ local function handle_edit_items(index, event) if edit_current_macro.loop >= edit_insert_position then edit_current_macro.loop = edit_current_macro.loop + 1 end + edit_start_step = edit_insert_position edit_insert_position = edit_insert_position + 1 end + edit_start_selection = index table.insert(menu_stack, MENU_TYPES.INPUT) return true elseif event == 'left' then @@ -386,11 +406,12 @@ local function add_edit_items(items) edit_items[#items] = { action = 'holdaction' } for i, step in ipairs(edit_current_macro.steps) do - items[#items + 1] = { '---', '', '' } - - items[#items + 1] = { string.format(_p('plugin-inputmacro', 'Step %d'), i), '', 'off' } + items[#items + 1] = { string.format(_p('plugin-inputmacro', 'Step %d'), i), '', 'heading' } items[#items + 1] = { _p('plugin-inputmacro', 'Delay (frames)'), step.delay, (step.delay > 0) and 'lr' or 'r' } edit_items[#items] = { action = 'delay', step = i } + if edit_start_step == i then + edit_start_selection = #items + end items[#items + 1] = { _p('plugin-inputmacro', 'Duration (frames)'), step.duration, (step.duration > 1) and 'lr' or 'r' } edit_items[#items] = { action = 'duration', step = i } @@ -411,6 +432,7 @@ local function add_edit_items(items) edit_items[#items] = { action = 'deletestep', step = i } end end + edit_start_step = nil local laststep = edit_current_macro.steps[#edit_current_macro.steps] if laststep.inputs[#laststep.inputs].field then @@ -438,6 +460,7 @@ local function handle_add(index, event) elseif (index == edit_item_exit) and (event == 'select') then if current_macro_complete() then table.insert(macros, edit_current_macro) + macros_start_macro = #macros end edit_current_macro = nil edit_items = nil @@ -475,7 +498,9 @@ local function populate_add() end edit_item_exit = #items - return items + local selection = edit_start_selection + edit_start_selection = nil + return items, selection end local function populate_edit() @@ -490,13 +515,16 @@ local function populate_edit() items[#items + 1] = { _p('plugin-inputmacro', 'Done'), '', '' } edit_item_exit = #items - return items + local selection = edit_start_selection + edit_start_selection = nil + return items, selection end -- Macros menu local macros_item_first_macro +local macros_selection_save local macros_item_add function handle_macros(index, event) @@ -504,6 +532,8 @@ function handle_macros(index, event) if event == 'select' then edit_current_macro = new_macro() edit_insert_position = #edit_current_macro.steps + 1 + edit_start_selection = 1 -- not actually selectable, but it will take the first item + macros_selection_save = index table.insert(menu_stack, MENU_TYPES.ADD) return true end @@ -512,10 +542,17 @@ function handle_macros(index, event) if event == 'select' then edit_current_macro = macros[macro] edit_insert_position = #edit_current_macro.steps + 1 + macros_selection_save = index table.insert(menu_stack, MENU_TYPES.EDIT) return true elseif event == 'clear' then table.remove(macros, macro) + if #macros > 0 then + macros_selection_save = index + if macro > #macros then + macros_selection_save = macros_selection_save - 1 + end + end return true end end @@ -535,16 +572,22 @@ function populate_macros() if #macros > 0 then for index, macro in ipairs(macros) do items[#items + 1] = { macro.name, input:seq_name(macro.binding), '' } + if macros_start_macro == index then + macros_selection_save = #items + end end else items[#items + 1] = { _p('plugin-inputmacro', 'No macros'), '', 'off' } end + macros_start_macro = nil items[#items + 1] = { '---', '', '' } items[#items + 1] = { _p('plugin-inputmacro', 'Add macro'), '', '' } macros_item_add = #items - return items + local selection = macros_selection_save + macros_selection_save = nil + return items, selection end diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index a76c46fb1d5..9169bdc9f50 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -432,31 +432,33 @@ sol::object lua_engine::call_plugin(const std::string &name, sol::object in) return sol::lua_nil; } -void lua_engine::menu_populate(const std::string &menu, std::vector> &menu_list) +std::optional lua_engine::menu_populate(const std::string &menu, std::vector> &menu_list) { std::string field = "menu_pop_" + menu; sol::object obj = sol().registry()[field]; - if(obj.is()) + if (obj.is()) { auto res = invoke(obj.as()); - if(!res.valid()) + if (!res.valid()) { sol::error err = res; osd_printf_error("[LUA ERROR] in menu_populate: %s\n", err.what()); } else { - sol::table table = res; - for(auto &entry : table) + std::tuple > table = res; + for (auto &entry : std::get<0>(table)) { - if(entry.second.is()) + if (entry.second.is()) { sol::table enttable = entry.second.as(); menu_list.emplace_back(enttable.get(1, 2, 3)); } } + return std::get<1>(table); } } + return std::nullopt; } bool lua_engine::menu_callback(const std::string &menu, int index, const std::string &event) diff --git a/src/frontend/mame/luaengine.h b/src/frontend/mame/luaengine.h index 973dfedfd89..5b945e864c9 100644 --- a/src/frontend/mame/luaengine.h +++ b/src/frontend/mame/luaengine.h @@ -16,13 +16,11 @@ #include #include #include +#include #include +#include #include -#if defined(__GNUC__) && (__GNUC__ > 6) -#pragma GCC diagnostic ignored "-Wnoexcept-type" -#endif - #define SOL_SAFE_USERTYPE 1 #include "sol/sol.hpp" @@ -50,7 +48,7 @@ public: bool frame_hook(); - void menu_populate(const std::string &menu, std::vector> &menu_list); + std::optional menu_populate(const std::string &menu, std::vector> &menu_list); bool menu_callback(const std::string &menu, int index, const std::string &event); void set_machine(running_machine *machine); diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp index 08cbab0facc..5ddf7864adf 100644 --- a/src/frontend/mame/ui/inputmap.cpp +++ b/src/frontend/mame/ui/inputmap.cpp @@ -481,9 +481,9 @@ void menu_input::populate_sorted(float &customtop, float &custombottom) else item_append(menu_item_type::SEPARATOR); if (item.owner->owner()) - item_append(string_format(_("%1$s [root%2$s]"), item.owner->type().fullname(), item.owner->tag()), 0, nullptr); + item_append(string_format(_("%1$s [root%2$s]"), item.owner->type().fullname(), item.owner->tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); else - item_append(string_format(_("[root%1$s]"), item.owner->tag()), 0, nullptr); + item_append(string_format(_("[root%1$s]"), item.owner->tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); prev_owner = item.owner; } diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp index d36503cdcee..e065582103b 100644 --- a/src/frontend/mame/ui/pluginopt.cpp +++ b/src/frontend/mame/ui/pluginopt.cpp @@ -117,7 +117,8 @@ void menu_plugin_opt::handle() void menu_plugin_opt::populate(float &customtop, float &custombottom) { std::vector> menu_list; - mame_machine_manager::instance()->lua()->menu_populate(m_menu, menu_list); + auto const sel = mame_machine_manager::instance()->lua()->menu_populate(m_menu, menu_list); + uintptr_t i = 1; for(auto &item : menu_list) { @@ -126,13 +127,15 @@ void menu_plugin_opt::populate(float &customtop, float &custombottom) const std::string &tflags = std::get<2>(item); uint32_t flags = 0; - if(tflags == "off") + if (tflags == "off") flags = FLAG_DISABLE; - else if(tflags == "l") + else if (tflags == "heading") + flags = FLAG_DISABLE | FLAG_UI_HEADING; + else if (tflags == "l") flags = FLAG_LEFT_ARROW; - else if(tflags == "r") + else if (tflags == "r") flags = FLAG_RIGHT_ARROW; - else if(tflags == "lr") + else if (tflags == "lr") flags = FLAG_RIGHT_ARROW | FLAG_LEFT_ARROW; if(text == "---") @@ -141,9 +144,14 @@ void menu_plugin_opt::populate(float &customtop, float &custombottom) i++; } else - item_append(text, subtext, flags, (void *)i++); + { + item_append(text, subtext, flags, reinterpret_cast(i++)); + } } item_append(menu_item_type::SEPARATOR); + + if (sel) + set_selection(reinterpret_cast(uintptr_t(*sel))); } menu_plugin_opt::~menu_plugin_opt() -- cgit v1.2.3