From 65aeb63a2a1f4f65a6fa0dedabba1b852a189f96 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 24 Feb 2023 19:31:12 +1100 Subject: [PATCH] Update accumulating relative inputs exactly once per frame. This fixes "amplification" effects that would happen if the frame rate rose above 100 Hz (whether by unthrottling or otherwise). Synchronise with wall clock any time inputs are read. Not doing this has weird effects on relative inputs with frame skipping and contributes to unresponsiveness of menus. Reduce visual latency for mouse movement on menus when paused or skipping frames. The rest of the code changes to menus won't provide benefits until draw can happen after event handling. --- language/Vietnamese/strings.po | 18 +- src/emu/main.h | 2 +- src/emu/video.cpp | 10 +- src/frontend/mame/mame.cpp | 4 +- src/frontend/mame/ui/about.cpp | 6 +- src/frontend/mame/ui/about.h | 2 +- src/frontend/mame/ui/analogipt.cpp | 275 +++++++------ src/frontend/mame/ui/analogipt.h | 2 +- src/frontend/mame/ui/auditmenu.cpp | 7 +- src/frontend/mame/ui/auditmenu.h | 2 +- src/frontend/mame/ui/barcode.cpp | 106 ++--- src/frontend/mame/ui/barcode.h | 8 +- src/frontend/mame/ui/cheatopt.cpp | 135 +++---- src/frontend/mame/ui/cheatopt.h | 2 +- src/frontend/mame/ui/confswitch.cpp | 191 ++++----- src/frontend/mame/ui/confswitch.h | 2 +- src/frontend/mame/ui/custui.cpp | 487 ++++++++++++----------- src/frontend/mame/ui/custui.h | 15 +- src/frontend/mame/ui/datmenu.cpp | 46 ++- src/frontend/mame/ui/datmenu.h | 2 +- src/frontend/mame/ui/devctrl.h | 10 +- src/frontend/mame/ui/devopt.cpp | 6 +- src/frontend/mame/ui/devopt.h | 2 +- src/frontend/mame/ui/dirmenu.cpp | 163 ++++---- src/frontend/mame/ui/dirmenu.h | 2 +- src/frontend/mame/ui/filecreate.cpp | 110 ++--- src/frontend/mame/ui/filecreate.h | 12 +- src/frontend/mame/ui/filemngr.cpp | 43 +- src/frontend/mame/ui/filemngr.h | 2 +- src/frontend/mame/ui/filesel.cpp | 74 ++-- src/frontend/mame/ui/filesel.h | 4 +- src/frontend/mame/ui/imgcntrl.cpp | 12 +- src/frontend/mame/ui/imgcntrl.h | 2 +- src/frontend/mame/ui/info.cpp | 13 +- src/frontend/mame/ui/info.h | 6 +- src/frontend/mame/ui/info_pty.cpp | 3 +- src/frontend/mame/ui/info_pty.h | 2 +- src/frontend/mame/ui/inputdevices.cpp | 108 ++--- src/frontend/mame/ui/inputdevices.h | 2 +- src/frontend/mame/ui/inputmap.cpp | 17 +- src/frontend/mame/ui/inputmap.h | 4 +- src/frontend/mame/ui/inputopts.cpp | 4 +- src/frontend/mame/ui/inputopts.h | 2 +- src/frontend/mame/ui/inputtoggle.cpp | 172 ++++---- src/frontend/mame/ui/inputtoggle.h | 2 +- src/frontend/mame/ui/keyboard.cpp | 72 ++-- src/frontend/mame/ui/keyboard.h | 2 +- src/frontend/mame/ui/mainmenu.cpp | 6 +- src/frontend/mame/ui/mainmenu.h | 2 +- src/frontend/mame/ui/menu.cpp | 27 +- src/frontend/mame/ui/menu.h | 6 +- src/frontend/mame/ui/miscmenu.cpp | 205 ++++++---- src/frontend/mame/ui/miscmenu.h | 14 +- src/frontend/mame/ui/optsmenu.cpp | 23 +- src/frontend/mame/ui/optsmenu.h | 8 +- src/frontend/mame/ui/pluginopt.cpp | 28 +- src/frontend/mame/ui/pluginopt.h | 5 +- src/frontend/mame/ui/quitmenu.cpp | 36 +- src/frontend/mame/ui/quitmenu.h | 5 +- src/frontend/mame/ui/selector.cpp | 69 ++-- src/frontend/mame/ui/selector.h | 2 +- src/frontend/mame/ui/selgame.cpp | 97 +++-- src/frontend/mame/ui/selgame.h | 8 +- src/frontend/mame/ui/selmenu.cpp | 28 +- src/frontend/mame/ui/selmenu.h | 4 +- src/frontend/mame/ui/selsoft.cpp | 33 +- src/frontend/mame/ui/selsoft.h | 4 +- src/frontend/mame/ui/simpleselgame.cpp | 64 +-- src/frontend/mame/ui/simpleselgame.h | 4 +- src/frontend/mame/ui/sliders.cpp | 202 +++++----- src/frontend/mame/ui/sliders.h | 2 +- src/frontend/mame/ui/slotopt.cpp | 41 +- src/frontend/mame/ui/slotopt.h | 2 +- src/frontend/mame/ui/sndmenu.cpp | 5 +- src/frontend/mame/ui/sndmenu.h | 2 +- src/frontend/mame/ui/state.cpp | 14 +- src/frontend/mame/ui/state.h | 2 +- src/frontend/mame/ui/submenu.cpp | 5 +- src/frontend/mame/ui/submenu.h | 2 +- src/frontend/mame/ui/swlist.cpp | 106 +++-- src/frontend/mame/ui/swlist.h | 6 +- src/frontend/mame/ui/tapectrl.cpp | 3 +- src/frontend/mame/ui/tapectrl.h | 2 +- src/frontend/mame/ui/textbox.cpp | 22 +- src/frontend/mame/ui/textbox.h | 4 +- src/frontend/mame/ui/ui.cpp | 47 ++- src/frontend/mame/ui/ui.h | 16 +- src/frontend/mame/ui/utils.cpp | 370 ++++++++--------- src/frontend/mame/ui/videoopt.cpp | 14 +- src/frontend/mame/ui/videoopt.h | 4 +- src/frontend/mame/ui/viewgfx.cpp | 2 +- src/osd/mac/osdmac.h | 2 +- src/osd/mac/video.cpp | 4 +- src/osd/modules/debugger/debugwin.cpp | 2 +- src/osd/modules/input/input_common.cpp | 6 +- src/osd/modules/input/input_common.h | 16 +- src/osd/modules/input/input_dinput.cpp | 12 +- src/osd/modules/input/input_dinput.h | 2 +- src/osd/modules/input/input_module.h | 2 +- src/osd/modules/input/input_none.cpp | 8 +- src/osd/modules/input/input_rawinput.cpp | 44 +- src/osd/modules/input/input_sdl.cpp | 39 +- src/osd/modules/input/input_win32.cpp | 15 +- src/osd/modules/input/input_xinput.cpp | 38 +- src/osd/modules/lib/osdobj_common.cpp | 10 +- src/osd/modules/lib/osdobj_common.h | 2 +- src/osd/osdepend.h | 2 +- src/osd/sdl/osdsdl.cpp | 4 +- src/osd/sdl/osdsdl.h | 2 +- src/osd/windows/video.cpp | 4 +- src/osd/windows/winmain.h | 2 +- 111 files changed, 2148 insertions(+), 1792 deletions(-) diff --git a/language/Vietnamese/strings.po b/language/Vietnamese/strings.po index 2cf7c83bd38..2ba9ed917e9 100644 --- a/language/Vietnamese/strings.po +++ b/language/Vietnamese/strings.po @@ -294,7 +294,7 @@ msgstr "" #: src/frontend/mame/ui/optsmenu.cpp:85 msgid "Input Devices" -msgstr "" +msgstr "Thiết bị đưa vào" #: src/frontend/mame/ui/optsmenu.cpp:87 msgid "Save Settings" @@ -340,11 +340,11 @@ msgstr "" #: src/frontend/mame/ui/filesel.cpp:520 msgid "Read-only" -msgstr "" +msgstr "Chỉ đọc" #: src/frontend/mame/ui/filesel.cpp:522 msgid "Read-write" -msgstr "" +msgstr "Đọc/ghi" #: src/frontend/mame/ui/filesel.cpp:523 msgid "Read this image, write to another image" @@ -524,11 +524,11 @@ msgstr "" #: src/frontend/mame/ui/submenu.cpp:84 msgid "Mouse" -msgstr "" +msgstr "Chuột" #: src/frontend/mame/ui/submenu.cpp:85 msgid "Joystick" -msgstr "" +msgstr "Cần điều khiển" #: src/frontend/mame/ui/submenu.cpp:86 msgid "Lightgun" @@ -688,7 +688,7 @@ msgstr "" #: src/frontend/mame/ui/analogipt.cpp:527 plugins/cheatfind/init.lua:766 #: plugins/cheatfind/init.lua:777 plugins/cheat/init.lua:679 msgid "On" -msgstr "" +msgstr "Bật" #: src/frontend/mame/ui/menu.cpp:372 src/frontend/mame/ui/menu.cpp:741 #: src/frontend/mame/ui/videoopt.cpp:185 @@ -697,11 +697,11 @@ msgstr "" #: plugins/cheatfind/init.lua:774 plugins/cheat/init.lua:682 #: plugins/cheat/init.lua:691 msgid "Off" -msgstr "" +msgstr "Tắt" #: src/frontend/mame/ui/menu.cpp:744 msgid "Auto" -msgstr "" +msgstr "Tự động" #: src/frontend/mame/ui/menu.cpp:1272 #: src/frontend/mame/ui/simpleselgame.cpp:283 @@ -1243,7 +1243,7 @@ msgstr "" #: src/frontend/mame/ui/utils.cpp:88 msgctxt "machine-filter" msgid "Not Working" -msgstr "" +msgstr "Không hoạt động" #: src/frontend/mame/ui/utils.cpp:89 msgctxt "machine-filter" diff --git a/src/emu/main.h b/src/emu/main.h index 5d51d0ba844..78553ca5236 100644 --- a/src/emu/main.h +++ b/src/emu/main.h @@ -54,7 +54,7 @@ public: static void display_ui_chooser(running_machine &machine); static int start_frontend(emu_options &options, osd_interface &osd, std::vector &args); static int start_frontend(emu_options &options, osd_interface &osd, int argc, char *argv[]); - static void draw_user_interface(running_machine& machine); + static bool draw_user_interface(running_machine& machine); static void periodic_check(); static bool frame_hook(); static void sound_hook(); diff --git a/src/emu/video.cpp b/src/emu/video.cpp index 5bb3ecdaf47..ed00fab3ea7 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -219,8 +219,8 @@ void video_manager::frame_update(bool from_debugger) bool anything_changed = update_screens && finish_screen_updates(); // update inputs and draw the user interface - machine().osd().input_update(); - emulator_info::draw_user_interface(machine()); + machine().osd().input_update(true); + anything_changed = emulator_info::draw_user_interface(machine()) || anything_changed; // let plugins draw over the UI anything_changed = emulator_info::frame_hook() || anything_changed; @@ -235,7 +235,7 @@ void video_manager::frame_update(bool from_debugger) // if we're throttling, synchronize before rendering attotime current_time = machine().time(); - if (!from_debugger && !skipped_it && phase > machine_phase::INIT && !m_low_latency && effective_throttle()) + if (!from_debugger && phase > machine_phase::INIT && !m_low_latency && effective_throttle()) update_throttle(current_time); // ask the OSD to update @@ -244,10 +244,10 @@ void video_manager::frame_update(bool from_debugger) g_profiler.stop(); // we synchronize after rendering instead of before, if low latency mode is enabled - if (!from_debugger && !skipped_it && phase > machine_phase::INIT && m_low_latency && effective_throttle()) + if (!from_debugger && phase > machine_phase::INIT && m_low_latency && effective_throttle()) update_throttle(current_time); - machine().osd().input_update(); + machine().osd().input_update(false); emulator_info::periodic_check(); if (!from_debugger) diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp index 045ef56ac82..56c5638b3a8 100644 --- a/src/frontend/mame/mame.cpp +++ b/src/frontend/mame/mame.cpp @@ -458,9 +458,9 @@ int emulator_info::start_frontend(emu_options &options, osd_interface &osd, int return start_frontend(options, osd, args); } -void emulator_info::draw_user_interface(running_machine& machine) +bool emulator_info::draw_user_interface(running_machine& machine) { - mame_machine_manager::instance()->ui().update_and_render(machine.render().ui_container()); + return mame_machine_manager::instance()->ui().update_and_render(machine.render().ui_container()); } void emulator_info::periodic_check() diff --git a/src/frontend/mame/ui/about.cpp b/src/frontend/mame/ui/about.cpp index 62d0a1c5241..afb2b73d5d3 100644 --- a/src/frontend/mame/ui/about.cpp +++ b/src/frontend/mame/ui/about.cpp @@ -125,10 +125,12 @@ void menu_about::populate() // handle - manages inputs in the about modal //------------------------------------------------- -void menu_about::handle(event const *ev) +bool menu_about::handle(event const *ev) { if (ev) - handle_key(ev->iptkey); + return handle_key(ev->iptkey); + else + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/about.h b/src/frontend/mame/ui/about.h index 5e394ba5d9e..3e84aff7a5e 100644 --- a/src/frontend/mame/ui/about.h +++ b/src/frontend/mame/ui/about.h @@ -36,7 +36,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector const m_header; }; diff --git a/src/frontend/mame/ui/analogipt.cpp b/src/frontend/mame/ui/analogipt.cpp index 393feeb7822..f8767ad3c58 100644 --- a/src/frontend/mame/ui/analogipt.cpp +++ b/src/frontend/mame/ui/analogipt.cpp @@ -227,158 +227,171 @@ void menu_analog::menu_activated() } -void menu_analog::handle(event const *ev) +bool menu_analog::handle(event const *ev) { - // handle events - if (ev) + if (!ev) { - if (IPT_UI_ON_SCREEN_DISPLAY == ev->iptkey) + return false; + } + else if (IPT_UI_ON_SCREEN_DISPLAY == ev->iptkey) + { + m_hide_menu = !m_hide_menu; + set_process_flags(PROCESS_LR_REPEAT | (m_hide_menu ? (PROCESS_CUSTOM_NAV | PROCESS_CUSTOM_ONLY) : 0)); + return true; + } + else if (IPT_UI_HELP == ev->iptkey) + { + stack_push( + ui(), + container(), + _("menu-analoginput", "Analog Input Adjustments Help"), + util::string_format( + _("menu-analoginput", HELP_TEXT), + ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY), + ui().get_general_input_setting(IPT_UI_LEFT), + ui().get_general_input_setting(IPT_UI_RIGHT), + ui().get_general_input_setting(IPT_UI_CLEAR), + ui().get_general_input_setting(IPT_UI_PREV_GROUP), + ui().get_general_input_setting(IPT_UI_NEXT_GROUP), + ui().get_general_input_setting(IPT_UI_BACK))); + return false; + } + else if (m_hide_menu) + { + switch (ev->iptkey) { - m_hide_menu = !m_hide_menu; - set_process_flags(PROCESS_LR_REPEAT | (m_hide_menu ? (PROCESS_CUSTOM_NAV | PROCESS_CUSTOM_ONLY) : 0)); + case IPT_UI_UP: + --m_top_field; + return true; + case IPT_UI_DOWN: + ++m_top_field; + return true; + case IPT_UI_HOME: + m_top_field = 0; + return true; + case IPT_UI_END: + m_top_field = m_field_data.size(); + return true; + default: + return false; } - else if (IPT_UI_HELP == ev->iptkey) + } + else if (ev->itemref) + { + item_data &data(*reinterpret_cast(ev->itemref)); + int newval(data.cur); + + switch (ev->iptkey) { - stack_push( - ui(), - container(), - _("menu-analoginput", "Analog Input Adjustments Help"), - util::string_format( - _("menu-analoginput", HELP_TEXT), - ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY), - ui().get_general_input_setting(IPT_UI_LEFT), - ui().get_general_input_setting(IPT_UI_RIGHT), - ui().get_general_input_setting(IPT_UI_CLEAR), - ui().get_general_input_setting(IPT_UI_PREV_GROUP), - ui().get_general_input_setting(IPT_UI_NEXT_GROUP), - ui().get_general_input_setting(IPT_UI_BACK))); - } - else if (m_hide_menu) - { - switch (ev->iptkey) + // flip toggles when selected + case IPT_UI_SELECT: + if (ANALOG_ITEM_REVERSE == data.type) + newval = newval ? 0 : 1; + break; + + // if cleared, reset to default value + case IPT_UI_CLEAR: + newval = data.defvalue; + break; + + // left decrements + case IPT_UI_LEFT: + newval -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; + break; + + // right increments + case IPT_UI_RIGHT: + newval += machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; + break; + + // move to first item for previous device + case IPT_UI_PREV_GROUP: { - case IPT_UI_UP: - --m_top_field; - break; - case IPT_UI_DOWN: - ++m_top_field; - break; - case IPT_UI_HOME: - m_top_field = 0; - break; - case IPT_UI_END: - m_top_field = m_field_data.size(); - break; - } - } - else if (ev->itemref) - { - item_data &data(*reinterpret_cast(ev->itemref)); - int newval(data.cur); - - switch (ev->iptkey) - { - // flip toggles when selected - case IPT_UI_SELECT: - if (ANALOG_ITEM_REVERSE == data.type) - newval = newval ? 0 : 1; - break; - - // if cleared, reset to default value - case IPT_UI_CLEAR: - newval = data.defvalue; - break; - - // left decrements - case IPT_UI_LEFT: - newval -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; - break; - - // right increments - case IPT_UI_RIGHT: - newval += machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; - break; - - // move to first item for previous device - case IPT_UI_PREV_GROUP: + auto current = std::distance(m_item_data.data(), &data); + device_t const *dev(&data.field.get().device()); + bool found_break = false; + while (0 < current) { - auto current = std::distance(m_item_data.data(), &data); - device_t const *dev(&data.field.get().device()); - bool found_break = false; - while (0 < current) + if (!found_break) { - if (!found_break) + device_t const *prev(&m_item_data[--current].field.get().device()); + if (prev != dev) { - device_t const *prev(&m_item_data[--current].field.get().device()); - if (prev != dev) - { - dev = prev; - found_break = true; - } - } - else if (&m_item_data[current - 1].field.get().device() != dev) - { - set_selection(&m_item_data[current]); - set_top_line(selected_index() - 1); - break; - } - else - { - --current; - } - if (found_break && !current) - { - set_selection(&m_item_data[current]); - set_top_line(selected_index() - 1); - break; + dev = prev; + found_break = true; } } - } - break; - - // move to first item for next device - case IPT_UI_NEXT_GROUP: - { - auto current = std::distance(m_item_data.data(), &data); - device_t const *const dev(&data.field.get().device()); - while (m_item_data.size() > ++current) + else if (&m_item_data[current - 1].field.get().device() != dev) { - if (&m_item_data[current].field.get().device() != dev) - { - set_selection(&m_item_data[current]); - set_top_line(selected_index() - 1); - break; - } + set_selection(&m_item_data[current]); + set_top_line(selected_index() - 1); + return true; + } + else + { + --current; + } + if (found_break && !current) + { + set_selection(&m_item_data[current]); + set_top_line(selected_index() - 1); + return true; } } - break; } + break; - // clamp to range - newval = std::clamp(newval, data.min, data.max); - - // if things changed, update - if (newval != data.cur) + // move to first item for next device + case IPT_UI_NEXT_GROUP: { - ioport_field::user_settings settings; - - // get the settings and set the new value - data.field.get().get_user_settings(settings); - switch (data.type) + auto current = std::distance(m_item_data.data(), &data); + device_t const *const dev(&data.field.get().device()); + while (m_item_data.size() > ++current) { - case ANALOG_ITEM_KEYSPEED: settings.delta = newval; break; - case ANALOG_ITEM_CENTERSPEED: settings.centerdelta = newval; break; - case ANALOG_ITEM_REVERSE: settings.reverse = newval; break; - case ANALOG_ITEM_SENSITIVITY: settings.sensitivity = newval; break; + if (&m_item_data[current].field.get().device() != dev) + { + set_selection(&m_item_data[current]); + set_top_line(selected_index() - 1); + return true; + } } - data.field.get().set_user_settings(settings); - data.cur = newval; - - // update the menu item - ev->item->set_subtext(item_text(data.type, newval)); - ev->item->set_flags((data.cur <= data.min) ? FLAG_RIGHT_ARROW : (data.cur >= data.max) ? FLAG_LEFT_ARROW : FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW); } + break; } + + // clamp to range + newval = std::clamp(newval, data.min, data.max); + + // if things changed, update + if (newval != data.cur) + { + ioport_field::user_settings settings; + + // get the settings and set the new value + data.field.get().get_user_settings(settings); + switch (data.type) + { + case ANALOG_ITEM_KEYSPEED: settings.delta = newval; break; + case ANALOG_ITEM_CENTERSPEED: settings.centerdelta = newval; break; + case ANALOG_ITEM_REVERSE: settings.reverse = newval; break; + case ANALOG_ITEM_SENSITIVITY: settings.sensitivity = newval; break; + } + data.field.get().set_user_settings(settings); + data.cur = newval; + + // update the menu item + ev->item->set_subtext(item_text(data.type, newval)); + ev->item->set_flags((data.cur <= data.min) ? FLAG_RIGHT_ARROW : (data.cur >= data.max) ? FLAG_LEFT_ARROW : FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW); + return true; + } + else + { + return false; + } + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/analogipt.h b/src/frontend/mame/ui/analogipt.h index 26f2580318a..d60aafd6cc4 100644 --- a/src/frontend/mame/ui/analogipt.h +++ b/src/frontend/mame/ui/analogipt.h @@ -68,7 +68,7 @@ private: using field_data_vector = std::vector; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void find_fields(); diff --git a/src/frontend/mame/ui/auditmenu.cpp b/src/frontend/mame/ui/auditmenu.cpp index 07f55510ec8..d225535c4e7 100644 --- a/src/frontend/mame/ui/auditmenu.cpp +++ b/src/frontend/mame/ui/auditmenu.cpp @@ -150,7 +150,7 @@ void menu_audit::populate() item_append(menu_item_type::SEPARATOR, 0); } -void menu_audit::handle(event const *ev) +bool menu_audit::handle(event const *ev) { switch (m_phase) { @@ -166,6 +166,7 @@ void menu_audit::handle(event const *ev) m_future.resize(std::thread::hardware_concurrency()); for (auto &future : m_future) future = std::async(std::launch::async, [this] () { return do_audit(); }); + return true; } } break; @@ -191,13 +192,17 @@ void menu_audit::handle(event const *ev) m_phase = phase::CANCELLATION; else m_phase = phase::AUDIT; + return true; } else if ((phase::CANCELLATION == m_phase) && machine().ui_input().pressed(IPT_UI_SELECT)) { m_cancel.store(true); + return true; } break; } + + return false; } bool menu_audit::do_audit() diff --git a/src/frontend/mame/ui/auditmenu.h b/src/frontend/mame/ui/auditmenu.h index f0a37f09fba..5d71b63fd2f 100644 --- a/src/frontend/mame/ui/auditmenu.h +++ b/src/frontend/mame/ui/auditmenu.h @@ -37,7 +37,7 @@ private: enum class phase { CONFIRMATION, AUDIT, CANCELLATION }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool do_audit(); void save_available_machines(); diff --git a/src/frontend/mame/ui/barcode.cpp b/src/frontend/mame/ui/barcode.cpp index 31dcf768e78..979203f0133 100644 --- a/src/frontend/mame/ui/barcode.cpp +++ b/src/frontend/mame/ui/barcode.cpp @@ -75,66 +75,74 @@ void menu_barcode_reader::populate() // handle - manages inputs in the barcode input menu //------------------------------------------------- -void menu_barcode_reader::handle(event const *ev) +bool menu_barcode_reader::handle(event const *ev) { - // process the event - if (ev) + if (!ev) + return false; + + switch (ev->iptkey) { - // handle selections - switch (ev->iptkey) + case IPT_UI_LEFT: + if (ev->itemref == ITEMREF_SELECT_READER) + return previous(); + break; + + case IPT_UI_RIGHT: + if (ev->itemref == ITEMREF_SELECT_READER) + return next(); + break; + + case IPT_UI_SELECT: + if (ev->itemref == ITEMREF_ENTER_BARCODE) { - case IPT_UI_LEFT: - if (ev->itemref == ITEMREF_SELECT_READER) - previous(); - break; - - case IPT_UI_RIGHT: - if (ev->itemref == ITEMREF_SELECT_READER) - next(); - break; - - case IPT_UI_SELECT: - if (ev->itemref == ITEMREF_ENTER_BARCODE) + //osd_printf_verbose("code %s\n", m_barcode_buffer); + if (!current_device()->is_valid(m_barcode_buffer.length())) { - std::string tmp_file(m_barcode_buffer); - //printf("code %s\n", m_barcode_buffer); - if (!current_device()->is_valid(tmp_file.length())) - ui().popup_time(5, "%s", _("Barcode length invalid!")); - else - { - current_device()->write_code(tmp_file.c_str(), tmp_file.length()); - // if sending was successful, reset char buffer - m_barcode_buffer.clear(); - reset(reset_options::REMEMBER_POSITION); - } + ui().popup_time(5, "%s", _("Barcode length invalid!")); } - break; - - case IPT_UI_CLEAR: - if (get_selection_ref() == ITEMREF_NEW_BARCODE) + else { + current_device()->write_code(m_barcode_buffer.c_str(), m_barcode_buffer.length()); + // if sending was successful, reset char buffer m_barcode_buffer.clear(); reset(reset_options::REMEMBER_POSITION); } - break; - - case IPT_UI_PASTE: - if (get_selection_ref() == ITEMREF_NEW_BARCODE) - { - if (paste_text(m_barcode_buffer, uchar_is_digit)) - ev->item->set_subtext(m_barcode_buffer); - } - break; - - case IPT_SPECIAL: - if (get_selection_ref() == ITEMREF_NEW_BARCODE) - { - if (input_character(m_barcode_buffer, ev->unichar, uchar_is_digit)) - ev->item->set_subtext(m_barcode_buffer); - } - break; } + break; + + case IPT_UI_CLEAR: + if (ev->itemref == ITEMREF_NEW_BARCODE) + { + m_barcode_buffer.clear(); + ev->item->set_subtext(m_barcode_buffer); + return true; + } + break; + + case IPT_UI_PASTE: + if (get_selection_ref() == ITEMREF_NEW_BARCODE) + { + if (paste_text(m_barcode_buffer, uchar_is_digit)) + { + ev->item->set_subtext(m_barcode_buffer); + return true; + } + } + break; + + case IPT_SPECIAL: + if (get_selection_ref() == ITEMREF_NEW_BARCODE) + { + if (input_character(m_barcode_buffer, ev->unichar, uchar_is_digit)) + { + ev->item->set_subtext(m_barcode_buffer); + return true; + } + } + break; } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/barcode.h b/src/frontend/mame/ui/barcode.h index 5f70fe65276..7fa9881c3dd 100644 --- a/src/frontend/mame/ui/barcode.h +++ b/src/frontend/mame/ui/barcode.h @@ -13,9 +13,13 @@ #pragma once -#include "machine/bcreader.h" #include "ui/devctrl.h" +#include "machine/bcreader.h" + +#include + + namespace ui { class menu_barcode_reader : public menu_device_control { @@ -25,7 +29,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::string m_barcode_buffer; }; diff --git a/src/frontend/mame/ui/cheatopt.cpp b/src/frontend/mame/ui/cheatopt.cpp index 193a3c9efd6..054df4aed81 100644 --- a/src/frontend/mame/ui/cheatopt.cpp +++ b/src/frontend/mame/ui/cheatopt.cpp @@ -29,76 +29,77 @@ namespace ui { menu_cheat - handle the cheat menu -------------------------------------------------*/ -void menu_cheat::handle(event const *ev) +bool menu_cheat::handle(event const *ev) { - // handle events - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + bool changed = false; + + // clear cheat comment on any movement or keypress + machine().popmessage(); + + if ((ev->itemref == ITEMREF_CHEATS_RESET_ALL || ev->itemref == ITEMREF_CHEATS_RELOAD_ALL) && ev->iptkey == IPT_UI_SELECT) { - bool changed = false; - - // clear cheat comment on any movement or keypress - machine().popmessage(); - - if ((ev->itemref == ITEMREF_CHEATS_RESET_ALL || ev->itemref == ITEMREF_CHEATS_RELOAD_ALL) && ev->iptkey == IPT_UI_SELECT) - { - // handle reset all + reset all cheats for reload all option - for (auto &curcheat : mame_machine_manager::instance()->cheat().entries()) - if (curcheat->select_default_state()) - changed = true; - } - else if (ev->itemref >= ITEMREF_CHEATS_FIRST_ITEM) - { - // handle individual cheats - cheat_entry *curcheat = reinterpret_cast(ev->itemref); - const char *string; - switch (ev->iptkey) - { - // if selected, activate a oneshot - case IPT_UI_SELECT: - changed = curcheat->activate(); - break; - - // if cleared, reset to default value - case IPT_UI_CLEAR: - changed = curcheat->select_default_state(); - break; - - // left decrements - case IPT_UI_LEFT: - changed = curcheat->select_previous_state(); - break; - - // right increments - case IPT_UI_RIGHT: - changed = curcheat->select_next_state(); - break; - - // bring up display comment if one exists - case IPT_UI_DISPLAY_COMMENT: - case IPT_UI_UP: - case IPT_UI_DOWN: - string = curcheat->comment(); - if (string && *string) - machine().popmessage(_("Cheat Comment:\n%s"), string); - break; - } - } - - // handle reload all - if (ev->itemref == ITEMREF_CHEATS_RELOAD_ALL && ev->iptkey == IPT_UI_SELECT) - { - // re-init cheat engine and thus reload cheats/cheats have already been turned off by here - mame_machine_manager::instance()->cheat().reload(); - - // display the reloaded cheats - reset(reset_options::REMEMBER_REF); - machine().popmessage(_("All cheats reloaded")); - } - - // if things changed, update - if (changed) - reset(reset_options::REMEMBER_REF); + // handle reset all + reset all cheats for reload all option + for (auto &curcheat : mame_machine_manager::instance()->cheat().entries()) + if (curcheat->select_default_state()) + changed = true; } + else if (ev->itemref >= ITEMREF_CHEATS_FIRST_ITEM) + { + // handle individual cheats + cheat_entry *curcheat = reinterpret_cast(ev->itemref); + const char *string; + switch (ev->iptkey) + { + // if selected, activate a oneshot + case IPT_UI_SELECT: + changed = curcheat->activate(); + break; + + // if cleared, reset to default value + case IPT_UI_CLEAR: + changed = curcheat->select_default_state(); + break; + + // left decrements + case IPT_UI_LEFT: + changed = curcheat->select_previous_state(); + break; + + // right increments + case IPT_UI_RIGHT: + changed = curcheat->select_next_state(); + break; + + // bring up display comment if one exists + case IPT_UI_DISPLAY_COMMENT: + case IPT_UI_UP: + case IPT_UI_DOWN: + string = curcheat->comment(); + if (string && *string) + machine().popmessage(_("Cheat Comment:\n%s"), string); + break; + } + } + + // handle reload all + if (ev->itemref == ITEMREF_CHEATS_RELOAD_ALL && ev->iptkey == IPT_UI_SELECT) + { + // re-init cheat engine and thus reload cheats/cheats have already been turned off by here + mame_machine_manager::instance()->cheat().reload(); + + // display the reloaded cheats + reset(reset_options::REMEMBER_REF); + machine().popmessage(_("All cheats reloaded")); + } + + // if things changed, update + if (changed) + reset(reset_options::REMEMBER_REF); + + return false; // always triggers an item reset if the menu needs to be redrawn } diff --git a/src/frontend/mame/ui/cheatopt.h b/src/frontend/mame/ui/cheatopt.h index ba0f144dbaf..b704562202b 100644 --- a/src/frontend/mame/ui/cheatopt.h +++ b/src/frontend/mame/ui/cheatopt.h @@ -25,7 +25,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/confswitch.cpp b/src/frontend/mame/ui/confswitch.cpp index 7d6030ce669..946062b9a1d 100644 --- a/src/frontend/mame/ui/confswitch.cpp +++ b/src/frontend/mame/ui/confswitch.cpp @@ -171,103 +171,106 @@ void menu_confswitch::populate() } -void menu_confswitch::handle(event const *ev) +bool menu_confswitch::handle(event const *ev) { - // handle events - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + if (uintptr_t(ev->itemref) == 1U) { - if (uintptr_t(ev->itemref) == 1U) - { - // reset - if (ev->iptkey == IPT_UI_SELECT) - machine().schedule_hard_reset(); - } - else - { - // actual settings - ioport_field &field(*reinterpret_cast(ev->itemref)); - bool changed(false); - - switch (ev->iptkey) - { - // left goes to previous setting - case IPT_UI_LEFT: - field.select_previous_setting(); - changed = true; - break; - - // right goes to next setting - case IPT_UI_SELECT: - case IPT_UI_RIGHT: - field.select_next_setting(); - changed = true; - break; - - // if cleared, reset to default value - case IPT_UI_CLEAR: - { - ioport_field::user_settings settings; - field.get_user_settings(settings); - if (field.defvalue() != settings.value) - { - settings.value = field.defvalue(); - field.set_user_settings(settings); - changed = true; - } - } - break; - - // trick to get previous group - depend on headings having null reference - case IPT_UI_PREV_GROUP: - { - auto current = selected_index(); - bool found_break = false; - while (0 < current) - { - if (!found_break) - { - if (!item(--current).ref()) - found_break = true; - } - else if (!item(current - 1).ref()) - { - set_selected_index(current); - set_top_line(current - 1); - break; - } - else - { - --current; - } - } - } - break; - - // trick to get next group - depend on special item references - case IPT_UI_NEXT_GROUP: - { - auto current = selected_index(); - while (item_count() > ++current) - { - if (!item(current).ref()) - { - if ((item_count() > (current + 1)) && (uintptr_t(item(current + 1).ref()) != 1)) - { - set_selected_index(current + 1); - set_top_line(current); - } - break; - } - } - } - break; - } - - // if anything changed, rebuild the menu, trying to stay on the same field - if (changed) - reset(reset_options::REMEMBER_REF); - } + // reset + if (ev->iptkey == IPT_UI_SELECT) + machine().schedule_hard_reset(); } + else + { + // actual settings + ioport_field &field(*reinterpret_cast(ev->itemref)); + bool changed(false); + + switch (ev->iptkey) + { + // left goes to previous setting + case IPT_UI_LEFT: + field.select_previous_setting(); + changed = true; + break; + + // right goes to next setting + case IPT_UI_SELECT: + case IPT_UI_RIGHT: + field.select_next_setting(); + changed = true; + break; + + // if cleared, reset to default value + case IPT_UI_CLEAR: + { + ioport_field::user_settings settings; + field.get_user_settings(settings); + if (field.defvalue() != settings.value) + { + settings.value = field.defvalue(); + field.set_user_settings(settings); + changed = true; + } + } + break; + + // trick to get previous group - depend on headings having null reference + case IPT_UI_PREV_GROUP: + { + auto current = selected_index(); + bool found_break = false; + while (0 < current) + { + if (!found_break) + { + if (!item(--current).ref()) + found_break = true; + } + else if (!item(current - 1).ref()) + { + set_selected_index(current); + set_top_line(current - 1); + return true; + } + else + { + --current; + } + } + } + break; + + // trick to get next group - depend on special item references + case IPT_UI_NEXT_GROUP: + { + auto current = selected_index(); + while (item_count() > ++current) + { + if (!item(current).ref()) + { + if ((item_count() > (current + 1)) && (uintptr_t(item(current + 1).ref()) != 1)) + { + set_selected_index(current + 1); + set_top_line(current); + return true; + } + break; + } + } + } + break; + } + + // if anything changed, rebuild the menu, trying to stay on the same field + if (changed) + reset(reset_options::REMEMBER_REF); + } + + // changing settings triggers an item rebuild because it can affect whether things are enabled + return false; } diff --git a/src/frontend/mame/ui/confswitch.h b/src/frontend/mame/ui/confswitch.h index 9094fb2dc22..2d025f7dfc8 100644 --- a/src/frontend/mame/ui/confswitch.h +++ b/src/frontend/mame/ui/confswitch.h @@ -64,7 +64,7 @@ protected: unsigned active_switch_groups() const { return m_active_switch_groups; } private: - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void find_fields(); diff --git a/src/frontend/mame/ui/custui.cpp b/src/frontend/mame/ui/custui.cpp index 22740412ff9..1db4a64ba13 100644 --- a/src/frontend/mame/ui/custui.cpp +++ b/src/frontend/mame/ui/custui.cpp @@ -110,99 +110,103 @@ void menu_custom_ui::menu_dismissed() // handle //------------------------------------------------- -void menu_custom_ui::handle(event const *ev) +bool menu_custom_ui::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + switch ((uintptr_t)ev->itemref) { - switch ((uintptr_t)ev->itemref) + case FONT_MENU: + if (ev->iptkey == IPT_UI_SELECT) + menu::stack_push(ui(), container(), nullptr); + break; + case COLORS_MENU: + if (ev->iptkey == IPT_UI_SELECT) + menu::stack_push(ui(), container()); + break; + case LANGUAGE_MENU: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) { - case FONT_MENU: - if (ev->iptkey == IPT_UI_SELECT) - menu::stack_push(ui(), container(), nullptr); - break; - case COLORS_MENU: - if (ev->iptkey == IPT_UI_SELECT) - menu::stack_push(ui(), container()); - break; - case LANGUAGE_MENU: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - if (ev->iptkey == IPT_UI_LEFT) - --m_currlang; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_currlang; - else - m_currlang = 0; - ev->item->set_subtext(m_languages[m_currlang]); - ev->item->set_flags(get_arrow_flags(0, m_languages.size() - 1, m_currlang)); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - // copying list of language names - expensive - menu::stack_push( - ui(), container(), _("UI Language"), std::vector(m_languages), m_currlang, - [this, item = ev->item] (int selection) - { - m_currlang = selection; - item->set_subtext(m_languages[selection]); - item->set_flags(get_arrow_flags(0, m_languages.size() - 1, selection)); - }); - } - break; - case SYSNAMES_MENU: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - if (ev->iptkey == IPT_UI_LEFT) - --m_currsysnames; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_currsysnames; - else - m_currsysnames = 0; - ev->item->set_subtext(m_sysnames[m_currsysnames]); - ev->item->set_flags(get_arrow_flags(0, m_sysnames.size() - 1, m_currsysnames)); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - // copying list of file names - expensive - menu::stack_push( - ui(), container(), _("System Names"), std::vector(m_sysnames), m_currsysnames, - [this, item = ev->item] (int selection) - { - m_currsysnames = selection; - item->set_subtext(m_sysnames[selection]); - item->set_flags(get_arrow_flags(0, m_sysnames.size() - 1, selection)); - }); - } - break; - case HIDE_MENU: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - if (ev->iptkey == IPT_UI_LEFT) - --m_currpanels; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_currpanels; - else - m_currpanels = 0; - ev->item->set_subtext(_(HIDE_STATUS[m_currpanels])); - ev->item->set_flags(get_arrow_flags(0, HIDE_BOTH, m_currpanels)); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - std::vector s_sel(std::size(HIDE_STATUS)); - std::transform(std::begin(HIDE_STATUS), std::end(HIDE_STATUS), s_sel.begin(), [](auto &s) { return _(s); }); - menu::stack_push( - ui(), container(), _("Show Side Panels"), std::move(s_sel), m_currpanels, - [this, item = ev->item] (int selection) - { - m_currpanels = selection; - item->set_subtext(_(HIDE_STATUS[selection])); - item->set_flags(get_arrow_flags(0, HIDE_BOTH, selection)); - }); - } - break; + if (ev->iptkey == IPT_UI_LEFT) + --m_currlang; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_currlang; + else + m_currlang = 0; + ev->item->set_subtext(m_languages[m_currlang]); + ev->item->set_flags(get_arrow_flags(0, m_languages.size() - 1, m_currlang)); + return true; } + else if (ev->iptkey == IPT_UI_SELECT) + { + // copying list of language names - expensive + menu::stack_push( + ui(), container(), _("UI Language"), std::vector(m_languages), m_currlang, + [this, item = ev->item] (int selection) + { + m_currlang = selection; + item->set_subtext(m_languages[selection]); + item->set_flags(get_arrow_flags(0, m_languages.size() - 1, selection)); + }); + } + break; + case SYSNAMES_MENU: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + if (ev->iptkey == IPT_UI_LEFT) + --m_currsysnames; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_currsysnames; + else + m_currsysnames = 0; + ev->item->set_subtext(m_sysnames[m_currsysnames]); + ev->item->set_flags(get_arrow_flags(0, m_sysnames.size() - 1, m_currsysnames)); + return true; + } + else if (ev->iptkey == IPT_UI_SELECT) + { + // copying list of file names - expensive + menu::stack_push( + ui(), container(), _("System Names"), std::vector(m_sysnames), m_currsysnames, + [this, item = ev->item] (int selection) + { + m_currsysnames = selection; + item->set_subtext(m_sysnames[selection]); + item->set_flags(get_arrow_flags(0, m_sysnames.size() - 1, selection)); + }); + } + break; + case HIDE_MENU: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + if (ev->iptkey == IPT_UI_LEFT) + --m_currpanels; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_currpanels; + else + m_currpanels = 0; + ev->item->set_subtext(_(HIDE_STATUS[m_currpanels])); + ev->item->set_flags(get_arrow_flags(0, HIDE_BOTH, m_currpanels)); + return true; + } + else if (ev->iptkey == IPT_UI_SELECT) + { + std::vector s_sel(std::size(HIDE_STATUS)); + std::transform(std::begin(HIDE_STATUS), std::end(HIDE_STATUS), s_sel.begin(), [](auto &s) { return _(s); }); + menu::stack_push( + ui(), container(), _("Show Side Panels"), std::move(s_sel), m_currpanels, + [this, item = ev->item] (int selection) + { + m_currpanels = selection; + item->set_subtext(_(HIDE_STATUS[selection])); + item->set_flags(get_arrow_flags(0, HIDE_BOTH, selection)); + }); + } + break; } + + return false; } //------------------------------------------------- @@ -405,93 +409,97 @@ void menu_font_ui::menu_dismissed() // handle //------------------------------------------------- -void menu_font_ui::handle(event const *ev) +bool menu_font_ui::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + switch ((uintptr_t)ev->itemref) { - switch ((uintptr_t)ev->itemref) + case FONT_SIZE: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) { - case FONT_SIZE: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_changed = true; - if (ev->iptkey == IPT_UI_LEFT) - --m_font_size; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_font_size; - else - m_font_size = parse_number(ui().options().get_entry(OPTION_FONT_ROWS)->default_value().c_str()); - ev->item->set_subtext(string_format("%d", m_font_size)); - ev->item->set_flags(get_arrow_flags(m_font_min, m_font_max, m_font_size)); - } - break; + m_changed = true; + if (ev->iptkey == IPT_UI_LEFT) + --m_font_size; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_font_size; + else + m_font_size = parse_number(ui().options().get_entry(OPTION_FONT_ROWS)->default_value().c_str()); + ev->item->set_subtext(string_format("%d", m_font_size)); + ev->item->set_flags(get_arrow_flags(m_font_min, m_font_max, m_font_size)); + return true; + } + break; - case INFOS_SIZE: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_changed = true; - if (ev->iptkey == IPT_UI_LEFT) - m_info_size -= 0.05f; - else if (ev->iptkey == IPT_UI_RIGHT) - m_info_size += 0.05f; - else - m_info_size = parse_number(ui().options().get_entry(OPTION_INFOS_SIZE)->default_value().c_str()); - ev->item->set_subtext(string_format("%.2f", m_info_size)); - ev->item->set_flags(get_arrow_flags(m_info_min, m_info_max, m_info_size)); - } - break; + case INFOS_SIZE: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + m_changed = true; + if (ev->iptkey == IPT_UI_LEFT) + m_info_size -= 0.05f; + else if (ev->iptkey == IPT_UI_RIGHT) + m_info_size += 0.05f; + else + m_info_size = parse_number(ui().options().get_entry(OPTION_INFOS_SIZE)->default_value().c_str()); + ev->item->set_subtext(string_format("%.2f", m_info_size)); + ev->item->set_flags(get_arrow_flags(m_info_min, m_info_max, m_info_size)); + return true; + } + break; - case MUI_FNT: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_face_changed = true; - m_changed = true; - if (ev->iptkey == IPT_UI_LEFT) - --m_actual; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_actual; - else - m_actual = 0; - reset(reset_options::REMEMBER_REF); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - std::vector display_names; - display_names.reserve(m_fonts.size()); - for (auto const &font : m_fonts) - display_names.emplace_back(font.second); - menu::stack_push( - ui(), container(), _("UI Font"), std::move(display_names), m_actual, - [this] (int selection) - { - m_face_changed = true; - m_changed = true; - m_actual = selection; - reset(reset_options::REMEMBER_REF); - }); - } - break; + case MUI_FNT: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + m_face_changed = true; + m_changed = true; + if (ev->iptkey == IPT_UI_LEFT) + --m_actual; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_actual; + else + m_actual = 0; + reset(reset_options::REMEMBER_REF); + } + else if (ev->iptkey == IPT_UI_SELECT) + { + std::vector display_names; + display_names.reserve(m_fonts.size()); + for (auto const &font : m_fonts) + display_names.emplace_back(font.second); + menu::stack_push( + ui(), container(), _("UI Font"), std::move(display_names), m_actual, + [this] (int selection) + { + m_face_changed = true; + m_changed = true; + m_actual = selection; + reset(reset_options::REMEMBER_REF); + }); + } + break; #ifdef UI_WINDOWS - case MUI_BOLD: - case MUI_ITALIC: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_SELECT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_face_changed = true; - m_changed = true; - bool &val = ((uintptr_t)ev->itemref == MUI_BOLD) ? m_bold : m_italic; - if (ev->iptkey == IPT_UI_CLEAR) - val = false; - else - val = !val; - ev->item->set_subtext(val ? _("On") : _("Off")); - ev->item->set_flags(val ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); - } - break; -#endif + case MUI_BOLD: + case MUI_ITALIC: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_SELECT) || (ev->iptkey == IPT_UI_CLEAR)) + { + m_face_changed = true; + m_changed = true; + bool &val = ((uintptr_t)ev->itemref == MUI_BOLD) ? m_bold : m_italic; + if (ev->iptkey == IPT_UI_CLEAR) + val = false; + else + val = !val; + ev->item->set_subtext(val ? _("On") : _("Off")); + ev->item->set_flags(val ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; } + break; +#endif } + + return false; } //------------------------------------------------- @@ -601,9 +609,8 @@ void menu_colors_ui::menu_dismissed() // handle //------------------------------------------------- -void menu_colors_ui::handle(event const *ev) +bool menu_colors_ui::handle(event const *ev) { - // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) { if ((uintptr_t)ev->itemref != MUI_RESTORE) @@ -613,8 +620,11 @@ void menu_colors_ui::handle(event const *ev) else { restore_colors(); + return true; } } + + return false; } //------------------------------------------------- @@ -813,81 +823,82 @@ menu_rgb_ui::menu_rgb_ui(mame_ui_manager &mui, render_container &container, rgb_ // handle //------------------------------------------------- -void menu_rgb_ui::handle(event const *ev) +bool menu_rgb_ui::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) - { - switch (ev->iptkey) - { - case IPT_UI_LEFT: - case IPT_UI_RIGHT: - { - bool changed = false; - int updated = (IPT_UI_LEFT == ev->iptkey) ? -1 : 1; - switch (uintptr_t(ev->itemref)) - { - case RGB_ALPHA: - updated += m_color->a(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_a(updated); - changed = true; - } - break; - case RGB_RED: - updated += m_color->r(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_r(updated); - changed = true; - } - break; - case RGB_GREEN: - updated += m_color->g(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_g(updated); - changed = true; - } - break; - case RGB_BLUE: - updated += m_color->b(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_b(updated); - changed = true; - } - break; - } - if (changed) - { - ev->item->set_subtext(string_format("%3u", updated)); - ev->item->set_flags(get_arrow_flags(0, 255, updated)); - } - } - break; + if (!ev || !ev->itemref) + return false; - case IPT_UI_SELECT: - if (uintptr_t(ev->itemref) == PALETTE_CHOOSE) - { - menu::stack_push(ui(), container(), *m_color); - break; - } - [[fallthrough]]; - case IPT_SPECIAL: + switch (ev->iptkey) + { + case IPT_UI_LEFT: + case IPT_UI_RIGHT: + { + bool changed = false; + int updated = (IPT_UI_LEFT == ev->iptkey) ? -1 : 1; switch (uintptr_t(ev->itemref)) { case RGB_ALPHA: + updated += m_color->a(); + if ((0 <= updated) && (255 >= updated)) + { + m_color->set_a(updated); + changed = true; + } + break; case RGB_RED: + updated += m_color->r(); + if ((0 <= updated) && (255 >= updated)) + { + m_color->set_r(updated); + changed = true; + } + break; case RGB_GREEN: + updated += m_color->g(); + if ((0 <= updated) && (255 >= updated)) + { + m_color->set_g(updated); + changed = true; + } + break; case RGB_BLUE: - inkey_special(ev); + updated += m_color->b(); + if ((0 <= updated) && (255 >= updated)) + { + m_color->set_b(updated); + changed = true; + } break; } + if (changed) + { + ev->item->set_subtext(string_format("%3u", updated)); + ev->item->set_flags(get_arrow_flags(0, 255, updated)); + return true; + } + } + break; + + case IPT_UI_SELECT: + if (uintptr_t(ev->itemref) == PALETTE_CHOOSE) + { + menu::stack_push(ui(), container(), *m_color); break; } + [[fallthrough]]; + case IPT_SPECIAL: + switch (uintptr_t(ev->itemref)) + { + case RGB_ALPHA: + case RGB_RED: + case RGB_GREEN: + case RGB_BLUE: + return inkey_special(ev); + } + break; } + + return false; } //------------------------------------------------- @@ -997,7 +1008,7 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa // handle special key event //------------------------------------------------- -void menu_rgb_ui::inkey_special(const event *menu_event) +bool menu_rgb_ui::inkey_special(const event *menu_event) { if (menu_event->iptkey == IPT_UI_SELECT) { @@ -1040,11 +1051,16 @@ void menu_rgb_ui::inkey_special(const event *menu_event) menu_event->item->set_subtext("_"); menu_event->item->set_flags(0); } + return true; } - else if (m_key_active) + else if (m_key_active && input_character(m_search, 3, menu_event->unichar, uchar_is_digit)) { - input_character(m_search, 3, menu_event->unichar, uchar_is_digit); menu_event->item->set_subtext(m_search + "_"); + return true; + } + else + { + return false; } } @@ -1074,9 +1090,8 @@ menu_palette_sel::menu_palette_sel(mame_ui_manager &mui, render_container &conta // handle //------------------------------------------------- -void menu_palette_sel::handle(event const *ev) +bool menu_palette_sel::handle(event const *ev) { - // process the menu if (ev && ev->itemref) { if (ev->iptkey == IPT_UI_SELECT) @@ -1086,6 +1101,8 @@ void menu_palette_sel::handle(event const *ev) stack_pop(); } } + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/custui.h b/src/frontend/mame/ui/custui.h index c009a4eccf0..981546c64e3 100644 --- a/src/frontend/mame/ui/custui.h +++ b/src/frontend/mame/ui/custui.h @@ -16,6 +16,8 @@ #include "ui/menu.h" #include +#include +#include namespace ui { @@ -34,7 +36,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void find_languages(); void find_sysnames(); @@ -63,7 +65,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void list(); @@ -126,7 +128,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; s_color_table m_color_table[MUI_RESTORE]; void restore_colors(); @@ -156,15 +158,14 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; - void inkey_special(const event *menu_event); + bool inkey_special(const event *menu_event); rgb_t *m_color; std::string m_search; bool m_key_active; int m_lock_ref; - std::string m_title; }; //------------------------------------------------- @@ -178,7 +179,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; static std::pair const s_palette[]; rgb_t &m_original; diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp index 47ed1f2ca8f..35deb7ff523 100644 --- a/src/frontend/mame/ui/datmenu.cpp +++ b/src/frontend/mame/ui/datmenu.cpp @@ -166,32 +166,36 @@ void menu_dats_view::add_info_text(text_layout &layout, std::string_view text, r // handle //------------------------------------------------- -void menu_dats_view::handle(event const *ev) +bool menu_dats_view::handle(event const *ev) { - if (ev) + if (!ev) + return false; + + switch (ev->iptkey) { - switch (ev->iptkey) + case IPT_UI_LEFT: + if (m_actual > 0) { - case IPT_UI_LEFT: - if (m_actual > 0) - { - m_actual--; - reset_layout(); - } - break; - - case IPT_UI_RIGHT: - if ((m_actual + 1) < m_items_list.size()) - { - m_actual++; - reset_layout(); - } - break; - - default: - handle_key(ev->iptkey); + m_actual--; + reset_layout(); + return true; } + break; + + case IPT_UI_RIGHT: + if ((m_actual + 1) < m_items_list.size()) + { + m_actual++; + reset_layout(); + return true; + } + break; + + default: + return handle_key(ev->iptkey); } + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/datmenu.h b/src/frontend/mame/ui/datmenu.h index 680e4f0f37a..5c255c5fbff 100644 --- a/src/frontend/mame/ui/datmenu.h +++ b/src/frontend/mame/ui/datmenu.h @@ -60,7 +60,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void get_data(std::string &buffer); void get_data_sw(std::string &buffer); diff --git a/src/frontend/mame/ui/devctrl.h b/src/frontend/mame/ui/devctrl.h index ec9dc0d2928..ad89f726172 100644 --- a/src/frontend/mame/ui/devctrl.h +++ b/src/frontend/mame/ui/devctrl.h @@ -37,8 +37,8 @@ protected: int count() { return m_count; } int current_index(); - void previous(); - void next(); + bool previous(); + bool next(); std::string current_display_name(); uint32_t current_display_flags(); @@ -82,7 +82,7 @@ int menu_device_control::current_index() //------------------------------------------------- template -void menu_device_control::previous() +bool menu_device_control::previous() { // left arrow - rotate left through devices if (m_device && (1 < m_count)) @@ -96,6 +96,7 @@ void menu_device_control::previous() m_device = iter.byindex(index); reset(reset_options::REMEMBER_POSITION); } + return false; // triggers an item reset on changes anyway } @@ -104,7 +105,7 @@ void menu_device_control::previous() //------------------------------------------------- template -void menu_device_control::next() +bool menu_device_control::next() { // right arrow - rotate right through cassette devices if (m_device && (1 < m_count)) @@ -118,6 +119,7 @@ void menu_device_control::next() m_device = iter.byindex(index); reset(reset_options::REMEMBER_POSITION); } + return false; // triggers an item reset on changes anyway } diff --git a/src/frontend/mame/ui/devopt.cpp b/src/frontend/mame/ui/devopt.cpp index 9886c4e941d..0e9b44a25fc 100644 --- a/src/frontend/mame/ui/devopt.cpp +++ b/src/frontend/mame/ui/devopt.cpp @@ -359,10 +359,12 @@ void menu_device_config::populate() { } -void menu_device_config::handle(event const *ev) +bool menu_device_config::handle(event const *ev) { if (ev) - handle_key(ev->iptkey); + return handle_key(ev->iptkey); + else + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/devopt.h b/src/frontend/mame/ui/devopt.h index 05fef63240b..67500c81a41 100644 --- a/src/frontend/mame/ui/devopt.h +++ b/src/frontend/mame/ui/devopt.h @@ -29,7 +29,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; device_slot_interface::slot_option const *const m_option; bool const m_mounted; diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp index a4000dc68b7..e597b973d32 100644 --- a/src/frontend/mame/ui/dirmenu.cpp +++ b/src/frontend/mame/ui/dirmenu.cpp @@ -9,11 +9,10 @@ *********************************************************************/ #include "emu.h" +#include "ui/dirmenu.h" #include "ui/ui.h" -#include "ui/dirmenu.h" #include "ui/utils.h" -#include "ui/optsmenu.h" #include "emuopts.h" #include "fileio.h" @@ -83,7 +82,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::string m_searchpath; int const m_ref; @@ -115,7 +114,7 @@ menu_remove_folder::menu_remove_folder(mame_ui_manager &mui, render_container &c // handle //------------------------------------------------- -void menu_remove_folder::handle(event const *ev) +bool menu_remove_folder::handle(event const *ev) { // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) @@ -132,13 +131,13 @@ void menu_remove_folder::handle(event const *ev) if (ui().options().exists(f_folders[m_ref].option)) ui().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); else if (machine().options().value(f_folders[m_ref].option) != tmppath) - { machine().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); - } reset_parent(reset_options::REMEMBER_REF); stack_pop(); } + + return false; } //------------------------------------------------- @@ -172,7 +171,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void update_search(); @@ -211,86 +210,92 @@ menu_add_change_folder::menu_add_change_folder(mame_ui_manager &mui, render_cont // handle //------------------------------------------------- -void menu_add_change_folder::handle(event const *ev) +bool menu_add_change_folder::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) - { - if (ev->iptkey == IPT_UI_SELECT) - { - assert(ev->item); - menu_item const &pitem = *ev->item; + if (!ev || !ev->itemref) + return false; - // go up to the parent path - if (pitem.text() == "..") + if (ev->iptkey == IPT_UI_SELECT) + { + assert(ev->item); + menu_item const &pitem = *ev->item; + + // go up to the parent path + if (pitem.text() == "..") + { + size_t const first_sep = m_current_path.find_first_of(PATH_SEPARATOR[0]); + size_t const last_sep = m_current_path.find_last_of(PATH_SEPARATOR[0]); + m_current_path.erase(last_sep + ((first_sep == last_sep) ? 1 : 0)); + } + else + { + // if isn't a drive, appends the directory + if (pitem.subtext() != "[DRIVE]") + util::path_append(m_current_path, pitem.text()); + else + m_current_path = pitem.text(); + } + + // reset the char buffer also in this case + m_search.clear(); + reset(reset_options::SELECT_FIRST); + } + else if (ev->iptkey == IPT_UI_PASTE) + { + if (paste_text(m_search, uchar_is_printable)) + { + update_search(); + return true; + } + } + else if (ev->iptkey == IPT_SPECIAL) + { + if (ev->unichar == 0x09) + { + // Tab key, save current path + std::string error_string; + if (!m_multipath) { - size_t const first_sep = m_current_path.find_first_of(PATH_SEPARATOR[0]); - size_t const last_sep = m_current_path.find_last_of(PATH_SEPARATOR[0]); - m_current_path.erase(last_sep + ((first_sep == last_sep) ? 1 : 0)); + if (ui().options().exists(f_folders[m_ref].option)) + ui().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); + else if (machine().options().value(f_folders[m_ref].option) != m_current_path) + machine().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); } else { - // if isn't a drive, appends the directory - if (pitem.subtext() != "[DRIVE]") - util::path_append(m_current_path, pitem.text()); - else - m_current_path = pitem.text(); - } - - // reset the char buffer also in this case - m_search.clear(); - reset(reset_options::SELECT_FIRST); - } - else if (ev->iptkey == IPT_UI_PASTE) - { - if (paste_text(m_search, uchar_is_printable)) - update_search(); - } - else if (ev->iptkey == IPT_SPECIAL) - { - if (ev->unichar == 0x09) - { - // Tab key, save current path - std::string error_string; - if (!m_multipath) + m_folders.push_back(m_current_path); + std::string tmppath; + for (int x = 0; x < m_folders.size(); ++x) { - if (ui().options().exists(f_folders[m_ref].option)) - ui().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); - else if (machine().options().value(f_folders[m_ref].option) != m_current_path) - machine().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); - } - else - { - m_folders.push_back(m_current_path); - std::string tmppath; - for (int x = 0; x < m_folders.size(); ++x) - { - tmppath.append(m_folders[x]); - if (x != m_folders.size() - 1) - tmppath.append(";"); - } - - if (ui().options().exists(f_folders[m_ref].option)) - ui().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); - else if (machine().options().value(f_folders[m_ref].option) != tmppath) - machine().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); + tmppath.append(m_folders[x]); + if (x != m_folders.size() - 1) + tmppath.append(";"); } - reset_parent(reset_options::SELECT_FIRST); - stack_pop(); - } - else if (input_character(m_search, ev->unichar, uchar_is_printable)) - { - // if it's any other key and we're not maxed out, update - update_search(); + if (ui().options().exists(f_folders[m_ref].option)) + ui().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); + else if (machine().options().value(f_folders[m_ref].option) != tmppath) + machine().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); } + + reset_parent(reset_options::SELECT_FIRST); + stack_pop(); } - else if (ev->iptkey == IPT_UI_CANCEL) + else if (input_character(m_search, ev->unichar, uchar_is_printable)) { - // reset the char buffer also in this case - m_search.clear(); + // if it's any other key and we're not maxed out, update + update_search(); + return true; } } + else if (ev->iptkey == IPT_UI_CANCEL) + { + // reset the char buffer also in this case + m_search.clear(); + return true; + } + + return false; } //------------------------------------------------- @@ -451,7 +456,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool is_multipath(std::string_view folder) const; @@ -480,9 +485,8 @@ bool menu_display_actual::is_multipath(std::string_view folder) const // handle //------------------------------------------------- -void menu_display_actual::handle(event const *ev) +bool menu_display_actual::handle(event const *ev) { - // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) { switch ((uintptr_t)ev->itemref) @@ -496,6 +500,8 @@ void menu_display_actual::handle(event const *ev) break; } } + + return false; } //------------------------------------------------- @@ -589,11 +595,12 @@ menu_directory::~menu_directory() // handle //------------------------------------------------- -void menu_directory::handle(event const *ev) +bool menu_directory::handle(event const *ev) { - // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) menu::stack_push(ui(), container(), selected_index()); + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/dirmenu.h b/src/frontend/mame/ui/dirmenu.h index 209fb7953fe..54eb155267e 100644 --- a/src/frontend/mame/ui/dirmenu.h +++ b/src/frontend/mame/ui/dirmenu.h @@ -32,7 +32,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/filecreate.cpp b/src/frontend/mame/ui/filecreate.cpp index cf55499ab00..4532f2bf747 100644 --- a/src/frontend/mame/ui/filecreate.cpp +++ b/src/frontend/mame/ui/filecreate.cpp @@ -53,11 +53,11 @@ CONFIRM SAVE AS MENU // ctor //------------------------------------------------- -menu_confirm_save_as::menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool *yes) +menu_confirm_save_as::menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool &yes) : menu(mui, container) + , m_yes(yes) { - m_yes = yes; - *m_yes = false; + m_yes = false; } @@ -86,17 +86,19 @@ void menu_confirm_save_as::populate() // handle - confirm save as menu //------------------------------------------------- -void menu_confirm_save_as::handle(event const *ev) +bool menu_confirm_save_as::handle(event const *ev) { // process the event if (ev && (ev->iptkey == IPT_UI_SELECT)) { if (ev->itemref == ITEMREF_YES) - *m_yes = true; + m_yes = true; // no matter what, pop out stack_pop(); } + + return false; } @@ -207,56 +209,64 @@ void menu_file_create::populate() // handle - file creator menu //------------------------------------------------- -void menu_file_create::handle(event const *ev) +bool menu_file_create::handle(event const *ev) { - // process the event - if (ev) + if (!ev) + return false; + + // handle selections + switch (ev->iptkey) { - // handle selections - switch (ev->iptkey) + case IPT_UI_SELECT: + if ((ev->itemref == ITEMREF_CREATE) || (ev->itemref == ITEMREF_NEW_IMAGE_NAME)) { - case IPT_UI_SELECT: - if ((ev->itemref == ITEMREF_CREATE) || (ev->itemref == ITEMREF_NEW_IMAGE_NAME)) + std::string tmp_file(m_filename); + if (tmp_file.find('.') != -1 && tmp_file.find('.') < tmp_file.length() - 1) { - std::string tmp_file(m_filename); - if (tmp_file.find('.') != -1 && tmp_file.find('.') < tmp_file.length() - 1) - { - m_current_file = m_filename; - m_ok = true; - stack_pop(); - } - else - { - ui().popup_time(1, "%s", _("Please enter a file extension too")); - } + m_current_file = m_filename; + m_ok = true; + stack_pop(); } - break; - - case IPT_UI_PASTE: - if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) + else { - if (paste_text(m_filename, &osd_is_valid_filename_char)) - ev->item->set_subtext(m_filename + "_"); + ui().popup_time(1, "%s", _("Please enter a file extension too")); } - break; - - case IPT_SPECIAL: - if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) - { - if (input_character(m_filename, ev->unichar, &osd_is_valid_filename_char)) - ev->item->set_subtext(m_filename + "_"); - } - break; - - case IPT_UI_CANCEL: - if ((ev->itemref == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty()) - { - m_filename.clear(); - ev->item->set_subtext("_"); - } - break; } + break; + + case IPT_UI_PASTE: + if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) + { + if (paste_text(m_filename, &osd_is_valid_filename_char)) + { + ev->item->set_subtext(m_filename + "_"); + return true; + } + } + break; + + case IPT_SPECIAL: + if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) + { + if (input_character(m_filename, ev->unichar, &osd_is_valid_filename_char)) + { + ev->item->set_subtext(m_filename + "_"); + return true; + } + } + break; + + case IPT_UI_CANCEL: + if ((ev->itemref == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty()) + { + m_filename.clear(); + ev->item->set_subtext("_"); + return true; + } + break; } + + return false; } @@ -308,7 +318,7 @@ void menu_select_format::populate() // handle //------------------------------------------------- -void menu_select_format::handle(event const *ev) +bool menu_select_format::handle(event const *ev) { // process the menu if (ev && ev->iptkey == IPT_UI_SELECT) @@ -316,6 +326,8 @@ void menu_select_format::handle(event const *ev) *m_result = (floppy_image_format_t *)ev->itemref; stack_pop(); } + + return false; } @@ -362,7 +374,7 @@ void menu_select_floppy_init::populate() // handle //------------------------------------------------- -void menu_select_floppy_init::handle(event const *ev) +bool menu_select_floppy_init::handle(event const *ev) { // process the menu if (ev && ev->iptkey == IPT_UI_SELECT) @@ -370,6 +382,8 @@ void menu_select_floppy_init::handle(event const *ev) *m_result = int(uintptr_t(ev->itemref)); stack_pop(); } + + return false; } diff --git a/src/frontend/mame/ui/filecreate.h b/src/frontend/mame/ui/filecreate.h index c4ef529168b..9537003a6f7 100644 --- a/src/frontend/mame/ui/filecreate.h +++ b/src/frontend/mame/ui/filecreate.h @@ -27,14 +27,14 @@ namespace ui { class menu_confirm_save_as : public menu { public: - menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool *yes); + menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool &yes); virtual ~menu_confirm_save_as() override; private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; - bool *m_yes; + bool &m_yes; }; @@ -53,7 +53,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool & m_ok; device_image_interface * m_image; @@ -74,7 +74,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal state std::vector m_formats; @@ -93,7 +93,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal state std::vector> m_fs; diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp index 81540b568b0..47cfd7be4fa 100644 --- a/src/frontend/mame/ui/filemngr.cpp +++ b/src/frontend/mame/ui/filemngr.cpp @@ -171,31 +171,32 @@ void menu_file_manager::populate() // handle //------------------------------------------------- -void menu_file_manager::handle(event const *ev) +bool menu_file_manager::handle(event const *ev) { - // process the menu - if (ev && ev->itemref && (ev->iptkey == IPT_UI_SELECT)) - { - if ((uintptr_t)ev->itemref == 1) - { - machine().schedule_hard_reset(); - } - else - { - selected_device = (device_image_interface *) ev->itemref; - if (selected_device) - { - floppy_image_device *floppy_device = dynamic_cast(selected_device); - if (floppy_device) - menu::stack_push(ui(), container(), *floppy_device); - else - menu::stack_push(ui(), container(), *selected_device); + if (!ev || !ev->itemref || (ev->iptkey != IPT_UI_SELECT)) + return false; - // reset the existing menu - reset(reset_options::REMEMBER_POSITION); - } + if ((uintptr_t)ev->itemref == 1) + { + machine().schedule_hard_reset(); + } + else + { + selected_device = (device_image_interface *) ev->itemref; + if (selected_device) + { + floppy_image_device *floppy_device = dynamic_cast(selected_device); + if (floppy_device) + menu::stack_push(ui(), container(), *floppy_device); + else + menu::stack_push(ui(), container(), *selected_device); + + // reset the existing menu + reset(reset_options::REMEMBER_POSITION); } } + + return false; } // force file manager menu diff --git a/src/frontend/mame/ui/filemngr.h b/src/frontend/mame/ui/filemngr.h index a2368e5a959..2c0be45449c 100644 --- a/src/frontend/mame/ui/filemngr.h +++ b/src/frontend/mame/ui/filemngr.h @@ -35,7 +35,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void fill_image_line(device_image_interface *img, std::string &instance, std::string &filename); diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp index e12beadb8eb..f43ddeac007 100644 --- a/src/frontend/mame/ui/filesel.cpp +++ b/src/frontend/mame/ui/filesel.cpp @@ -446,40 +446,49 @@ void menu_file_selector::populate() // handle //------------------------------------------------- -void menu_file_selector::handle(event const *ev) +bool menu_file_selector::handle(event const *ev) { - // process the menu - if (ev) - { - if (ev->iptkey == IPT_SPECIAL) - { - // if it's any other key and we're not maxed out, update - if (input_character(m_filename, ev->unichar, uchar_is_printable)) - update_search(); - } - else if (ev->iptkey == IPT_UI_PASTE) - { - if (paste_text(m_filename, uchar_is_printable)) - update_search(); - } - else if (ev->iptkey == IPT_UI_CANCEL) - { - // reset the char buffer also in this case - if (!m_filename.empty()) - { - m_filename.clear(); - ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename); - } - } - else if (ev->itemref && (ev->iptkey == IPT_UI_SELECT)) - { - // handle selections - select_item(*reinterpret_cast(ev->itemref)); + if (!ev) + return false; - // reset the char buffer when pressing IPT_UI_SELECT - m_filename.clear(); + if (ev->iptkey == IPT_SPECIAL) + { + // if it's any other key and we're not maxed out, update + if (input_character(m_filename, ev->unichar, uchar_is_printable)) + { + update_search(); + return true; } } + else if (ev->iptkey == IPT_UI_PASTE) + { + if (paste_text(m_filename, uchar_is_printable)) + { + update_search(); + return true; + } + } + else if (ev->iptkey == IPT_UI_CANCEL) + { + // reset the char buffer also in this case + if (!m_filename.empty()) + { + m_filename.clear(); + ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename); + return true; + } + } + else if (ev->itemref && (ev->iptkey == IPT_UI_SELECT)) + { + // handle selections + select_item(*reinterpret_cast(ev->itemref)); + + // reset the char buffer when pressing IPT_UI_SELECT + m_filename.clear(); + return true; + } + + return false; } @@ -529,14 +538,15 @@ void menu_select_rw::populate() // handle //------------------------------------------------- -void menu_select_rw::handle(event const *ev) +bool menu_select_rw::handle(event const *ev) { - // process the menu if (ev && ev->iptkey == IPT_UI_SELECT) { m_result = result_from_itemref(ev->itemref); stack_pop(); } + + return false; } diff --git a/src/frontend/mame/ui/filesel.h b/src/frontend/mame/ui/filesel.h index f8968f798c9..8bef06e53ca 100644 --- a/src/frontend/mame/ui/filesel.h +++ b/src/frontend/mame/ui/filesel.h @@ -84,7 +84,7 @@ private: std::string m_filename; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // methods file_selector_entry &append_entry(file_selector_entry_type entry_type, const std::string &entry_basename, const std::string &entry_fullpath); @@ -121,7 +121,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal state bool m_can_in_place; diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp index 174b8bab9e6..053da006a43 100644 --- a/src/frontend/mame/ui/imgcntrl.cpp +++ b/src/frontend/mame/ui/imgcntrl.cpp @@ -12,20 +12,22 @@ #include "ui/imgcntrl.h" -#include "ui/ui.h" -#include "ui/filesel.h" #include "ui/filecreate.h" +#include "ui/filesel.h" #include "ui/swlist.h" +#include "ui/ui.h" #include "audit.h" #include "drivenum.h" #include "emuopts.h" #include "image.h" #include "softlist_dev.h" -#include "zippath.h" + +#include "util/zippath.h" namespace ui { + /*************************************************************************** IMPLEMENTATION ***************************************************************************/ @@ -194,7 +196,7 @@ void menu_control_device_image::populate() // handle //------------------------------------------------- -void menu_control_device_image::handle(event const *ev) +bool menu_control_device_image::handle(event const *ev) { throw emu_fatalerror("menu_control_device_image::handle: Shouldn't get here!"); } @@ -338,7 +340,7 @@ void menu_control_device_image::menu_activated() { if (need_confirm) { - menu::stack_push(ui(), container(), &m_create_confirmed); + menu::stack_push(ui(), container(), m_create_confirmed); m_state = CREATE_CONFIRM; } else diff --git a/src/frontend/mame/ui/imgcntrl.h b/src/frontend/mame/ui/imgcntrl.h index 80b4548686a..22911f70141 100644 --- a/src/frontend/mame/ui/imgcntrl.h +++ b/src/frontend/mame/ui/imgcntrl.h @@ -56,7 +56,7 @@ protected: // methods virtual void menu_activated() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void hook_load(const std::string &filename); private: diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp index 32575133a24..1a19fd10c49 100644 --- a/src/frontend/mame/ui/info.cpp +++ b/src/frontend/mame/ui/info.cpp @@ -552,10 +552,9 @@ void menu_game_info::populate() { } -void menu_game_info::handle(event const *ev) +bool menu_game_info::handle(event const *ev) { - if (ev) - handle_key(ev->iptkey); + return ev && handle_key(ev->iptkey); } @@ -617,10 +616,9 @@ void menu_warn_info::populate() { } -void menu_warn_info::handle(event const *ev) +bool menu_warn_info::handle(event const *ev) { - if (ev) - handle_key(ev->iptkey); + return ev && handle_key(ev->iptkey); } @@ -648,8 +646,9 @@ void menu_image_info::populate() image_info(&image); } -void menu_image_info::handle(event const *ev) +bool menu_image_info::handle(event const *ev) { + return false; } diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h index d36c476c7b5..4d5e5e434b7 100644 --- a/src/frontend/mame/ui/info.h +++ b/src/frontend/mame/ui/info.h @@ -101,7 +101,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -116,7 +116,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -131,7 +131,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void image_info(device_image_interface *image); }; diff --git a/src/frontend/mame/ui/info_pty.cpp b/src/frontend/mame/ui/info_pty.cpp index 018c3bc9b61..6aa4826e241 100644 --- a/src/frontend/mame/ui/info_pty.cpp +++ b/src/frontend/mame/ui/info_pty.cpp @@ -39,8 +39,9 @@ void menu_pty_info::populate() } } -void menu_pty_info::handle(event const *ev) +bool menu_pty_info::handle(event const *ev) { + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/info_pty.h b/src/frontend/mame/ui/info_pty.h index af384a5a92d..203209fddc4 100644 --- a/src/frontend/mame/ui/info_pty.h +++ b/src/frontend/mame/ui/info_pty.h @@ -25,7 +25,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/inputdevices.cpp b/src/frontend/mame/ui/inputdevices.cpp index 4890b1ac724..0fe8de2a1c0 100644 --- a/src/frontend/mame/ui/inputdevices.cpp +++ b/src/frontend/mame/ui/inputdevices.cpp @@ -139,7 +139,7 @@ private: set_custom_space(0.0F, (line_height() * (m_have_analog ? 2.0F : 1.0F)) + (tb_border() * 3.0F)); } - virtual void handle(event const *ev) override + virtual bool handle(event const *ev) override { // FIXME: hacky, depending on first item being "copy ID", but need a better model for item reference values if (ev && ev->item && (IPT_UI_SELECT == ev->iptkey) && (&item(0) == ev->item)) @@ -150,15 +150,23 @@ private: machine().popmessage(_("menu-inputdev", "Error copying device ID to clipboard")); } + bool updated = false; for (int i = 0; item_count() > i; ++i) { void *const ref(item(i).ref()); if (ref) { input_device_item &input = *reinterpret_cast(ref); - item(i).set_subtext(format_value(input)); + std::string value(format_value(input)); + if (item(i).subtext() != value) + { + item(i).set_subtext(std::move(value)); + updated = true; + } } } + + return updated; } static std::string format_value(input_device_item &input) @@ -233,68 +241,70 @@ void menu_input_devices::populate() } -void menu_input_devices::handle(event const *ev) +bool menu_input_devices::handle(event const *ev) { - if (ev && ev->itemref) - { - input_device &dev = *reinterpret_cast(ev->itemref); - switch (ev->iptkey) - { - case IPT_UI_SELECT: - stack_push(ui(), container(), dev); - break; + if (!ev || !ev->itemref) + return false; - case IPT_UI_PREV_GROUP: + input_device &dev = *reinterpret_cast(ev->itemref); + switch (ev->iptkey) + { + case IPT_UI_SELECT: + stack_push(ui(), container(), dev); + break; + + case IPT_UI_PREV_GROUP: + { + auto group = dev.devclass(); + bool found_break = false; + int target = 0; + for (auto i = selected_index(); 0 < i--; ) { - auto group = dev.devclass(); - bool found_break = false; - int target = 0; - for (auto i = selected_index(); 0 < i--; ) + input_device *const candidate = reinterpret_cast(item(i).ref()); + if (candidate) { - input_device *const candidate = reinterpret_cast(item(i).ref()); - if (candidate) + if (candidate->devclass() == group) { - if (candidate->devclass() == group) - { - target = i; - } - else if (!found_break) - { - group = candidate->devclass(); - found_break = true; - target = i; - } - else - { - set_selected_index(target); - break; - } + target = i; } - if (!i && found_break) + else if (!found_break) + { + group = candidate->devclass(); + found_break = true; + target = i; + } + else { set_selected_index(target); - break; + return true; } } - } - break; - - case IPT_UI_NEXT_GROUP: - { - auto const group = dev.devclass(); - for (auto i = selected_index(); item_count() > ++i; ) + if (!i && found_break) { - input_device *const candidate = reinterpret_cast(item(i).ref()); - if (candidate && (candidate->devclass() != group)) - { - set_selected_index(i); - break; - } + set_selected_index(target); + return true; } } - break; } + break; + + case IPT_UI_NEXT_GROUP: + { + auto const group = dev.devclass(); + for (auto i = selected_index(); item_count() > ++i; ) + { + input_device *const candidate = reinterpret_cast(item(i).ref()); + if (candidate && (candidate->devclass() != group)) + { + set_selected_index(i); + return true; + } + } + } + break; } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/inputdevices.h b/src/frontend/mame/ui/inputdevices.h index 39d2afda4e5..3d4bfb51e4e 100644 --- a/src/frontend/mame/ui/inputdevices.h +++ b/src/frontend/mame/ui/inputdevices.h @@ -26,7 +26,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp index 4fa6ffab25b..b5b56b6e1fb 100644 --- a/src/frontend/mame/ui/inputmap.cpp +++ b/src/frontend/mame/ui/inputmap.cpp @@ -46,9 +46,8 @@ void menu_input_groups::populate() item_append(menu_item_type::SEPARATOR); } -void menu_input_groups::handle(event const *ev) +bool menu_input_groups::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT)) { menu::stack_push( @@ -57,6 +56,8 @@ void menu_input_groups::handle(event const *ev) int(uintptr_t(ev->itemref) - 1), util::string_format(_("Input Assignments (%1$s)"), ev->item->text())); } + + return false; } @@ -377,10 +378,11 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float } } -void menu_input::handle(event const *ev) +bool menu_input::handle(event const *ev) { input_item_data *seqchangeditem = nullptr; bool invalidate = false; + bool redraw = false; // process the menu if (pollingitem) @@ -421,6 +423,11 @@ void menu_input::handle(event const *ev) seq_poll.reset(); machine().ui_input().reset(); } + else + { + // always redraw to ensure it updates as soon as possible in response to changes + redraw = true; + } } else if (ev && ev->itemref) { @@ -516,6 +523,7 @@ void menu_input::handle(event const *ev) } record_next = false; lastitem = &item; + redraw = true; } // flip between set and append @@ -531,6 +539,7 @@ void menu_input::handle(event const *ev) { record_next = !record_next; } + redraw = true; } } @@ -546,6 +555,8 @@ void menu_input::handle(event const *ev) // if the menu is invalidated, clear it now if (invalidate) reset(reset_options::REMEMBER_POSITION); + + return redraw && !invalidate; } diff --git a/src/frontend/mame/ui/inputmap.h b/src/frontend/mame/ui/inputmap.h index d512b670345..e5947a9b649 100644 --- a/src/frontend/mame/ui/inputmap.h +++ b/src/frontend/mame/ui/inputmap.h @@ -29,7 +29,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -84,7 +84,7 @@ private: osd_ticks_t modified_ticks; input_seq starting_seq; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void update_input(input_item_data &seqchangeditem) = 0; }; diff --git a/src/frontend/mame/ui/inputopts.cpp b/src/frontend/mame/ui/inputopts.cpp index e4802e8de8f..48db7698e71 100644 --- a/src/frontend/mame/ui/inputopts.cpp +++ b/src/frontend/mame/ui/inputopts.cpp @@ -111,7 +111,7 @@ void menu_input_options::populate() } -void menu_input_options::handle(event const *ev) +bool menu_input_options::handle(event const *ev) { if (ev && (IPT_UI_SELECT == ev->iptkey)) { @@ -137,6 +137,8 @@ void menu_input_options::handle(event const *ev) break; } } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/inputopts.h b/src/frontend/mame/ui/inputopts.h index 7cff7713537..bf6afebabf5 100644 --- a/src/frontend/mame/ui/inputopts.h +++ b/src/frontend/mame/ui/inputopts.h @@ -29,7 +29,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/inputtoggle.cpp b/src/frontend/mame/ui/inputtoggle.cpp index 172ae16b141..7a307c01c66 100644 --- a/src/frontend/mame/ui/inputtoggle.cpp +++ b/src/frontend/mame/ui/inputtoggle.cpp @@ -110,109 +110,111 @@ void menu_input_toggles::populate() } -void menu_input_toggles::handle(event const *ev) +bool menu_input_toggles::handle(event const *ev) { - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + auto const ref = reinterpret_cast *>(ev->itemref); + ioport_field &field = ref->get(); + bool invalidate = false; + switch (ev->iptkey) { - auto const ref = reinterpret_cast *>(ev->itemref); - ioport_field &field = ref->get(); - bool invalidate = false; - switch (ev->iptkey) + case IPT_UI_SELECT: // toggle regular items, cycle multi-value items + if (field.settings().empty()) + field.live().value ^= field.mask(); + else + field.select_next_setting(); + invalidate = true; + break; + + case IPT_UI_CLEAR: // set to default + if (field.defvalue() != field.live().value) { - case IPT_UI_SELECT: // toggle regular items, cycle multi-value items - if (field.settings().empty()) - field.live().value ^= field.mask(); - else - field.select_next_setting(); + field.live().value = field.defvalue(); invalidate = true; - break; + } + break; - case IPT_UI_CLEAR: // set to default - if (field.defvalue() != field.live().value) + case IPT_UI_LEFT: // toggle or select previous setting + if (field.settings().empty()) + field.live().value ^= field.mask(); + else + field.select_previous_setting(); + invalidate = true; + break; + + case IPT_UI_RIGHT: // toggle or select next setting + if (field.settings().empty()) + field.live().value ^= field.mask(); + else + field.select_next_setting(); + invalidate = true; + break; + + case IPT_UI_PREV_GROUP: // previous device if any + { + auto current = std::distance(m_fields.data(), ref); + device_t const *dev = &field.device(); + bool found_break = false; + void *candidate = nullptr; + while (0 < current) { - field.live().value = field.defvalue(); - invalidate = true; - } - break; - - case IPT_UI_LEFT: // toggle or select previous setting - if (field.settings().empty()) - field.live().value ^= field.mask(); - else - field.select_previous_setting(); - invalidate = true; - break; - - case IPT_UI_RIGHT: // toggle or select next setting - if (field.settings().empty()) - field.live().value ^= field.mask(); - else - field.select_next_setting(); - invalidate = true; - break; - - case IPT_UI_PREV_GROUP: // previous device if any - { - auto current = std::distance(m_fields.data(), ref); - device_t const *dev = &field.device(); - bool found_break = false; - void *candidate = nullptr; - while (0 < current) + if (!found_break) { - if (!found_break) + if (m_fields[--current].get().enabled()) { - if (m_fields[--current].get().enabled()) + device_t const *prev = &m_fields[current].get().device(); + if (prev != dev) { - device_t const *prev = &m_fields[current].get().device(); - if (prev != dev) - { - dev = prev; - found_break = true; - candidate = &m_fields[current]; - } + dev = prev; + found_break = true; + candidate = &m_fields[current]; } } - else if (&m_fields[--current].get().device() != dev) - { - set_selection(candidate); - set_top_line(selected_index() - 1); - break; - } - else if (m_fields[current].get().enabled()) - { - candidate = &m_fields[current]; - } - if (found_break && !current) - { - set_selection(candidate); - set_top_line(selected_index() - 1); - break; - } } - } - break; - - case IPT_UI_NEXT_GROUP: // next device if any - { - auto current = std::distance(m_fields.data(), ref); - device_t const *const dev = &field.device(); - while (m_fields.size() > ++current) + else if (&m_fields[--current].get().device() != dev) { - if (m_fields[current].get().enabled() && (&m_fields[current].get().device() != dev)) - { - set_selection(&m_fields[current]); - set_top_line(selected_index() - 1); - break; - } + set_selection(candidate); + set_top_line(selected_index() - 1); + return true; + } + else if (m_fields[current].get().enabled()) + { + candidate = &m_fields[current]; + } + if (found_break && !current) + { + set_selection(candidate); + set_top_line(selected_index() - 1); + return true; } } - break; } + break; - // changing value can enable or disable other fields - if (invalidate) - reset(reset_options::REMEMBER_REF); + case IPT_UI_NEXT_GROUP: // next device if any + { + auto current = std::distance(m_fields.data(), ref); + device_t const *const dev = &field.device(); + while (m_fields.size() > ++current) + { + if (m_fields[current].get().enabled() && (&m_fields[current].get().device() != dev)) + { + set_selection(&m_fields[current]); + set_top_line(selected_index() - 1); + return true; + } + } + } + break; } + + // changing value can enable or disable other fields + if (invalidate) + reset(reset_options::REMEMBER_REF); + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/inputtoggle.h b/src/frontend/mame/ui/inputtoggle.h index b4d48908d96..676be71e58d 100644 --- a/src/frontend/mame/ui/inputtoggle.h +++ b/src/frontend/mame/ui/inputtoggle.h @@ -32,7 +32,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector > m_fields; }; diff --git a/src/frontend/mame/ui/keyboard.cpp b/src/frontend/mame/ui/keyboard.cpp index 931ff96f046..9eaeb5c94ee 100644 --- a/src/frontend/mame/ui/keyboard.cpp +++ b/src/frontend/mame/ui/keyboard.cpp @@ -71,47 +71,51 @@ menu_keyboard_mode::~menu_keyboard_mode() { } -void menu_keyboard_mode::handle(event const *ev) +bool menu_keyboard_mode::handle(event const *ev) { - if (ev && uintptr_t(ev->itemref)) + if (!ev || !uintptr_t(ev->itemref)) + return false; + + natural_keyboard &natkbd(machine().natkeyboard()); + uintptr_t const ref(uintptr_t(ev->itemref)); + bool left(IPT_UI_LEFT == ev->iptkey); + bool right(IPT_UI_RIGHT == ev->iptkey); + if (ITEM_KBMODE == ref) { - natural_keyboard &natkbd(machine().natkeyboard()); - uintptr_t const ref(uintptr_t(ev->itemref)); - bool left(IPT_UI_LEFT == ev->iptkey); - bool right(IPT_UI_RIGHT == ev->iptkey); - if (ITEM_KBMODE == ref) + if (IPT_UI_SELECT == ev->iptkey) { - if (IPT_UI_SELECT == ev->iptkey) - { - left = natkbd.in_use(); - right = !left; - } - if ((left || right) && (natkbd.in_use() != right)) - { - natkbd.set_in_use(right); - ev->item->set_subtext(right ? _("menu-keyboard", "Natural") : _("menu-keyboard", "Emulated")); - ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); - } + left = natkbd.in_use(); + right = !left; } - else if (ITEM_KBDEV_FIRST <= ref) + if ((left || right) && (natkbd.in_use() != right)) { - auto const kbdno(ref - ITEM_KBDEV_FIRST); - if (IPT_UI_SELECT == ev->iptkey) - { - left = natkbd.keyboard_enabled(kbdno); - right = !left; - } - if ((left || right) && (natkbd.keyboard_enabled(kbdno) != right)) - { - if (right) - natkbd.enable_keyboard(kbdno); - else - natkbd.disable_keyboard(kbdno); - ev->item->set_subtext(right ? _("Enabled") : _("Disabled")); - ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); - } + natkbd.set_in_use(right); + ev->item->set_subtext(right ? _("menu-keyboard", "Natural") : _("menu-keyboard", "Emulated")); + ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; } } + else if (ITEM_KBDEV_FIRST <= ref) + { + auto const kbdno(ref - ITEM_KBDEV_FIRST); + if (IPT_UI_SELECT == ev->iptkey) + { + left = natkbd.keyboard_enabled(kbdno); + right = !left; + } + if ((left || right) && (natkbd.keyboard_enabled(kbdno) != right)) + { + if (right) + natkbd.enable_keyboard(kbdno); + else + natkbd.disable_keyboard(kbdno); + ev->item->set_subtext(right ? _("Enabled") : _("Disabled")); + ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; + } + } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/keyboard.h b/src/frontend/mame/ui/keyboard.h index 478d97a5a11..dd51e6c9d1e 100644 --- a/src/frontend/mame/ui/keyboard.h +++ b/src/frontend/mame/ui/keyboard.h @@ -28,7 +28,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp index 7d53266e65b..240ac30f1ee 100644 --- a/src/frontend/mame/ui/mainmenu.cpp +++ b/src/frontend/mame/ui/mainmenu.cpp @@ -206,7 +206,7 @@ void menu_main::populate() handle - handle main menu events -------------------------------------------------*/ -void menu_main::handle(event const *ev) +bool menu_main::handle(event const *ev) { // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT)) @@ -321,12 +321,14 @@ void menu_main::handle(event const *ev) case DISMISS: stack_pop(); - return; + break; default: fatalerror("ui::menu_main::handle - unknown reference\n"); } } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/mainmenu.h b/src/frontend/mame/ui/mainmenu.h index de596716da6..d34da5e009e 100644 --- a/src/frontend/mame/ui/mainmenu.h +++ b/src/frontend/mame/ui/mainmenu.h @@ -29,7 +29,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; machine_phase m_phase; }; diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp index c945b3f0297..f3273752299 100644 --- a/src/frontend/mame/ui/menu.cpp +++ b/src/frontend/mame/ui/menu.cpp @@ -195,8 +195,7 @@ uint32_t menu::global_state::ui_handler(render_container &container) // update the menu state m_hide = false; - if (m_stack) - m_stack->do_handle(); + bool need_update = m_stack && m_stack->do_handle(); // clear up anything pending being released clear_free_list(); @@ -216,10 +215,10 @@ uint32_t menu::global_state::ui_handler(render_container &container) m_stack->menu_deactivated(); } } - return UI_HANDLER_CANCEL; + return mame_ui_manager::HANDLER_CANCEL; } - return 0; + return need_update ? mame_ui_manager::HANDLER_UPDATE : 0; } @@ -392,7 +391,7 @@ void menu::set_custom_space(float top, float bottom) // and returning any interesting events //------------------------------------------------- -const menu::event *menu::process() +std::pair menu::process() { // reset the event m_event.iptkey = IPT_INVALID; @@ -414,6 +413,8 @@ const menu::event *menu::process() container().add_rect(0.0F, 0.0F, 1.0F, 1.0F, rgb_t(114, 0, 0, 0), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // draw the menu proper + // FIXME: this should happen after processing events to fix the egregious latency + // The main thing preventing this is that mouse handling is mixed up with drawing draw(m_process_flags); // process input @@ -432,11 +433,11 @@ const menu::event *menu::process() { m_event.itemref = get_selection_ref(); m_event.item = &m_items[m_selected]; - return &m_event; + return std::make_pair(&m_event, false); } else { - return nullptr; + return std::make_pair(nullptr, false); } } @@ -1250,8 +1251,10 @@ void menu::validate_selection(int scandir) MENU STACK MANAGEMENT ***************************************************************************/ -void menu::do_handle() +bool menu::do_handle() { + bool need_update = false; + // let OSD do its thing machine().osd().check_osd_inputs(); @@ -1265,6 +1268,7 @@ void menu::do_handle() m_last_size = uisize; m_last_aspect = aspect; recompute_metrics(uisize.first, uisize.second, aspect); + need_update = true; } if (m_items.empty()) @@ -1278,6 +1282,7 @@ void menu::do_handle() // let implementation add other items populate(); + need_update = true; } catch (...) { @@ -1287,7 +1292,11 @@ void menu::do_handle() } m_rebuilding = false; } - handle(process()); + + auto [eventptr, changed] = process(); + need_update = need_update || changed; + need_update = handle(eventptr) || need_update; + return need_update; } diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h index 16223ebebd8..eeeb7ae6eb3 100644 --- a/src/frontend/mame/ui/menu.h +++ b/src/frontend/mame/ui/menu.h @@ -102,7 +102,7 @@ public: // Used by sliders void validate_selection(int scandir); - void do_handle(); + bool do_handle(); protected: using bitmap_ptr = widgets_manager::bitmap_ptr; @@ -418,7 +418,7 @@ private: }; // process a menu, drawing it and returning any interesting events - const event *process(); + std::pair process(); virtual void draw(uint32_t flags); // request the specific handling of the game selection main menu @@ -428,7 +428,7 @@ private: virtual void populate() = 0; // to be implemented in derived classes - virtual void handle(event const *ev) = 0; + virtual bool handle(event const *ev) = 0; void extra_text_draw_box(float origx1, float origx2, float origy, float yspan, std::string_view text, int direction); diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp index 9839d59a966..6a41da2f070 100644 --- a/src/frontend/mame/ui/miscmenu.cpp +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -90,57 +90,64 @@ menu_bios_selection::~menu_bios_selection() menu_bios_selection - menu that -------------------------------------------------*/ -void menu_bios_selection::handle(event const *ev) +bool menu_bios_selection::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + if ((uintptr_t)ev->itemref == 1 && ev->iptkey == IPT_UI_SELECT) { - if ((uintptr_t)ev->itemref == 1 && ev->iptkey == IPT_UI_SELECT) - machine().schedule_hard_reset(); + machine().schedule_hard_reset(); + return false; + } + + device_t *const dev = (device_t *)ev->itemref; + int bios_val = 0; + + switch (ev->iptkey) + { + // reset to default + case IPT_UI_CLEAR: + bios_val = dev->default_bios(); + break; + + // previous/next BIOS setting + case IPT_UI_SELECT: + case IPT_UI_LEFT: + case IPT_UI_RIGHT: + { + int const cnt = ([bioses = romload::entries(dev->rom_region()).get_system_bioses()] () { return std::distance(bioses.begin(), bioses.end()); })(); + bios_val = dev->system_bios() + ((ev->iptkey == IPT_UI_LEFT) ? -1 : +1); + + // wrap + if (bios_val < 1) + bios_val = cnt; + if (bios_val > cnt) + bios_val = 1; + } + break; + + default: + break; + } + + if (bios_val > 0) + { + dev->set_system_bios(bios_val); + if (!strcmp(dev->tag(), ":")) + { + machine().options().set_value("bios", bios_val - 1, OPTION_PRIORITY_CMDLINE); + } else { - device_t *dev = (device_t *)ev->itemref; - int bios_val = 0; - - switch (ev->iptkey) - { - // reset to default - case IPT_UI_SELECT: - bios_val = dev->default_bios(); - break; - - // previous/next bios setting - case IPT_UI_LEFT: case IPT_UI_RIGHT: - { - int const cnt = ([bioses = romload::entries(dev->rom_region()).get_system_bioses()] () { return std::distance(bioses.begin(), bioses.end()); })(); - bios_val = dev->system_bios() + ((ev->iptkey == IPT_UI_LEFT) ? -1 : +1); - - // wrap - if (bios_val < 1) - bios_val = cnt; - if (bios_val > cnt) - bios_val = 1; - - break; - } - - default: - break; - } - - if (bios_val > 0) - { - dev->set_system_bios(bios_val); - if (strcmp(dev->tag(),":")==0) { - machine().options().set_value("bios", bios_val-1, OPTION_PRIORITY_CMDLINE); - } else { - const char *slot_option_name = dev->owner()->tag() + 1; - machine().options().slot_option(slot_option_name).set_bios(string_format("%d", bios_val - 1)); - } - reset(reset_options::REMEMBER_REF); - } + const char *slot_option_name = dev->owner()->tag() + 1; + machine().options().slot_option(slot_option_name).set_bios(string_format("%d", bios_val - 1)); } + reset(reset_options::REMEMBER_REF); } + + // triggers an item reset for any change + return false; } @@ -166,15 +173,16 @@ void menu_network_devices::populate() { int curr = network.get_interface(); const char *title = nullptr; - for(auto &entry : get_netdev_list()) + for (auto &entry : get_netdev_list()) { - if(entry->id==curr) { + if (entry->id == curr) + { title = entry->description; break; } } - item_append(network.device().tag(), (title) ? title : "------", FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, (void *)&network); + item_append(network.device().tag(), title ? title : "------", FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, (void *)&network); } item_append(menu_item_type::SEPARATOR); @@ -184,24 +192,41 @@ void menu_network_devices::populate() menu_network_devices - menu that -------------------------------------------------*/ -void menu_network_devices::handle(event const *ev) +bool menu_network_devices::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) { - if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) + return false; + } + else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) + { + device_network_interface *const network = (device_network_interface *)ev->itemref; + int curr = network->get_interface(); + if (ev->iptkey == IPT_UI_LEFT) + curr--; + else + curr++; + if (curr == -2) + curr = netdev_count() - 1; + network->set_interface(curr); + + curr = network->get_interface(); + const char *title = nullptr; + for (auto &entry : get_netdev_list()) { - device_network_interface *network = (device_network_interface *)ev->itemref; - int curr = network->get_interface(); - if (ev->iptkey == IPT_UI_LEFT) - curr--; - else - curr++; - if (curr == -2) - curr = netdev_count() - 1; - network->set_interface(curr); - reset(reset_options::REMEMBER_REF); + if (entry->id == curr) + { + title = entry->description; + break; + } } + + ev->item->set_subtext(title ? title : "------"); + return true; + } + else + { + return false; } } @@ -272,16 +297,20 @@ void menu_bookkeeping::populate() { } -void menu_bookkeeping::handle(event const *ev) +bool menu_bookkeeping::handle(event const *ev) { // if the time has rolled over another second, regenerate // TODO: what about other bookkeeping events happening with the menu open? attotime const curtime = machine().time(); if (curtime.seconds() != prevtime.seconds()) + { reset_layout(); - - if (ev) - handle_key(ev->iptkey); + return true; + } + else + { + return ev && handle_key(ev->iptkey); + } } @@ -290,7 +319,7 @@ void menu_bookkeeping::handle(event const *ev) menu -------------------------------------------------*/ -void menu_crosshair::handle(event const *ev) +bool menu_crosshair::handle(event const *ev) { // handle events if (ev && ev->itemref) @@ -383,6 +412,9 @@ void menu_crosshair::handle(event const *ev) if (changed) reset(reset_options::REMEMBER_REF); // rebuild the menu } + + // triggers an item reset for any changes + return false; } @@ -601,7 +633,7 @@ menu_export::~menu_export() // handle the export menu //------------------------------------------------- -void menu_export::handle(event const *ev) +bool menu_export::handle(event const *ev) { // process the menu if (ev && ev->itemref) @@ -640,7 +672,7 @@ void menu_export::handle(event const *ev) auto iter = std::find_if( driver_list.begin(), driver_list.end(), - [shortname](const game_driver *driver) { return !strcmp(shortname, driver->name); }); + [shortname] (const game_driver *driver) { return !strcmp(shortname, driver->name); }); return iter != driver_list.end(); }; @@ -695,6 +727,8 @@ void menu_export::handle(event const *ev) break; } } + + return false; } //------------------------------------------------- @@ -752,7 +786,7 @@ menu_machine_configure::~menu_machine_configure() // handle the machine options menu //------------------------------------------------- -void menu_machine_configure::handle(event const *ev) +bool menu_machine_configure::handle(event const *ev) { // process the menu if (ev && ev->itemref) @@ -805,6 +839,9 @@ void menu_machine_configure::handle(event const *ev) reset(reset_options::REMEMBER_POSITION); } } + + // triggers an item reset for any changes + return false; } //------------------------------------------------- @@ -905,25 +942,25 @@ menu_plugins_configure::~menu_plugins_configure() // handle the plugins menu //------------------------------------------------- -void menu_plugins_configure::handle(event const *ev) +bool menu_plugins_configure::handle(event const *ev) { - // process the menu - bool changed = false; - plugin_options &plugins = mame_machine_manager::instance()->plugins(); - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT) { - if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT) + plugin_options &plugins = mame_machine_manager::instance()->plugins(); + plugin_options::plugin *p = plugins.find((const char*)ev->itemref); + if (p) { - plugin_options::plugin *p = plugins.find((const char*)ev->itemref); - if (p) - { - p->m_start = !p->m_start; - changed = true; - } + p->m_start = !p->m_start; + ev->item->set_subtext(p->m_start ? _("On") : _("Off")); + ev->item->set_flags(p->m_start ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; } } - if (changed) - reset(reset_options::REMEMBER_REF); + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/miscmenu.h b/src/frontend/mame/ui/miscmenu.h index ab763b7ed26..6d365ddba67 100644 --- a/src/frontend/mame/ui/miscmenu.h +++ b/src/frontend/mame/ui/miscmenu.h @@ -34,7 +34,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; class menu_bookkeeping : public menu_textbox @@ -49,7 +49,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; attotime prevtime; }; @@ -82,7 +82,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector m_data; std::vector m_pics; @@ -97,7 +97,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -113,7 +113,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector m_list; }; @@ -149,7 +149,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void setup_bios(); @@ -175,7 +175,7 @@ public: protected: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp index 91e5fb52adb..07178b2cae4 100644 --- a/src/frontend/mame/ui/optsmenu.cpp +++ b/src/frontend/mame/ui/optsmenu.cpp @@ -60,11 +60,9 @@ menu_simple_game_options::~menu_simple_game_options() // handle //------------------------------------------------- -void menu_simple_game_options::handle(event const *ev) +bool menu_simple_game_options::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) - handle_item_event(*ev); + return ev && ev->itemref && handle_item_event(*ev); } //------------------------------------------------- @@ -91,7 +89,7 @@ void menu_simple_game_options::populate() // handle item //------------------------------------------------- -void menu_simple_game_options::handle_item_event(event const &menu_event) +bool menu_simple_game_options::handle_item_event(event const &menu_event) { if (IPT_UI_SELECT == menu_event.iptkey) { @@ -130,6 +128,7 @@ void menu_simple_game_options::handle_item_event(event const &menu_event) break; } } + return false; } @@ -161,11 +160,9 @@ menu_game_options::~menu_game_options() // handle //------------------------------------------------- -void menu_game_options::handle(event const *ev) +bool menu_game_options::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) - handle_item_event(*ev); + return ev && ev->itemref && handle_item_event(*ev); } //------------------------------------------------- @@ -203,7 +200,7 @@ void menu_game_options::populate() // handle item //------------------------------------------------- -void menu_game_options::handle_item_event(event const &menu_event) +bool menu_game_options::handle_item_event(event const &menu_event) { bool changed = false; @@ -268,12 +265,14 @@ void menu_game_options::handle_item_event(event const &menu_event) menu::stack_push(ui(), container(), [this] () { reset(reset_options::REMEMBER_REF); }); break; default: - menu_simple_game_options::handle_item_event(menu_event); - return; + return menu_simple_game_options::handle_item_event(menu_event); } if (changed) reset(reset_options::REMEMBER_REF); + + // triggers an item reset for any changes + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/optsmenu.h b/src/frontend/mame/ui/optsmenu.h index d1779ede52a..b300ed90cd5 100644 --- a/src/frontend/mame/ui/optsmenu.h +++ b/src/frontend/mame/ui/optsmenu.h @@ -28,10 +28,10 @@ public: virtual ~menu_simple_game_options() override; protected: - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void populate() override; - void handle_item_event(event const &menu_event); + bool handle_item_event(event const &menu_event); private: enum @@ -62,10 +62,10 @@ public: virtual ~menu_game_options() override; protected: - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void populate() override; - void handle_item_event(event const &menu_event); + bool handle_item_event(event const &menu_event); private: enum diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp index bbf3c447087..2a091d25b7a 100644 --- a/src/frontend/mame/ui/pluginopt.cpp +++ b/src/frontend/mame/ui/pluginopt.cpp @@ -19,13 +19,14 @@ namespace ui { -void menu_plugin::handle(event const *ev) +bool menu_plugin::handle(event const *ev) { if (ev && ev->itemref) { if (ev->iptkey == IPT_UI_SELECT) menu::stack_push(ui(), container(), (char *)ev->itemref); } + return false; } menu_plugin::menu_plugin(mame_ui_manager &mui, render_container &container) : @@ -68,7 +69,7 @@ menu_plugin_opt::menu_plugin_opt(mame_ui_manager &mui, render_container &contain { } -void menu_plugin_opt::handle(event const *ev) +bool menu_plugin_opt::handle(event const *ev) { void *const itemref = ev ? ev->itemref : get_selection_ref(); std::string key; @@ -116,16 +117,19 @@ void menu_plugin_opt::handle(event const *ev) break; } } - if (!key.empty() || m_need_idle) - { - auto const result = mame_machine_manager::instance()->lua()->menu_callback(m_menu, uintptr_t(itemref), key); - if (result.second) - set_selection(reinterpret_cast(uintptr_t(*result.second))); - if (result.first) - reset(reset_options::REMEMBER_REF); - else if (ev && (ev->iptkey == IPT_UI_BACK)) - stack_pop(); - } + + if (key.empty() && !m_need_idle) + return false; + + auto const result = mame_machine_manager::instance()->lua()->menu_callback(m_menu, uintptr_t(itemref), key); + if (result.second) + set_selection(reinterpret_cast(uintptr_t(*result.second))); + if (result.first) + reset(reset_options::REMEMBER_REF); + else if (ev && (ev->iptkey == IPT_UI_BACK)) + stack_pop(); + + return result.second && !result.first; } void menu_plugin_opt::populate() diff --git a/src/frontend/mame/ui/pluginopt.h b/src/frontend/mame/ui/pluginopt.h index 1e947a9ccd3..46b386f5ff0 100644 --- a/src/frontend/mame/ui/pluginopt.h +++ b/src/frontend/mame/ui/pluginopt.h @@ -33,11 +33,12 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector &m_plugins; }; + class menu_plugin_opt : public menu { public: @@ -49,7 +50,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::string const m_menu; bool m_need_idle; diff --git a/src/frontend/mame/ui/quitmenu.cpp b/src/frontend/mame/ui/quitmenu.cpp index cd1fb4ac59b..2177313a0cd 100644 --- a/src/frontend/mame/ui/quitmenu.cpp +++ b/src/frontend/mame/ui/quitmenu.cpp @@ -20,7 +20,8 @@ menu_confirm_quit::menu_confirm_quit(mame_ui_manager &mui, render_container &con : autopause_menu<>(mui, container) { set_one_shot(true); - set_process_flags(PROCESS_CUSTOM_ONLY | PROCESS_NOINPUT); + set_needs_prev_menu_item(false); + set_heading(_("menu-quit", "Are you sure you want to quit?")); } @@ -29,33 +30,24 @@ menu_confirm_quit::~menu_confirm_quit() } -void menu_confirm_quit::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) -{ - ui().draw_text_box( - container(), - util::string_format( - _("Are you sure you want to quit?\n\n" - "Press %1$s to quit\n" - "Press %2$s to return to emulation"), - ui().get_general_input_setting(IPT_UI_SELECT), - ui().get_general_input_setting(IPT_UI_BACK)), - text_layout::text_justify::CENTER, - 0.5f, 0.5f, - UI_RED_COLOR); -} - - void menu_confirm_quit::populate() { + item_append(_("menu-quit", "Quit"), 0, nullptr); + item_append(_("menu-quit", "Return to emulation"), 0, nullptr); } -void menu_confirm_quit::handle(event const *ev) +bool menu_confirm_quit::handle(event const *ev) { - if (machine().ui_input().pressed(IPT_UI_SELECT)) - machine().schedule_exit(); - else if (machine().ui_input().pressed(IPT_UI_BACK)) - stack_pop(); + if (ev && (IPT_UI_SELECT == ev->iptkey)) + { + if (0 == selected_index()) + machine().schedule_exit(); + else + stack_pop(); + } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/quitmenu.h b/src/frontend/mame/ui/quitmenu.h index 206ef1983ea..9f22801fdba 100644 --- a/src/frontend/mame/ui/quitmenu.h +++ b/src/frontend/mame/ui/quitmenu.h @@ -23,12 +23,9 @@ public: menu_confirm_quit(mame_ui_manager &mui, render_container &container); virtual ~menu_confirm_quit(); -protected: - virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; - private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/selector.cpp b/src/frontend/mame/ui/selector.cpp index b3a579cd049..e21026f6d44 100644 --- a/src/frontend/mame/ui/selector.cpp +++ b/src/frontend/mame/ui/selector.cpp @@ -49,46 +49,47 @@ menu_selector::~menu_selector() // handle //------------------------------------------------- -void menu_selector::handle(event const *ev) +bool menu_selector::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + return false; + + switch (ev->iptkey) { - switch (ev->iptkey) + case IPT_UI_SELECT: + if (ev->itemref) { - case IPT_UI_SELECT: - if (ev->itemref) - { - int selection(-1); - for (size_t idx = 0; (m_str_items.size() > idx) && (0 > selection); ++idx) - if ((void*)&m_str_items[idx] == ev->itemref) - selection = int(unsigned(idx)); + int selection(-1); + for (size_t idx = 0; (m_str_items.size() > idx) && (0 > selection); ++idx) + if ((void*)&m_str_items[idx] == ev->itemref) + selection = int(unsigned(idx)); - m_handler(selection); - stack_pop(); - } - break; - - case IPT_UI_PASTE: - if (paste_text(m_search, uchar_is_printable)) - reset(reset_options::SELECT_FIRST); - break; - - case IPT_SPECIAL: - if (input_character(m_search, ev->unichar, uchar_is_printable)) - reset(reset_options::SELECT_FIRST); - break; - - case IPT_UI_CANCEL: - if (!m_search.empty()) - { - // escape pressed with non-empty search text clears the search text - m_search.clear(); - reset(reset_options::SELECT_FIRST); - } - break; + m_handler(selection); + stack_pop(); } + break; + + case IPT_UI_PASTE: + if (paste_text(m_search, uchar_is_printable)) + reset(reset_options::SELECT_FIRST); + break; + + case IPT_SPECIAL: + if (input_character(m_search, ev->unichar, uchar_is_printable)) + reset(reset_options::SELECT_FIRST); + break; + + case IPT_UI_CANCEL: + if (!m_search.empty()) + { + // escape pressed with non-empty search text clears the search text + m_search.clear(); + reset(reset_options::SELECT_FIRST); + } + break; } + + return false; // any changes will trigger an item reset } //------------------------------------------------- diff --git a/src/frontend/mame/ui/selector.h b/src/frontend/mame/ui/selector.h index 07528364f4d..4b8043a990a 100644 --- a/src/frontend/mame/ui/selector.h +++ b/src/frontend/mame/ui/selector.h @@ -46,7 +46,7 @@ private: enum { VISIBLE_SEARCH_ITEMS = 200 }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void find_matches(const char *str); diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp index 047e6f6f721..f9b2c702503 100644 --- a/src/frontend/mame/ui/selgame.cpp +++ b/src/frontend/mame/ui/selgame.cpp @@ -194,7 +194,7 @@ void menu_select_game::menu_deactivated() // handle //------------------------------------------------- -void menu_select_game::handle(event const *ev) +bool menu_select_game::handle(event const *ev) { if (!m_prev_selected && item_count() > 0) m_prev_selected = item(0).ref(); @@ -207,38 +207,52 @@ void menu_select_game::handle(event const *ev) const ui_software_info *software; get_selection(software, system); menu::stack_push(ui(), container(), *system); - return; + return false; } // FIXME: everything above here used to run before events were processed // process the menu + bool changed = false; if (ev) { if (dismiss_error()) { // reset the error on any subsequent menu event + changed = true; } else switch (ev->iptkey) { case IPT_UI_UP: if ((get_focus() == focused_menu::LEFT) && (machine_filter::FIRST < m_filter_highlight)) + { --m_filter_highlight; + changed = true; + } break; case IPT_UI_DOWN: if ((get_focus() == focused_menu::LEFT) && (machine_filter::LAST > m_filter_highlight)) + { m_filter_highlight++; + changed = true; + } break; case IPT_UI_HOME: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = machine_filter::FIRST; + changed = true; + } break; case IPT_UI_END: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = machine_filter::LAST; + changed = true; + } break; case IPT_UI_EXPORT: @@ -258,9 +272,9 @@ void menu_select_game::handle(event const *ev) if (get_focus() == focused_menu::MAIN) { if (m_populated_favorites) - inkey_select_favorite(ev); + changed = inkey_select_favorite(ev); else - inkey_select(ev); + changed = inkey_select(ev); } break; @@ -292,16 +306,16 @@ void menu_select_game::handle(event const *ev) case IPT_UI_LEFT: if (right_panel() == RP_IMAGES) - previous_image_view(); // Images + changed = previous_image_view(); // Images else if (right_panel() == RP_INFOS) - change_info_pane(-1); // Infos + changed = change_info_pane(-1); // Infos break; case IPT_UI_RIGHT: if (right_panel() == RP_IMAGES) - next_image_view(); // Images + changed = next_image_view(); // Images else if (right_panel() == RP_INFOS) - change_info_pane(1); // Infos + changed = change_info_pane(1); // Infos break; case IPT_UI_FAVORITES: @@ -322,6 +336,7 @@ void menu_select_game::handle(event const *ev) mfav.remove_favorite_system(driver); machine().popmessage(_("%s\n removed from favorites list."), info.description); } + changed = true; } else { @@ -343,6 +358,7 @@ void menu_select_game::handle(event const *ev) // if we're in an error state, overlay an error message draw_error_text(); + return changed; } //------------------------------------------------- @@ -606,7 +622,7 @@ void menu_select_game::force_game_select(mame_ui_manager &mui, render_container // handle select key event //------------------------------------------------- -void menu_select_game::inkey_select(const event *menu_event) +bool menu_select_game::inkey_select(const event *menu_event) { auto const system = reinterpret_cast(menu_event->itemref); @@ -618,13 +634,14 @@ void menu_select_game::inkey_select(const event *menu_event) container(), m_persistent_data.filter_data(), [this] () { reset(reset_options::SELECT_FIRST); }); + return false; } else if (uintptr_t(system) == CONF_MACHINE) { // special case for configure machine if (m_prev_selected) menu::stack_push(ui(), container(), *reinterpret_cast(m_prev_selected)); - return; + return false; } else { @@ -638,7 +655,7 @@ void menu_select_game::inkey_select(const event *menu_event) if (!swlistdev.get_info().empty()) { menu::stack_push(ui(), container(), *system); - return; + return false; } } @@ -651,11 +668,13 @@ void menu_select_game::inkey_select(const event *menu_event) { if (!select_bios(*system->driver, false)) launch_system(*system->driver); + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, summary)); + return true; } } } @@ -664,7 +683,7 @@ void menu_select_game::inkey_select(const event *menu_event) // handle select key event for favorites menu //------------------------------------------------- -void menu_select_game::inkey_select_favorite(const event *menu_event) +bool menu_select_game::inkey_select_favorite(const event *menu_event) { ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref; @@ -676,6 +695,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) container(), m_persistent_data.filter_data(), [this] () { reset(reset_options::SELECT_FIRST); }); + return false; } else if ((uintptr_t)ui_swinfo == CONF_MACHINE) { @@ -694,7 +714,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) reset(empty ? reset_options::SELECT_FIRST : reset_options::REMEMBER_REF); }); } - return; + return false; } else if (ui_swinfo->startempty) { @@ -708,7 +728,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) { ui_system_info const &system(m_persistent_data.systems()[driver_list::find(ui_swinfo->driver->name)]); menu::stack_push(ui(), container(), system); - return; + return false; } } @@ -724,11 +744,13 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) reselect_last::reselect(true); launch_system(*ui_swinfo->driver); } + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, summary)); + return true; } } else @@ -741,6 +763,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) if (!audit_passed(sysaudit)) { set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, sysaudit)); + return true; } else { @@ -755,11 +778,13 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) reselect_last::reselect(true); if (!select_bios(*ui_swinfo, false) && !select_part(*swinfo, *ui_swinfo)) launch_system(drv.driver(), *ui_swinfo, ui_swinfo->part); + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_software_audit_fail_text(auditor, swaudit)); + return true; } } } @@ -779,34 +804,46 @@ bool menu_select_game::isfavorite() const // change what's displayed in the info box //------------------------------------------------- -void menu_select_game::change_info_pane(int delta) +bool menu_select_game::change_info_pane(int delta) { - auto const cap_delta = [this, &delta] (uint8_t ¤t, uint8_t &total) - { - if ((0 > delta) && (-delta > current)) - delta = -int(unsigned(current)); - else if ((0 < delta) && ((current + unsigned(delta)) >= total)) - delta = int(unsigned(total - current - 1)); - if (delta) - { - current += delta; - m_topline_datsview = 0; - } - }; + auto const cap_delta = + [this, &delta] (uint8_t ¤t, uint8_t &total) -> bool + { + if ((0 > delta) && (-delta > current)) + delta = -int(unsigned(current)); + else if ((0 < delta) && ((current + unsigned(delta)) >= total)) + delta = int(unsigned(total - current - 1)); + if (delta) + { + current += delta; + m_topline_datsview = 0; + return true; + } + else + { + return false; + } + }; ui_system_info const *sys; ui_software_info const *soft; get_selection(soft, sys); if (!m_populated_favorites) { if (uintptr_t(sys) > m_skip_main_items) - cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); + return cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); + else + return false; } else if (uintptr_t(soft) > m_skip_main_items) { if (soft->startempty) - cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); + return cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); else - cap_delta(ui_globals::cur_sw_dats_view, ui_globals::cur_sw_dats_total); + return cap_delta(ui_globals::cur_sw_dats_view, ui_globals::cur_sw_dats_total); + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/selgame.h b/src/frontend/mame/ui/selgame.h index af1dad248ac..4aae7261687 100644 --- a/src/frontend/mame/ui/selgame.h +++ b/src/frontend/mame/ui/selgame.h @@ -59,7 +59,7 @@ private: static bool s_first_start; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // drawing virtual float draw_left_panel(float x1, float y1, float x2, float y2) override; @@ -80,7 +80,7 @@ private: virtual void inkey_export() override; // internal methods - void change_info_pane(int delta); + bool change_info_pane(int delta); void build_available_list(); @@ -90,8 +90,8 @@ private: void load_custom_filters(); // handlers - void inkey_select(const event *menu_event); - void inkey_select_favorite(const event *menu_event); + bool inkey_select(const event *menu_event); + bool inkey_select_favorite(const event *menu_event); }; } // namespace ui diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp index 1a0789bc394..baa89bfefe0 100644 --- a/src/frontend/mame/ui/selmenu.cpp +++ b/src/frontend/mame/ui/selmenu.cpp @@ -173,7 +173,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; ui_software_info const &m_uiinfo; s_parts const m_parts; @@ -190,7 +190,7 @@ private: bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, void const *driver, bool software, bool inlist); virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void const *m_driver; bool m_software, m_inlist; @@ -297,9 +297,8 @@ void menu_select_launch::software_parts::populate() // handle //------------------------------------------------- -void menu_select_launch::software_parts::handle(event const *ev) +bool menu_select_launch::software_parts::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref) { for (auto const &elem : m_parts) @@ -311,6 +310,8 @@ void menu_select_launch::software_parts::handle(event const *ev) } } } + + return false; } @@ -362,9 +363,8 @@ void menu_select_launch::bios_selection::populate() // handle //------------------------------------------------- -void menu_select_launch::bios_selection::handle(event const *ev) +bool menu_select_launch::bios_selection::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref) { for (auto & elem : m_bios) @@ -402,6 +402,8 @@ void menu_select_launch::bios_selection::handle(event const *ev) } } } + + return false; } @@ -526,22 +528,32 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c } -void menu_select_launch::next_image_view() +bool menu_select_launch::next_image_view() { if (LAST_VIEW > m_image_view) { ++m_image_view; set_switch_image(); + return true; + } + else + { + return false; } } -void menu_select_launch::previous_image_view() +bool menu_select_launch::previous_image_view() { if (FIRST_VIEW < m_image_view) { --m_image_view; set_switch_image(); + return true; + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/selmenu.h b/src/frontend/mame/ui/selmenu.h index 42edf8a773a..88ef0476ffe 100644 --- a/src/frontend/mame/ui/selmenu.h +++ b/src/frontend/mame/ui/selmenu.h @@ -114,8 +114,8 @@ protected: focused_menu get_focus() const { return m_focus; } void set_focus(focused_menu focus) { m_focus = focus; } - void next_image_view(); - void previous_image_view(); + bool next_image_view(); + bool previous_image_view(); bool dismiss_error(); void set_error(reset_options ropt, std::string &&message); diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp index 50822545dd1..4d0c9554a9d 100644 --- a/src/frontend/mame/ui/selsoft.cpp +++ b/src/frontend/mame/ui/selsoft.cpp @@ -420,7 +420,7 @@ menu_select_software::~menu_select_software() // handle //------------------------------------------------- -void menu_select_software::handle(event const *ev) +bool menu_select_software::handle(event const *ev) { if (m_prev_selected == nullptr && item_count() > 0) m_prev_selected = item(0).ref(); @@ -428,30 +428,33 @@ void menu_select_software::handle(event const *ev) // FIXME: everything above here used run before events were processed // process the menu + bool changed = false; if (ev) { if (dismiss_error()) { // reset the error on any subsequent menu event + changed = true; } else switch (ev->iptkey) { case IPT_UI_SELECT: if ((get_focus() == focused_menu::MAIN) && ev->itemref) - inkey_select(ev); + changed = inkey_select(ev); break; case IPT_UI_LEFT: if (right_panel() == RP_IMAGES) { // Images - previous_image_view(); + changed = previous_image_view(); } else if (right_panel() == RP_INFOS && ui_globals::cur_sw_dats_view > 0) { // Infos ui_globals::cur_sw_dats_view--; m_topline_datsview = 0; + changed = true; } break; @@ -459,34 +462,47 @@ void menu_select_software::handle(event const *ev) if (right_panel() == RP_IMAGES) { // Images - next_image_view(); + changed = next_image_view(); } else if (right_panel() == RP_INFOS && ui_globals::cur_sw_dats_view < (ui_globals::cur_sw_dats_total - 1)) { // Infos ui_globals::cur_sw_dats_view++; m_topline_datsview = 0; + changed = true; } break; case IPT_UI_UP: if ((get_focus() == focused_menu::LEFT) && (software_filter::FIRST < m_filter_highlight)) + { --m_filter_highlight; + changed = true; + } break; case IPT_UI_DOWN: if ((get_focus() == focused_menu::LEFT) && (software_filter::LAST > m_filter_highlight)) + { ++m_filter_highlight; + changed = true; + } break; case IPT_UI_HOME: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = software_filter::FIRST; + changed = true; + } break; case IPT_UI_END: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = software_filter::LAST; + changed = true; + } break; case IPT_UI_DATS: @@ -509,12 +525,12 @@ void menu_select_software::handle(event const *ev) mfav.add_favorite_software(*swinfo); machine().popmessage(_("%s\n added to favorites list."), swinfo->longname); } - else { machine().popmessage(_("%s\n removed from favorites list."), swinfo->longname); mfav.remove_favorite_software(*swinfo); } + changed = true; } } } @@ -523,6 +539,7 @@ void menu_select_software::handle(event const *ev) // if we're in an error state, overlay an error message draw_error_text(); + return changed; } //------------------------------------------------- @@ -633,7 +650,7 @@ void menu_select_software::populate() // handle select key event //------------------------------------------------- -void menu_select_software::inkey_select(const event *menu_event) +bool menu_select_software::inkey_select(const event *menu_event) { ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref; driver_enumerator drivlist(machine().options(), *ui_swinfo->driver); @@ -645,6 +662,7 @@ void menu_select_software::inkey_select(const event *menu_event) if (!audit_passed(sysaudit)) { set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, sysaudit)); + return true; } else if (ui_swinfo->startempty == 1) { @@ -653,6 +671,7 @@ void menu_select_software::inkey_select(const event *menu_event) reselect_last::reselect(true); launch_system(*ui_swinfo->driver, *ui_swinfo); } + return false; } else { @@ -668,11 +687,13 @@ void menu_select_software::inkey_select(const event *menu_event) reselect_last::reselect(true); launch_system(drivlist.driver(), *ui_swinfo); } + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_software_audit_fail_text(auditor, swaudit)); + return true; } } } diff --git a/src/frontend/mame/ui/selsoft.h b/src/frontend/mame/ui/selsoft.h index 1ac874ac93a..3b3074ddcdf 100644 --- a/src/frontend/mame/ui/selsoft.h +++ b/src/frontend/mame/ui/selsoft.h @@ -45,7 +45,7 @@ private: class machine_data; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // drawing virtual float draw_left_panel(float x1, float y1, float x2, float y2) override; @@ -65,7 +65,7 @@ private: virtual void inkey_export() override { throw false; } // handlers - void inkey_select(const event *menu_event); + bool inkey_select(const event *menu_event); std::map m_icon_paths; ui_system_info const &m_system; diff --git a/src/frontend/mame/ui/simpleselgame.cpp b/src/frontend/mame/ui/simpleselgame.cpp index 2c1cb28e29a..3919f97df23 100644 --- a/src/frontend/mame/ui/simpleselgame.cpp +++ b/src/frontend/mame/ui/simpleselgame.cpp @@ -110,37 +110,36 @@ void simple_menu_select_game::build_driver_list() // handle - handle the game select menu //------------------------------------------------- -void simple_menu_select_game::handle(event const *ev) +bool simple_menu_select_game::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + return false; + + if (m_error) { - if (m_error) - { - // reset the error on any subsequent menu event - m_error = false; - machine().ui_input().reset(); - } - else - { - // handle selections - switch (ev->iptkey) - { - case IPT_UI_SELECT: - inkey_select(*ev); - break; - case IPT_UI_CANCEL: - inkey_cancel(); - break; - case IPT_UI_PASTE: - if (paste_text(m_search, uchar_is_printable)) - reset(reset_options::SELECT_FIRST); - break; - case IPT_SPECIAL: - inkey_special(*ev); - break; - } - } + // reset the error on any subsequent menu event + m_error = false; + machine().ui_input().reset(); + return true; + } + + // handle selections + bool changed = false; + switch (ev->iptkey) + { + case IPT_UI_SELECT: + changed = inkey_select(*ev); + break; + case IPT_UI_CANCEL: + inkey_cancel(); + break; + case IPT_UI_PASTE: + if (paste_text(m_search, uchar_is_printable)) + reset(reset_options::SELECT_FIRST); + break; + case IPT_SPECIAL: + inkey_special(*ev); + break; } // if we're in an error state, overlay an error message @@ -152,6 +151,7 @@ void simple_menu_select_game::handle(event const *ev) "Please select a different game.\n\nPress any key to continue."), text_layout::text_justify::CENTER, 0.5f, 0.5f, UI_RED_COLOR); } + return changed; } @@ -159,7 +159,7 @@ void simple_menu_select_game::handle(event const *ev) // inkey_select //------------------------------------------------- -void simple_menu_select_game::inkey_select(const event &menu_event) +bool simple_menu_select_game::inkey_select(const event &menu_event) { const game_driver *driver = (const game_driver *)menu_event.itemref; @@ -169,10 +169,12 @@ void simple_menu_select_game::inkey_select(const event &menu_event) ui(), container(), [this] () { reset(reset_options::SELECT_FIRST); }); + return false; } else if (!driver) // special case for previous menu { stack_pop(); + return false; } else // anything else is a driver { @@ -188,12 +190,14 @@ void simple_menu_select_game::inkey_select(const event &menu_event) mame_machine_manager::instance()->schedule_new_driver(*driver); machine().schedule_hard_reset(); stack_reset(); + return false; } else { // otherwise, display an error reset(reset_options::REMEMBER_REF); m_error = true; + return true; } } } diff --git a/src/frontend/mame/ui/simpleselgame.h b/src/frontend/mame/ui/simpleselgame.h index b1f4c1946e3..f010bf14e8e 100644 --- a/src/frontend/mame/ui/simpleselgame.h +++ b/src/frontend/mame/ui/simpleselgame.h @@ -37,11 +37,11 @@ private: enum { VISIBLE_GAMES_IN_LIST = 15 }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal methods void build_driver_list(); - void inkey_select(const event &menu_event); + bool inkey_select(const event &menu_event); void inkey_cancel(); void inkey_special(const event &menu_event); diff --git a/src/frontend/mame/ui/sliders.cpp b/src/frontend/mame/ui/sliders.cpp index db1dbbe7b66..b708b6af56a 100644 --- a/src/frontend/mame/ui/sliders.cpp +++ b/src/frontend/mame/ui/sliders.cpp @@ -39,118 +39,134 @@ menu_sliders::~menu_sliders() // menu_sliders - handle the sliders menu //------------------------------------------------- -void menu_sliders::handle(event const *ev) +bool menu_sliders::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + return false; + + if (ev->iptkey == IPT_UI_ON_SCREEN_DISPLAY) { - if (ev->iptkey == IPT_UI_ON_SCREEN_DISPLAY) + // toggle visibility + if (m_menuless_mode) { - // toggle visibility + stack_pop(); + return false; + } + else + { + m_hidden = !m_hidden; + set_process_flags(PROCESS_LR_REPEAT | (m_hidden ? PROCESS_CUSTOM_ONLY : 0)); + return true; + } + } + + // handle keys if there is a valid item selected + if (ev->itemref && (ev->item->type() == menu_item_type::SLIDER)) + { + const slider_state *slider = (const slider_state *)ev->itemref; + int32_t curvalue = slider->update(nullptr, SLIDER_NOCHANGE); + int32_t increment = 0; + bool const alt_pressed = machine().input().code_pressed(KEYCODE_LALT) || machine().input().code_pressed(KEYCODE_RALT); + bool const ctrl_pressed = machine().input().code_pressed(KEYCODE_LCONTROL) || machine().input().code_pressed(KEYCODE_RCONTROL); + bool const shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT); + + switch (ev->iptkey) + { + // decrease value + case IPT_UI_LEFT: + if (alt_pressed && shift_pressed) + increment = -1; + else if (alt_pressed) + increment = -(curvalue - slider->minval); + else if (shift_pressed) + increment = (slider->incval > 10) ? -(slider->incval / 10) : -1; + else if (ctrl_pressed) + increment = -slider->incval * 10; + else + increment = -slider->incval; + break; + + // increase value + case IPT_UI_RIGHT: + if (alt_pressed && shift_pressed) + increment = 1; + else if (alt_pressed) + increment = slider->maxval - curvalue; + else if (shift_pressed) + increment = (slider->incval > 10) ? (slider->incval / 10) : 1; + else if (ctrl_pressed) + increment = slider->incval * 10; + else + increment = slider->incval; + break; + + // restore default + case IPT_UI_CLEAR: + increment = slider->defval - curvalue; + break; + } + + // handle any changes + if (increment != 0) + { + int32_t newvalue = curvalue + increment; + + // clamp within bounds + if (newvalue < slider->minval) + newvalue = slider->minval; + if (newvalue > slider->maxval) + newvalue = slider->maxval; + + // update the slider and recompute the menu + slider->update(nullptr, newvalue); if (m_menuless_mode) + ui().get_session_data(nullptr) = ev->itemref; + reset(reset_options::REMEMBER_REF); + } + + // slider changes trigger an item reset as they can change the available sliders + return false; + } + + // when highlighting an item that isn't a slider with the menu is hidden, skip to the next one + if (m_hidden) + { + if (ev->iptkey == IPT_UI_UP || ev->iptkey == IPT_UI_PAGE_UP) + { + // if we got here via up or page up, select the previous item + if (is_first_selected()) { - stack_pop(); + select_last_item(); } else { - m_hidden = !m_hidden; - set_process_flags(PROCESS_LR_REPEAT | (m_hidden ? PROCESS_CUSTOM_ONLY : 0)); + set_selected_index(selected_index() - 1); + validate_selection(-1); } - + return true; } - else if (ev->itemref && (ev->item->type() == menu_item_type::SLIDER)) + else if (ev->iptkey == IPT_UI_DOWN || ev->iptkey == IPT_UI_PAGE_DOWN) { - // handle keys if there is a valid item selected - const slider_state *slider = (const slider_state *)ev->itemref; - int32_t curvalue = slider->update(nullptr, SLIDER_NOCHANGE); - int32_t increment = 0; - bool const alt_pressed = machine().input().code_pressed(KEYCODE_LALT) || machine().input().code_pressed(KEYCODE_RALT); - bool const ctrl_pressed = machine().input().code_pressed(KEYCODE_LCONTROL) || machine().input().code_pressed(KEYCODE_RCONTROL); - bool const shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT); - - switch (ev->iptkey) + // otherwise select the next item + if (is_last_selected()) { - // decrease value - case IPT_UI_LEFT: - if (alt_pressed && shift_pressed) - increment = -1; - else if (alt_pressed) - increment = -(curvalue - slider->minval); - else if (shift_pressed) - increment = (slider->incval > 10) ? -(slider->incval / 10) : -1; - else if (ctrl_pressed) - increment = -slider->incval * 10; - else - increment = -slider->incval; - break; - - // increase value - case IPT_UI_RIGHT: - if (alt_pressed && shift_pressed) - increment = 1; - else if (alt_pressed) - increment = slider->maxval - curvalue; - else if (shift_pressed) - increment = (slider->incval > 10) ? (slider->incval / 10) : 1; - else if (ctrl_pressed) - increment = slider->incval * 10; - else - increment = slider->incval; - break; - - // restore default - case IPT_UI_CLEAR: - increment = slider->defval - curvalue; - break; + select_first_item(); } - - // handle any changes - if (increment != 0) + else { - int32_t newvalue = curvalue + increment; - - // clamp within bounds - if (newvalue < slider->minval) - newvalue = slider->minval; - if (newvalue > slider->maxval) - newvalue = slider->maxval; - - // update the slider and recompute the menu - slider->update(nullptr, newvalue); - if (m_menuless_mode) - ui().get_session_data(nullptr) = ev->itemref; - reset(reset_options::REMEMBER_REF); + set_selected_index(selected_index() + 1); + validate_selection(1); } + return true; } - else if (m_hidden) + else { - // if we are selecting an invalid item and we are hidden, skip to the next one - if (ev->iptkey == IPT_UI_UP || ev->iptkey == IPT_UI_PAGE_UP) - { - // if we got here via up or page up, select the previous item - if (is_first_selected()) - { - select_last_item(); - } - else - { - set_selected_index(selected_index() - 1); - validate_selection(-1); - } - } - else if (ev->iptkey == IPT_UI_DOWN || ev->iptkey == IPT_UI_PAGE_DOWN) - { - // otherwise select the next item - if (is_last_selected()) - select_first_item(); - else - { - set_selected_index(selected_index() + 1); - validate_selection(1); - } - } + return false; } } + + // didn't do anything + return false; } diff --git a/src/frontend/mame/ui/sliders.h b/src/frontend/mame/ui/sliders.h index 645169189cc..f9c0c69a176 100644 --- a/src/frontend/mame/ui/sliders.h +++ b/src/frontend/mame/ui/sliders.h @@ -32,7 +32,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool const m_menuless_mode; bool m_hidden; diff --git a/src/frontend/mame/ui/slotopt.cpp b/src/frontend/mame/ui/slotopt.cpp index 1b30b6120c1..bd92a2f9c9b 100644 --- a/src/frontend/mame/ui/slotopt.cpp +++ b/src/frontend/mame/ui/slotopt.cpp @@ -242,29 +242,30 @@ void menu_slot_devices::custom_render(void *selectedref, float top, float bottom // handle - process an input event //------------------------------------------------- -void menu_slot_devices::handle(event const *ev) +bool menu_slot_devices::handle(event const *ev) { - // process the menu - if (ev && ev->itemref != nullptr) + if (!ev || !ev->itemref) + return false; + + if (ev->itemref == ITEMREF_RESET) { - if (ev->itemref == ITEMREF_RESET) - { - if (ev->iptkey == IPT_UI_SELECT) - machine().schedule_hard_reset(); - } - else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) - { - device_slot_interface *slot = (device_slot_interface *)ev->itemref; - rotate_slot_device(*slot, ev->iptkey == IPT_UI_LEFT ? step_t::PREVIOUS : step_t::NEXT); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - device_slot_interface *slot = (device_slot_interface *)ev->itemref; - device_slot_interface::slot_option const *const option = get_current_option(*slot); - if (option) - menu::stack_push(ui(), container(), slot, option); - } + if (ev->iptkey == IPT_UI_SELECT) + machine().schedule_hard_reset(); } + else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) + { + device_slot_interface *slot = (device_slot_interface *)ev->itemref; + rotate_slot_device(*slot, ev->iptkey == IPT_UI_LEFT ? step_t::PREVIOUS : step_t::NEXT); + } + else if (ev->iptkey == IPT_UI_SELECT) + { + device_slot_interface *slot = (device_slot_interface *)ev->itemref; + device_slot_interface::slot_option const *const option = get_current_option(*slot); + if (option) + menu::stack_push(ui(), container(), slot, option); + } + + return false; // any changes require the menu to be rebuilt } diff --git a/src/frontend/mame/ui/slotopt.h b/src/frontend/mame/ui/slotopt.h index 6dae4ce062a..af272dde8ed 100644 --- a/src/frontend/mame/ui/slotopt.h +++ b/src/frontend/mame/ui/slotopt.h @@ -37,7 +37,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; device_slot_interface::slot_option const *get_current_option(device_slot_interface &slot) const; void set_slot_device(device_slot_interface &slot, std::string_view val); diff --git a/src/frontend/mame/ui/sndmenu.cpp b/src/frontend/mame/ui/sndmenu.cpp index f389c128c07..e5516f41cfa 100644 --- a/src/frontend/mame/ui/sndmenu.cpp +++ b/src/frontend/mame/ui/sndmenu.cpp @@ -72,7 +72,7 @@ void menu_sound_options::menu_dismissed() // handle //------------------------------------------------- -void menu_sound_options::handle(event const *ev) +bool menu_sound_options::handle(event const *ev) { bool changed = false; @@ -130,8 +130,9 @@ void menu_sound_options::handle(event const *ev) } } - if (changed) + if (changed) // FIXME: most changes only require the item sub text to be updated reset(reset_options::REMEMBER_REF); + return false; } diff --git a/src/frontend/mame/ui/sndmenu.h b/src/frontend/mame/ui/sndmenu.h index 6e79d4f6faa..01d69f6d8ff 100644 --- a/src/frontend/mame/ui/sndmenu.h +++ b/src/frontend/mame/ui/sndmenu.h @@ -39,7 +39,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; uint16_t m_cur_rates; static const int m_sound_rate[]; diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp index a7795c0347b..0c39c89d9e6 100644 --- a/src/frontend/mame/ui/state.cpp +++ b/src/frontend/mame/ui/state.cpp @@ -234,13 +234,14 @@ void menu_load_save_state_base::populate() // handle //------------------------------------------------- -void menu_load_save_state_base::handle(event const *ev) +bool menu_load_save_state_base::handle(event const *ev) { // process the event if (INPUT_CODE_INVALID != m_slot_selected) { if (!machine().input().code_pressed(m_slot_selected)) stack_pop(); + return false; } else if (ev && (ev->iptkey == IPT_UI_SELECT)) { @@ -251,6 +252,7 @@ void menu_load_save_state_base::handle(event const *ev) slot_selected(std::string(entry.file_name())); } stack_pop(); + return false; } else if (ev && (ev->iptkey == IPT_UI_CLEAR)) { @@ -263,6 +265,11 @@ void menu_load_save_state_base::handle(event const *ev) m_confirm_delete->visible_name(), ui().get_general_input_setting(IPT_UI_SELECT), ui().get_general_input_setting(IPT_UI_BACK)); + return true; + } + else + { + return false; } } else if (!m_confirm_delete) @@ -275,6 +282,11 @@ void menu_load_save_state_base::handle(event const *ev) m_switch_poller.reset(); m_slot_selected = code; } + return false; + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/state.h b/src/frontend/mame/ui/state.h index 8d982678d7d..8d02ab08881 100644 --- a/src/frontend/mame/ui/state.h +++ b/src/frontend/mame/ui/state.h @@ -40,7 +40,7 @@ protected: virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; virtual void handle_keys(uint32_t flags, int &iptkey) override; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void process_file(std::string &&file_name) = 0; diff --git a/src/frontend/mame/ui/submenu.cpp b/src/frontend/mame/ui/submenu.cpp index 5fbb0c47d9c..188f6622c71 100644 --- a/src/frontend/mame/ui/submenu.cpp +++ b/src/frontend/mame/ui/submenu.cpp @@ -245,7 +245,7 @@ submenu::~submenu() // handle the options menu //------------------------------------------------- -void submenu::handle(event const *ev) +bool submenu::handle(event const *ev) { bool changed = false; std::string error_string, tmptxt; @@ -332,8 +332,9 @@ void submenu::handle(event const *ev) } } - if (changed) + if (changed) // FIXME: most changes should only require updating the item's subtext reset(reset_options::REMEMBER_REF); + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/submenu.h b/src/frontend/mame/ui/submenu.h index c307f220924..87e92cc3d9d 100644 --- a/src/frontend/mame/ui/submenu.h +++ b/src/frontend/mame/ui/submenu.h @@ -65,7 +65,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector