summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/ui
diff options
context:
space:
mode:
author Vas Crabb <cuavas@users.noreply.github.com>2021-10-31 12:31:16 +1100
committer GitHub <noreply@github.com>2021-10-31 12:31:16 +1100
commitd64ea5331b2312f81df464fb22dcef0191216d86 (patch)
treea3f3784371da401e6a675e5b6b9734b88281a08d /src/frontend/mame/ui
parentcfffc54b61cabc5ef9533396bf87324eb5eeb63e (diff)
-frontend: Refactored menu event handling and fixed a number of issues. (#8777)
* Moved common code for drawing about box, info viewer, and other text box menus to a base class; removed the last of the info viewer logic and the multi-line item hack from the base menu class. * Added previous/next group navigation for general inputs and plugin input selection menus. * Moved message catalog logic to lib/util, allowing osd and emu to use localised messages. * Made the base menu class use the UI manager’s feature for holding session state rather than a static map and mutex. * Improved menu event handling model, and fixed many issues, particularly with menus behaving badly when hidden/shown. * Added better support for menus that don’t participate in the usual menu stack, like the menuless sliders and the save/load state menus. * Made a number of menus refresh state when being shown after being hidden (fixes MT08121 among other issues). * Fixed indication of mounted slot option in the slot option details menu. * Improved appearance of background menus when emulation isn't running - draw all menus in the stack, and darken the background menus to make the edges of the active menu clearer. * Fixed locale issues in -listxml. -debugger: Made GUI debuggers more uniform. * Added new memory view features to Win32 debugger. * Fixed spelling of hexadecimal in Cocoa debugger and added decimal address option. * Fixed duplicate keyboard shortcut in Cocoa debugger (Shift-Cmd-D was both new device window and 64-bit float format). * Made keyboard shortcuts slightly more consistent across debuggers. -plugins: Moved input selection menu and sequence polling code to a common library. Fixed the issue that prevented keyboard inputs being mapped with -steadykey on. -docs: Started adding some documentation for MAME's internal UI, and updated the list of example front-ends. -Regenerated message catalog sources. For translators, the new strings are mostly: * The names of the inputs provided by the OS-dependent layer for things like fullscreen and video features. These show up in the user interface inputs menu. * The names for automatically generated views. These show up in the video options menu - test with a system with a lot of screens to see more variants. * The input macro plugin UI. * A few format strings for analog input assignments. * A few strings for the about box header.
Diffstat (limited to 'src/frontend/mame/ui')
-rw-r--r--src/frontend/mame/ui/about.cpp179
-rw-r--r--src/frontend/mame/ui/about.h11
-rw-r--r--src/frontend/mame/ui/analogipt.cpp12
-rw-r--r--src/frontend/mame/ui/analogipt.h2
-rw-r--r--src/frontend/mame/ui/auditmenu.cpp24
-rw-r--r--src/frontend/mame/ui/auditmenu.h2
-rw-r--r--src/frontend/mame/ui/barcode.cpp22
-rw-r--r--src/frontend/mame/ui/barcode.h3
-rw-r--r--src/frontend/mame/ui/cheatopt.cpp56
-rw-r--r--src/frontend/mame/ui/cheatopt.h2
-rw-r--r--src/frontend/mame/ui/confswitch.cpp24
-rw-r--r--src/frontend/mame/ui/confswitch.h3
-rw-r--r--src/frontend/mame/ui/custui.cpp103
-rw-r--r--src/frontend/mame/ui/custui.h10
-rw-r--r--src/frontend/mame/ui/datmenu.cpp211
-rw-r--r--src/frontend/mame/ui/datmenu.h12
-rw-r--r--src/frontend/mame/ui/devopt.cpp519
-rw-r--r--src/frontend/mame/ui/devopt.h20
-rw-r--r--src/frontend/mame/ui/dirmenu.cpp36
-rw-r--r--src/frontend/mame/ui/dirmenu.h11
-rw-r--r--src/frontend/mame/ui/filecreate.cpp41
-rw-r--r--src/frontend/mame/ui/filecreate.h11
-rw-r--r--src/frontend/mame/ui/filemngr.cpp22
-rw-r--r--src/frontend/mame/ui/filemngr.h4
-rw-r--r--src/frontend/mame/ui/filesel.cpp22
-rw-r--r--src/frontend/mame/ui/filesel.h4
-rw-r--r--src/frontend/mame/ui/floppycntrl.cpp8
-rw-r--r--src/frontend/mame/ui/floppycntrl.h7
-rw-r--r--src/frontend/mame/ui/imgcntrl.cpp86
-rw-r--r--src/frontend/mame/ui/imgcntrl.h13
-rw-r--r--src/frontend/mame/ui/info.cpp51
-rw-r--r--src/frontend/mame/ui/info.h21
-rw-r--r--src/frontend/mame/ui/info_pty.cpp3
-rw-r--r--src/frontend/mame/ui/info_pty.h3
-rw-r--r--src/frontend/mame/ui/inputmap.cpp95
-rw-r--r--src/frontend/mame/ui/inputmap.h7
-rw-r--r--src/frontend/mame/ui/keyboard.cpp11
-rw-r--r--src/frontend/mame/ui/keyboard.h2
-rw-r--r--src/frontend/mame/ui/mainmenu.cpp49
-rw-r--r--src/frontend/mame/ui/mainmenu.h9
-rw-r--r--src/frontend/mame/ui/menu.cpp323
-rw-r--r--src/frontend/mame/ui/menu.h132
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp205
-rw-r--r--src/frontend/mame/ui/miscmenu.h29
-rw-r--r--src/frontend/mame/ui/optsmenu.cpp17
-rw-r--r--src/frontend/mame/ui/optsmenu.h4
-rw-r--r--src/frontend/mame/ui/pluginopt.cpp45
-rw-r--r--src/frontend/mame/ui/pluginopt.h5
-rw-r--r--src/frontend/mame/ui/selector.cpp16
-rw-r--r--src/frontend/mame/ui/selector.h2
-rw-r--r--src/frontend/mame/ui/selgame.cpp50
-rw-r--r--src/frontend/mame/ui/selgame.h5
-rw-r--r--src/frontend/mame/ui/selmenu.cpp49
-rw-r--r--src/frontend/mame/ui/selsoft.cpp22
-rw-r--r--src/frontend/mame/ui/selsoft.h2
-rw-r--r--src/frontend/mame/ui/simpleselgame.cpp96
-rw-r--r--src/frontend/mame/ui/simpleselgame.h7
-rw-r--r--src/frontend/mame/ui/sliders.cpp63
-rw-r--r--src/frontend/mame/ui/sliders.h19
-rw-r--r--src/frontend/mame/ui/slotopt.cpp22
-rw-r--r--src/frontend/mame/ui/slotopt.h2
-rw-r--r--src/frontend/mame/ui/sndmenu.cpp26
-rw-r--r--src/frontend/mame/ui/sndmenu.h6
-rw-r--r--src/frontend/mame/ui/state.cpp54
-rw-r--r--src/frontend/mame/ui/state.h15
-rw-r--r--src/frontend/mame/ui/submenu.cpp23
-rw-r--r--src/frontend/mame/ui/submenu.h2
-rw-r--r--src/frontend/mame/ui/swlist.cpp40
-rw-r--r--src/frontend/mame/ui/swlist.h8
-rw-r--r--src/frontend/mame/ui/tapectrl.cpp28
-rw-r--r--src/frontend/mame/ui/tapectrl.h9
-rw-r--r--src/frontend/mame/ui/textbox.cpp237
-rw-r--r--src/frontend/mame/ui/textbox.h49
-rw-r--r--src/frontend/mame/ui/ui.cpp65
-rw-r--r--src/frontend/mame/ui/ui.h7
-rw-r--r--src/frontend/mame/ui/utils.cpp28
-rw-r--r--src/frontend/mame/ui/videoopt.cpp42
-rw-r--r--src/frontend/mame/ui/videoopt.h4
78 files changed, 1795 insertions, 1694 deletions
diff --git a/src/frontend/mame/ui/about.cpp b/src/frontend/mame/ui/about.cpp
index ac38d9c08b7..05ba893ae00 100644
--- a/src/frontend/mame/ui/about.cpp
+++ b/src/frontend/mame/ui/about.cpp
@@ -12,12 +12,9 @@
#include "ui/about.h"
#include "ui/ui.h"
-#include "ui/utils.h"
#include "mame.h"
-#include <string_view>
-
namespace ui {
@@ -38,21 +35,22 @@ namespace {
//-------------------------------------------------
menu_about::menu_about(mame_ui_manager &mui, render_container &container)
- : menu(mui, container)
+ : menu_textbox(mui, container)
, m_header{
util::string_format(
#ifdef MAME_DEBUG
- _("%1$s %2$s (%3$s%4$sP%5$s, debug)"),
+ _("about-header", "%1$s %2$s (%3$s%4$sP%5$s, debug)"),
#else
- _("%1$s %2$s (%3$s%4$sP%5$s)"),
+ _("about-header", "%1$s %2$s (%3$s%4$sP%5$s)"),
#endif
emulator_info::get_appname(),
bare_build_version,
(sizeof(int) == sizeof(void *)) ? "I" : "",
(sizeof(long) == sizeof(void *)) ? "L" : (sizeof(long long) == sizeof(void *)) ? "LL" : "",
sizeof(void *) * 8),
- util::string_format(_("Revision: %1$s"), bare_vcs_revision) }
+ util::string_format(_("about-header", "Revision: %1$s"), bare_vcs_revision) }
{
+ set_process_flags(PROCESS_CUSTOM_NAV);
}
@@ -81,136 +79,23 @@ void menu_about::custom_render(void *selectedref, float top, float bottom, float
//-------------------------------------------------
-// draw - draw about
+// populate_text - populate the about box text
//-------------------------------------------------
-void menu_about::draw(uint32_t flags)
+void menu_about::populate_text(std::optional<text_layout> &layout, float &width, int &lines)
{
- rgb_t const color = ui().colors().text_color();
- float const aspect = machine().render().ui_aspect(&container());
- float const line_height = ui().get_line_height();
- float const ud_arrow_width = line_height * aspect;
- float const gutter_width = 0.52f * line_height * aspect;
- float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
- float const visible_left = (1.0f - visible_width) * 0.5f;
- float const extra_height = 2.0f * line_height;
- float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
-
- // determine effective positions taking into account the hilighting arrows
- float const maximum_width = visible_width - 2.0f * gutter_width;
-
- draw_background();
- map_mouse();
-
- // account for extra space at the top and bottom
- float visible_main_menu_height = 1.0f - 2.0f * ui().box_tb_border() - visible_extra_menu_height;
- m_visible_lines = int(std::trunc(visible_main_menu_height / line_height));
- visible_main_menu_height = float(m_visible_lines) * line_height;
-
- // compute top/left of inner menu area by centering, if the menu is at the bottom of the extra, adjust
- float const visible_top = ((1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f) + get_customtop();
-
- // lay out the text if necessary
- if (!m_layout || (m_layout->width() != maximum_width))
+ if (!layout || (layout->width() != width))
{
- m_layout.emplace(ui().create_layout(container(), maximum_width));
+ rgb_t const color = ui().colors().text_color();
+ layout.emplace(ui().create_layout(container(), width));
for (char const *const *line = copying_text; *line; ++line)
{
- m_layout->add_text(*line, color);
- m_layout->add_text("\n", color);
- }
- }
- float const actual_width = m_layout->actual_width();
-
- // compute text box size
- float const x1 = visible_left + ((maximum_width - actual_width) * 0.5f);
- float const y1 = visible_top - ui().box_tb_border();
- float const x2 = visible_left + visible_width - ((maximum_width - actual_width) * 0.5f);
- float const y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
- float const effective_left = x1 + gutter_width;
- float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float const separator = visible_top + float(m_visible_lines) * line_height;
-
- ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
-
- int const visible_items = m_layout->lines();
- m_visible_lines = (std::min)(visible_items, m_visible_lines);
- top_line = (std::max)(0, top_line);
- if (top_line + m_visible_lines >= visible_items)
- top_line = visible_items - m_visible_lines;
-
- clear_hover();
- if (top_line)
- {
- // if we're on the top line, display the up arrow
- rgb_t fgcolor = ui().colors().text_color();
- if (mouse_in_rect(line_x0, visible_top, line_x1, visible_top + line_height))
- {
- fgcolor = ui().colors().mouseover_color();
- highlight(
- line_x0, visible_top,
- line_x1, visible_top + line_height,
- ui().colors().mouseover_bg_color());
- set_hover(HOVER_ARROW_UP);
+ layout->add_text(*line, color);
+ layout->add_text("\n", color);
}
- draw_arrow(
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, visible_top + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, visible_top + 0.75f * line_height,
- fgcolor, ROT0);
+ lines = layout->lines();
}
- if ((top_line + m_visible_lines) < visible_items)
- {
- // if we're on the bottom line, display the down arrow
- float const line_y = visible_top + float(m_visible_lines - 1) * line_height;
- rgb_t fgcolor = ui().colors().text_color();
- if (mouse_in_rect(line_x0, line_y, line_x1, line_y + line_height))
- {
- fgcolor = ui().colors().mouseover_color();
- highlight(
- line_x0, line_y,
- line_x1, line_y + line_height,
- ui().colors().mouseover_bg_color());
- set_hover(HOVER_ARROW_DOWN);
- }
- draw_arrow(
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
- fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
- }
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- m_visible_items = m_visible_lines - (top_line ? 1 : 0) - (top_line + m_visible_lines != visible_items);
- m_layout->emit(
- container(),
- top_line ? (top_line + 1) : 0, m_visible_items,
- effective_left, visible_top + (top_line ? line_height : 0.0f));
-
- // add visual separator before the "return to prevous menu" item
- container().add_line(
- x1, separator + (0.5f * line_height),
- x2, separator + (0.5f * line_height),
- UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
- menu_item const &pitem = item(0);
- std::string_view const itemtext = pitem.text;
- float const line_y0 = separator + line_height;
- float const line_y1 = line_y0 + line_height;
-
- if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
- set_hover(0);
-
- highlight(line_x0, line_y0, line_x1, line_y1, ui().colors().selected_bg_color());
- ui().draw_text_full(
- container(), itemtext,
- effective_left, line_y0, actual_width,
- text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
- mame_ui_manager::NORMAL,
- ui().colors().selected_color(), ui().colors().selected_bg_color(),
- nullptr, nullptr);
-
- // if there is something special to add, do it by calling the virtual method
- custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
+ width = layout->actual_width();
}
@@ -229,38 +114,10 @@ void menu_about::populate(float &customtop, float &custombottom)
// handle - manages inputs in the about modal
//-------------------------------------------------
-void menu_about::handle()
+void menu_about::handle(event const *ev)
{
- const event *event = process(PROCESS_CUSTOM_NAV);
- if (event)
- {
- switch (event->iptkey)
- {
- case IPT_UI_UP:
- --top_line;
- break;
-
- case IPT_UI_DOWN:
- ++top_line;
- break;
-
- case IPT_UI_PAGE_UP:
- top_line -= m_visible_lines - 3;
- break;
-
- case IPT_UI_PAGE_DOWN:
- top_line += m_visible_lines - 3;
- break;
-
- case IPT_UI_HOME:
- top_line = 0;
- break;
-
- case IPT_UI_END:
- top_line = m_layout->lines() - m_visible_lines;
- break;
- }
- }
+ if (ev)
+ handle_key(ev->iptkey);
}
-};
+} // namespace ui
diff --git a/src/frontend/mame/ui/about.h b/src/frontend/mame/ui/about.h
index 8ef133c43c6..13fc8e3e84f 100644
--- a/src/frontend/mame/ui/about.h
+++ b/src/frontend/mame/ui/about.h
@@ -12,7 +12,8 @@
#pragma once
-#include "ui/menu.h"
+#include "ui/text.h"
+#include "ui/textbox.h"
#include <optional>
#include <string>
@@ -21,7 +22,7 @@
namespace ui {
-class menu_about : public menu
+class menu_about : public menu_textbox
{
public:
menu_about(mame_ui_manager &mui, render_container &container);
@@ -30,13 +31,13 @@ public:
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
+ virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
+
private:
- virtual void draw(uint32_t flags) override;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::vector<std::string> const m_header;
- std::optional<text_layout> m_layout;
};
} // namespace ui
diff --git a/src/frontend/mame/ui/analogipt.cpp b/src/frontend/mame/ui/analogipt.cpp
index 2f1d1a7128d..209a84b4f06 100644
--- a/src/frontend/mame/ui/analogipt.cpp
+++ b/src/frontend/mame/ui/analogipt.cpp
@@ -52,6 +52,7 @@ menu_analog::menu_analog(mame_ui_manager &mui, render_container &container)
, m_field_data()
, m_visible_fields(0U)
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
@@ -121,18 +122,15 @@ void menu_analog::custom_render(void *selectedref, float top, float bottom, floa
}
-void menu_analog::handle()
+void menu_analog::handle(event const *ev)
{
- // process the menu
- event const *const menu_event(process(PROCESS_LR_REPEAT));
-
// handle events
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
- item_data &data(*reinterpret_cast<item_data *>(menu_event->itemref));
+ item_data &data(*reinterpret_cast<item_data *>(ev->itemref));
int newval(data.cur);
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
// if selected, reset to default value
case IPT_UI_SELECT:
diff --git a/src/frontend/mame/ui/analogipt.h b/src/frontend/mame/ui/analogipt.h
index 2982aa142fe..36ab7906ee3 100644
--- a/src/frontend/mame/ui/analogipt.h
+++ b/src/frontend/mame/ui/analogipt.h
@@ -66,7 +66,7 @@ private:
using field_data_vector = std::vector<field_data>;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void 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 9c93cf361bd..aaad0967f00 100644
--- a/src/frontend/mame/ui/auditmenu.cpp
+++ b/src/frontend/mame/ui/auditmenu.cpp
@@ -139,32 +139,28 @@ void menu_audit::populate(float &customtop, float &custombottom)
custombottom = (ui().get_line_height() * 1.0f) + (ui().box_tb_border() * 3.0f);
}
-void menu_audit::handle()
+void menu_audit::handle(event const *ev)
{
switch (m_phase)
{
case phase::CONFIRMATION:
+ if (ev && (IPT_UI_SELECT == ev->iptkey))
{
- event const *const menu_event(process(0));
- if (menu_event && (IPT_UI_SELECT == menu_event->iptkey))
+ if ((ITEMREF_START_FULL == ev->itemref) || (ITEMREF_START_FAST == ev->itemref))
{
- if ((ITEMREF_START_FULL == menu_event->itemref) || (ITEMREF_START_FAST == menu_event->itemref))
- {
- m_phase = phase::AUDIT;
- m_fast = ITEMREF_START_FAST == menu_event->itemref;
- m_prompt = util::string_format(_("Press %1$s to cancel\n"), ui().get_general_input_setting(IPT_UI_CANCEL));
- m_future.resize(std::thread::hardware_concurrency());
- for (auto &future : m_future)
- future = std::async(std::launch::async, [this] () { return do_audit(); });
- }
+ set_process_flags(PROCESS_CUSTOM_ONLY | PROCESS_NOINPUT);
+ m_phase = phase::AUDIT;
+ m_fast = ITEMREF_START_FAST == ev->itemref;
+ m_prompt = util::string_format(_("Press %1$s to cancel\n"), ui().get_general_input_setting(IPT_UI_CANCEL));
+ m_future.resize(std::thread::hardware_concurrency());
+ for (auto &future : m_future)
+ future = std::async(std::launch::async, [this] () { return do_audit(); });
}
}
break;
case phase::AUDIT:
case phase::CANCELLATION:
- process(PROCESS_CUSTOM_ONLY | PROCESS_NOINPUT);
-
if ((m_next.load() >= m_availablesorted.size()) || m_cancel.load())
{
bool done(true);
diff --git a/src/frontend/mame/ui/auditmenu.h b/src/frontend/mame/ui/auditmenu.h
index ea1dfa26821..de42c33b6d1 100644
--- a/src/frontend/mame/ui/auditmenu.h
+++ b/src/frontend/mame/ui/auditmenu.h
@@ -36,7 +36,7 @@ private:
enum class phase { CONFIRMATION, AUDIT, CANCELLATION };
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void 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 846f2cc97c5..7181445e240 100644
--- a/src/frontend/mame/ui/barcode.cpp
+++ b/src/frontend/mame/ui/barcode.cpp
@@ -9,12 +9,14 @@
***************************************************************************/
#include "emu.h"
-
#include "ui/barcode.h"
+
#include "ui/ui.h"
#include "ui/utils.h"
+
namespace ui {
+
// itemrefs for key menu items
#define ITEMREF_NEW_BARCODE ((void *) 0x0001)
#define ITEMREF_ENTER_BARCODE ((void *) 0x0002)
@@ -35,6 +37,7 @@ namespace ui {
menu_barcode_reader::menu_barcode_reader(mame_ui_manager &mui, render_container &container, barcode_reader_device *device)
: menu_device_control<barcode_reader_device>(mui, container, device)
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
@@ -86,29 +89,26 @@ void menu_barcode_reader::populate(float &customtop, float &custombottom)
// handle - manages inputs in the barcode input menu
//-------------------------------------------------
-void menu_barcode_reader::handle()
+void menu_barcode_reader::handle(event const *ev)
{
- // process the menu
- const event *event = process(PROCESS_LR_REPEAT);
-
// process the event
- if (event)
+ if (ev)
{
// handle selections
- switch (event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_LEFT:
- if (event->itemref == ITEMREF_SELECT_READER)
+ if (ev->itemref == ITEMREF_SELECT_READER)
previous();
break;
case IPT_UI_RIGHT:
- if (event->itemref == ITEMREF_SELECT_READER)
+ if (ev->itemref == ITEMREF_SELECT_READER)
next();
break;
case IPT_UI_SELECT:
- if (event->itemref == ITEMREF_ENTER_BARCODE)
+ if (ev->itemref == ITEMREF_ENTER_BARCODE)
{
std::string tmp_file(m_barcode_buffer);
//printf("code %s\n", m_barcode_buffer);
@@ -135,7 +135,7 @@ void menu_barcode_reader::handle()
case IPT_SPECIAL:
if (get_selection_ref() == ITEMREF_NEW_BARCODE)
{
- if (input_character(m_barcode_buffer, event->unichar, uchar_is_digit))
+ if (input_character(m_barcode_buffer, ev->unichar, uchar_is_digit))
reset(reset_options::REMEMBER_POSITION);
}
break;
diff --git a/src/frontend/mame/ui/barcode.h b/src/frontend/mame/ui/barcode.h
index 7f48d4f78ed..e171485cf79 100644
--- a/src/frontend/mame/ui/barcode.h
+++ b/src/frontend/mame/ui/barcode.h
@@ -17,6 +17,7 @@
#include "ui/devctrl.h"
namespace ui {
+
class menu_barcode_reader : public menu_device_control<barcode_reader_device> {
public:
menu_barcode_reader(mame_ui_manager &mui, render_container &container, barcode_reader_device *device);
@@ -24,7 +25,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void 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 1bfd8e4e0b3..9aae81134ef 100644
--- a/src/frontend/mame/ui/cheatopt.cpp
+++ b/src/frontend/mame/ui/cheatopt.cpp
@@ -9,12 +9,12 @@
*********************************************************************/
#include "emu.h"
-#include "cheat.h"
-#include "mame.h"
+#include "ui/cheatopt.h"
#include "ui/ui.h"
-#include "ui/menu.h"
-#include "ui/cheatopt.h"
+
+#include "cheat.h"
+#include "mame.h"
namespace ui {
@@ -29,78 +29,73 @@ namespace ui {
menu_cheat - handle the cheat menu
-------------------------------------------------*/
-void menu_cheat::handle()
+void menu_cheat::handle(event const *ev)
{
- /* process the menu */
- const event *menu_event = process(PROCESS_LR_REPEAT);
-
-
- /* handle events */
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ // handle events
+ if (ev && ev->itemref)
{
bool changed = false;
- /* clear cheat comment on any movement or keypress */
+ // clear cheat comment on any movement or keypress
machine().popmessage();
- /* handle reset all + reset all cheats for reload all option */
- if ((menu_event->itemref == ITEMREF_CHEATS_RESET_ALL || menu_event->itemref == ITEMREF_CHEATS_RELOAD_ALL) && menu_event->iptkey == IPT_UI_SELECT)
+ 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;
}
-
- /* handle individual cheats */
- else if (menu_event->itemref >= ITEMREF_CHEATS_FIRST_ITEM)
+ else if (ev->itemref >= ITEMREF_CHEATS_FIRST_ITEM)
{
- cheat_entry *curcheat = reinterpret_cast<cheat_entry *>(menu_event->itemref);
+ // handle individual cheats
+ cheat_entry *curcheat = reinterpret_cast<cheat_entry *>(ev->itemref);
const char *string;
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
- /* if selected, activate a oneshot */
+ // if selected, activate a oneshot
case IPT_UI_SELECT:
changed = curcheat->activate();
break;
- /* if cleared, reset to default value */
+ // if cleared, reset to default value
case IPT_UI_CLEAR:
changed = curcheat->select_default_state();
break;
- /* left decrements */
+ // left decrements
case IPT_UI_LEFT:
changed = curcheat->select_previous_state();
break;
- /* right increments */
+ // right increments
case IPT_UI_RIGHT:
changed = curcheat->select_next_state();
break;
- /* bring up display comment if one exists */
+ // 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 != nullptr && string[0] != 0)
+ if (string && *string)
machine().popmessage(_("Cheat Comment:\n%s"), string);
break;
}
}
- /* handle reload all */
- if (menu_event->itemref == ITEMREF_CHEATS_RELOAD_ALL && menu_event->iptkey == IPT_UI_SELECT)
+ // 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 */
+ // 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 */
+ // display the reloaded cheats
reset(reset_options::REMEMBER_REF);
machine().popmessage(_("All cheats reloaded"));
}
- /* if things changed, update */
+ // if things changed, update
if (changed)
reset(reset_options::REMEMBER_REF);
}
@@ -113,6 +108,7 @@ void menu_cheat::handle()
menu_cheat::menu_cheat(mame_ui_manager &mui, render_container &container) : menu(mui, container)
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
void menu_cheat::populate(float &customtop, float &custombottom)
diff --git a/src/frontend/mame/ui/cheatopt.h b/src/frontend/mame/ui/cheatopt.h
index 1d925cb2a71..c01ec151189 100644
--- a/src/frontend/mame/ui/cheatopt.h
+++ b/src/frontend/mame/ui/cheatopt.h
@@ -25,7 +25,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
} // namespace ui
diff --git a/src/frontend/mame/ui/confswitch.cpp b/src/frontend/mame/ui/confswitch.cpp
index be1346171d3..3aa10cd9133 100644
--- a/src/frontend/mame/ui/confswitch.cpp
+++ b/src/frontend/mame/ui/confswitch.cpp
@@ -82,6 +82,13 @@ menu_confswitch::~menu_confswitch()
}
+void menu_confswitch::menu_activated()
+{
+ // switches can have input assignments, and scripts are a thing
+ reset(reset_options::REMEMBER_REF);
+}
+
+
void menu_confswitch::populate(float &customtop, float &custombottom)
{
// locate relevant fields if necessary
@@ -162,31 +169,28 @@ void menu_confswitch::populate(float &customtop, float &custombottom)
}
item_append(menu_item_type::SEPARATOR);
- item_append(_("Reset"), 0, (void *)1);
+ item_append(_("Reset Machine"), 0, (void *)1);
}
-void menu_confswitch::handle()
+void menu_confswitch::handle(event const *ev)
{
- // process the menu
- event const *const menu_event(process(0));
-
// handle events
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
- if (uintptr_t(menu_event->itemref) == 1U)
+ if (uintptr_t(ev->itemref) == 1U)
{
// reset
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
machine().schedule_hard_reset();
}
else
{
// actual settings
- ioport_field &field(*reinterpret_cast<ioport_field *>(menu_event->itemref));
+ ioport_field &field(*reinterpret_cast<ioport_field *>(ev->itemref));
bool changed(false);
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
// if selected, reset to default value
case IPT_UI_SELECT:
diff --git a/src/frontend/mame/ui/confswitch.h b/src/frontend/mame/ui/confswitch.h
index 5ece14ae4c1..598b0208085 100644
--- a/src/frontend/mame/ui/confswitch.h
+++ b/src/frontend/mame/ui/confswitch.h
@@ -56,6 +56,7 @@ protected:
menu_confswitch(mame_ui_manager &mui, render_container &container, uint32_t type);
+ virtual void menu_activated() override;
virtual void populate(float &customtop, float &custombottom) override;
field_vector const &fields() { return m_fields; }
@@ -63,7 +64,7 @@ protected:
unsigned active_switch_groups() const { return m_active_switch_groups; }
private:
- virtual void handle() override;
+ virtual void 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 76d5b282534..982ec8bde39 100644
--- a/src/frontend/mame/ui/custui.cpp
+++ b/src/frontend/mame/ui/custui.cpp
@@ -45,6 +45,7 @@ menu_custom_ui::menu_custom_ui(mame_ui_manager &mui, render_container &container
, m_currlang(0)
, m_currsysnames(0)
{
+ set_process_flags(PROCESS_LR_REPEAT);
find_languages();
find_sysnames();
}
@@ -72,19 +73,17 @@ menu_custom_ui::~menu_custom_ui()
// handle
//-------------------------------------------------
-void menu_custom_ui::handle()
+void menu_custom_ui::handle(event const *ev)
{
bool changed = false;
// process the menu
- const event *menu_event = process(PROCESS_LR_REPEAT);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ if (ev && ev->itemref)
{
- switch ((uintptr_t)menu_event->itemref)
+ switch ((uintptr_t)ev->itemref)
{
case FONT_MENU:
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
menu::stack_push<menu_font_ui>(
ui(),
container(),
@@ -95,16 +94,16 @@ void menu_custom_ui::handle()
});
break;
case COLORS_MENU:
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
menu::stack_push<menu_colors_ui>(ui(), container());
break;
case HIDE_MENU:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
changed = true;
- (menu_event->iptkey == IPT_UI_RIGHT) ? ui_globals::panels_status++ : ui_globals::panels_status--;
+ (ev->iptkey == IPT_UI_RIGHT) ? ui_globals::panels_status++ : ui_globals::panels_status--;
}
- else if (menu_event->iptkey == IPT_UI_SELECT)
+ else if (ev->iptkey == IPT_UI_SELECT)
{
std::vector<std::string> s_sel(std::size(HIDE_STATUS));
std::transform(std::begin(HIDE_STATUS), std::end(HIDE_STATUS), s_sel.begin(), [](auto &s) { return _(s); });
@@ -118,15 +117,15 @@ void menu_custom_ui::handle()
}
break;
case LANGUAGE_MENU:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
changed = true;
- if (menu_event->iptkey == IPT_UI_LEFT)
+ if (ev->iptkey == IPT_UI_LEFT)
m_currlang = (m_currlang ? m_currlang : m_languages.size())- 1;
else if (++m_currlang >= m_languages.size())
m_currlang = 0;
}
- else if (menu_event->iptkey == IPT_UI_SELECT)
+ else if (ev->iptkey == IPT_UI_SELECT)
{
// copying list of language names - expensive
menu::stack_push<menu_selector>(
@@ -139,15 +138,15 @@ void menu_custom_ui::handle()
}
break;
case SYSNAMES_MENU:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
changed = true;
- if (menu_event->iptkey == IPT_UI_LEFT)
+ if (ev->iptkey == IPT_UI_LEFT)
m_currsysnames = (m_currsysnames ? m_currsysnames : m_sysnames.size())- 1;
else if (++m_currsysnames >= m_sysnames.size())
m_currsysnames = 0;
}
- else if (menu_event->iptkey == IPT_UI_SELECT)
+ else if (ev->iptkey == IPT_UI_SELECT)
{
// copying list of file names - expensive
menu::stack_push<menu_selector>(
@@ -308,6 +307,8 @@ menu_font_ui::menu_font_ui(mame_ui_manager &mui, render_container &container, st
, m_changed(false)
, m_actual(0U)
{
+ set_process_flags(PROCESS_LR_REPEAT);
+
std::string name(mui.machine().options().ui_font());
list();
@@ -374,41 +375,39 @@ menu_font_ui::~menu_font_ui()
// handle
//-------------------------------------------------
-void menu_font_ui::handle()
+void menu_font_ui::handle(event const *ev)
{
bool changed = false;
// process the menu
- const event *menu_event = process(PROCESS_LR_REPEAT);
-
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
- switch ((uintptr_t)menu_event->itemref)
+ switch ((uintptr_t)ev->itemref)
{
case INFOS_SIZE:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
- (menu_event->iptkey == IPT_UI_RIGHT) ? m_info_size += 0.05f : m_info_size -= 0.05f;
+ (ev->iptkey == IPT_UI_RIGHT) ? m_info_size += 0.05f : m_info_size -= 0.05f;
changed = true;
}
break;
case FONT_SIZE:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
- (menu_event->iptkey == IPT_UI_RIGHT) ? m_font_size++ : m_font_size--;
+ (ev->iptkey == IPT_UI_RIGHT) ? m_font_size++ : m_font_size--;
changed = true;
}
break;
case MUI_FNT:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
- (menu_event->iptkey == IPT_UI_RIGHT) ? m_actual++ : m_actual--;
+ (ev->iptkey == IPT_UI_RIGHT) ? m_actual++ : m_actual--;
changed = true;
}
- else if (menu_event->iptkey == IPT_UI_SELECT)
+ else if (ev->iptkey == IPT_UI_SELECT)
{
std::vector<std::string> display_names;
display_names.reserve(m_fonts.size());
@@ -428,9 +427,9 @@ void menu_font_ui::handle()
#ifdef UI_WINDOWS
case MUI_BOLD:
case MUI_ITALIC:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT || menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT)
{
- ((uintptr_t)menu_event->itemref == MUI_BOLD) ? m_bold = !m_bold : m_italic = !m_italic;
+ ((uintptr_t)ev->itemref == MUI_BOLD) ? m_bold = !m_bold : m_italic = !m_italic;
changed = true;
}
break;
@@ -551,17 +550,17 @@ menu_colors_ui::~menu_colors_ui()
// handle
//-------------------------------------------------
-void menu_colors_ui::handle()
+void menu_colors_ui::handle(event const *ev)
{
bool changed = false;
// process the menu
- const event *menu_event = process(0);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr && menu_event->iptkey == IPT_UI_SELECT)
+ if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT)
{
- if ((uintptr_t)menu_event->itemref != MUI_RESTORE)
- menu::stack_push<menu_rgb_ui>(ui(), container(), &m_color_table[(uintptr_t)menu_event->itemref].color, selected_item().text);
+ if ((uintptr_t)ev->itemref != MUI_RESTORE)
+ {
+ menu::stack_push<menu_rgb_ui>(ui(), container(), &m_color_table[(uintptr_t)ev->itemref].color, selected_item().text);
+ }
else
{
changed = true;
@@ -767,6 +766,7 @@ menu_rgb_ui::menu_rgb_ui(mame_ui_manager &mui, render_container &container, rgb_
m_lock_ref(0),
m_title(_title)
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
//-------------------------------------------------
@@ -781,26 +781,19 @@ menu_rgb_ui::~menu_rgb_ui()
// handle
//-------------------------------------------------
-void menu_rgb_ui::handle()
+void menu_rgb_ui::handle(event const *ev)
{
// process the menu
- const event *menu_event;
-
- if (!m_key_active)
- menu_event = process(PROCESS_LR_REPEAT);
- else
- menu_event = process(PROCESS_ONLYCHAR);
-
- if (menu_event && menu_event->itemref != nullptr)
+ if (ev && ev->itemref)
{
bool changed = false;
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_LEFT:
case IPT_UI_RIGHT:
{
- int updated = (IPT_UI_LEFT == menu_event->iptkey) ? -1 : 1;
- switch (uintptr_t(menu_event->itemref))
+ int updated = (IPT_UI_LEFT == ev->iptkey) ? -1 : 1;
+ switch (uintptr_t(ev->itemref))
{
case RGB_ALPHA:
updated += m_color->a();
@@ -839,20 +832,20 @@ void menu_rgb_ui::handle()
break;
case IPT_UI_SELECT:
- if (uintptr_t(menu_event->itemref) == PALETTE_CHOOSE)
+ if (uintptr_t(ev->itemref) == PALETTE_CHOOSE)
{
menu::stack_push<menu_palette_sel>(ui(), container(), *m_color);
break;
}
[[fallthrough]];
case IPT_SPECIAL:
- switch (uintptr_t(menu_event->itemref))
+ switch (uintptr_t(ev->itemref))
{
case RGB_ALPHA:
case RGB_RED:
case RGB_GREEN:
case RGB_BLUE:
- inkey_special(menu_event);
+ inkey_special(ev);
changed = true;
break;
}
@@ -1004,6 +997,7 @@ void menu_rgb_ui::inkey_special(const event *menu_event)
if (menu_event->iptkey == IPT_UI_SELECT)
{
m_key_active = !m_key_active;
+ set_process_flags(m_key_active ? PROCESS_ONLYCHAR : PROCESS_LR_REPEAT);
m_lock_ref = (uintptr_t)menu_event->itemref;
if (!m_key_active)
@@ -1079,13 +1073,12 @@ menu_palette_sel::~menu_palette_sel()
// handle
//-------------------------------------------------
-void menu_palette_sel::handle()
+void menu_palette_sel::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ if (ev && ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
m_original = rgb_t(uint32_t(strtoul(selected_item().subtext.c_str(), nullptr, 16)));
reset_parent(reset_options::SELECT_FIRST);
diff --git a/src/frontend/mame/ui/custui.h b/src/frontend/mame/ui/custui.h
index 33e8149ffdc..f693b9eab24 100644
--- a/src/frontend/mame/ui/custui.h
+++ b/src/frontend/mame/ui/custui.h
@@ -44,7 +44,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
void find_languages();
void find_sysnames();
@@ -82,7 +82,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
void list();
@@ -143,7 +143,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
s_color_table m_color_table[MUI_RESTORE];
void restore_colors();
@@ -173,7 +173,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
void inkey_special(const event *menu_event);
@@ -196,7 +196,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
static std::pair<const char *, const char *> const s_palette[];
rgb_t &m_original;
diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp
index 10c5e3c9717..df8ac0a7e67 100644
--- a/src/frontend/mame/ui/datmenu.cpp
+++ b/src/frontend/mame/ui/datmenu.cpp
@@ -24,6 +24,7 @@
#include "uiinput.h"
#include <cmath>
+#include <limits>
#include <string_view>
@@ -34,14 +35,14 @@ namespace ui {
//-------------------------------------------------
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_system_info *system)
- : menu(mui, container)
+ : menu_textbox(mui, container)
, m_system(!system ? &system_list::instance().systems()[driver_list::find(mui.machine().system().name)] : system)
, m_swinfo(nullptr)
, m_issoft(false)
- , m_layout()
, m_actual(0)
{
+ set_process_flags(PROCESS_LR_ALWAYS | PROCESS_CUSTOM_NAV);
for (device_image_interface& image : image_interface_enumerator(mui.machine().root_device()))
{
if (image.filename())
@@ -71,11 +72,10 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container
//-------------------------------------------------
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_software_info &swinfo)
- : menu(mui, container)
+ : menu_textbox(mui, container)
, m_system(nullptr)
, m_swinfo(&swinfo)
, m_issoft(true)
- , m_layout()
, m_actual(0)
, m_list(swinfo.listname)
, m_short(swinfo.shortname)
@@ -83,6 +83,7 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container
, m_parent(swinfo.parentname)
{
+ set_process_flags(PROCESS_LR_ALWAYS | PROCESS_CUSTOM_NAV);
if (!swinfo.infotext.empty())
m_items_list.emplace_back(_("Software List Info"), 0, "");
std::vector<std::string> lua_list;
@@ -165,18 +166,17 @@ void menu_dats_view::add_info_text(text_layout &layout, std::string_view text, r
// handle
//-------------------------------------------------
-void menu_dats_view::handle()
+void menu_dats_view::handle(event const *ev)
{
- event const *const menu_event = process(PROCESS_LR_ALWAYS | PROCESS_CUSTOM_NAV);
- if (menu_event)
+ if (ev)
{
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_LEFT:
if (m_actual > 0)
{
m_actual--;
- reset(reset_options::SELECT_FIRST);
+ reset_layout();
}
break;
@@ -184,33 +184,12 @@ void menu_dats_view::handle()
if ((m_actual + 1) < m_items_list.size())
{
m_actual++;
- reset(reset_options::SELECT_FIRST);
+ reset_layout();
}
break;
- case IPT_UI_UP:
- --top_line;
- break;
-
- case IPT_UI_DOWN:
- ++top_line;
- break;
-
- case IPT_UI_PAGE_UP:
- top_line -= m_visible_lines - 3;
- break;
-
- case IPT_UI_PAGE_DOWN:
- top_line += m_visible_lines - 3;
- break;
-
- case IPT_UI_HOME:
- top_line = 0;
- break;
-
- case IPT_UI_END:
- top_line = m_layout->lines() - m_visible_lines;
- break;
+ default:
+ handle_key(ev->iptkey);
}
}
}
@@ -221,150 +200,8 @@ void menu_dats_view::handle()
void menu_dats_view::populate(float &customtop, float &custombottom)
{
- bool paused = machine().paused();
- if (!paused)
- machine().pause();
-
- m_layout = std::nullopt;
-
customtop = 2.0f * ui().get_line_height() + 4.0f * ui().box_tb_border();
custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border();
-
- if (!paused)
- machine().resume();
-}
-
-//-------------------------------------------------
-// draw - draw dats menu
-//-------------------------------------------------
-
-void menu_dats_view::draw(uint32_t flags)
-{
- float const aspect = machine().render().ui_aspect(&container());
- float const line_height = ui().get_line_height();
- float const ud_arrow_width = line_height * aspect;
- float const gutter_width = 0.52f * line_height * aspect;
- float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
- float const visible_left = (1.0f - visible_width) * 0.5f;
- float const extra_height = 2.0f * line_height;
- float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
-
- // determine effective positions taking into account the hilighting arrows
- float const effective_width = visible_width - 2.0f * gutter_width;
- float const effective_left = visible_left + gutter_width;
-
- draw_background();
- map_mouse();
-
- // account for extra space at the top and bottom
- float visible_main_menu_height = 1.0f - 2.0f * ui().box_tb_border() - visible_extra_menu_height;
- m_visible_lines = int(std::trunc(visible_main_menu_height / line_height));
- visible_main_menu_height = float(m_visible_lines) * line_height;
-
- // compute top/left of inner menu area by centering, if the menu is at the bottom of the extra, adjust
- float const visible_top = ((1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f) + get_customtop();
-
- // compute text box size
- float const x1 = visible_left;
- float const y1 = visible_top - ui().box_tb_border();
- float const x2 = x1 + visible_width;
- float const y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
- float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float const separator = visible_top + float(m_visible_lines) * line_height;
-
- ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
-
- if (!m_layout || (m_layout->width() != effective_width))
- {
- std::string buffer;
- if (!m_items_list.empty())
- {
- if (m_issoft)
- get_data_sw(buffer);
- else
- get_data(buffer);
- }
- m_layout.emplace(ui().create_layout(container(), effective_width));
- add_info_text(*m_layout, buffer, ui().colors().text_color());
- }
- int const visible_items = m_layout->lines();
- m_visible_lines = (std::min)(visible_items, m_visible_lines);
- top_line = (std::max)(0, top_line);
- if (top_line + m_visible_lines >= visible_items)
- top_line = visible_items - m_visible_lines;
-
- clear_hover();
- if (top_line)
- {
- // if we're on the top line, display the up arrow
- rgb_t fgcolor = ui().colors().text_color();
- if (mouse_in_rect(line_x0, visible_top, line_x1, visible_top + line_height))
- {
- fgcolor = ui().colors().mouseover_color();
- highlight(
- line_x0, visible_top,
- line_x1, visible_top + line_height,
- ui().colors().mouseover_bg_color());
- set_hover(HOVER_ARROW_UP);
- }
- draw_arrow(
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, visible_top + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, visible_top + 0.75f * line_height,
- fgcolor, ROT0);
- }
- if ((top_line + m_visible_lines) < visible_items)
- {
- // if we're on the bottom line, display the down arrow
- float const line_y = visible_top + float(m_visible_lines - 1) * line_height;
- rgb_t fgcolor = ui().colors().text_color();
- if (mouse_in_rect(line_x0, line_y, line_x1, line_y + line_height))
- {
- fgcolor = ui().colors().mouseover_color();
- highlight(
- line_x0, line_y,
- line_x1, line_y + line_height,
- ui().colors().mouseover_bg_color());
- set_hover(HOVER_ARROW_DOWN);
- }
- draw_arrow(
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
- fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
- }
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- m_visible_items = m_visible_lines - (top_line ? 1 : 0) - (top_line + m_visible_lines != visible_items);
- m_layout->emit(
- container(),
- top_line ? (top_line + 1) : 0, m_visible_items,
- effective_left, visible_top + (top_line ? line_height : 0.0f));
-
- // add visual separator before the "return to prevous menu" item
- container().add_line(
- x1, separator + (0.5f * line_height),
- x2, separator + (0.5f * line_height),
- UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
- menu_item const &pitem = item(0);
- std::string_view const itemtext = pitem.text;
- float const line_y0 = separator + line_height;
- float const line_y1 = line_y0 + line_height;
-
- if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
- set_hover(0);
-
- highlight(line_x0, line_y0, line_x1, line_y1, ui().colors().selected_bg_color());
- ui().draw_text_full(
- container(), itemtext,
- effective_left, line_y0, effective_width,
- text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
- mame_ui_manager::NORMAL,
- ui().colors().selected_color(), ui().colors().selected_bg_color(),
- nullptr, nullptr);
-
- // if there is something special to add, do it by calling the virtual method
- custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
}
//-------------------------------------------------
@@ -512,7 +349,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
}
//-------------------------------------------------
-// load data from DATs
+// custom mouse click handling
//-------------------------------------------------
bool menu_dats_view::custom_mouse_down()
@@ -533,6 +370,28 @@ bool menu_dats_view::custom_mouse_down()
}
//-------------------------------------------------
+// populate selected DAT text
+//-------------------------------------------------
+
+void menu_dats_view::populate_text(std::optional<text_layout> &layout, float &width, int &lines)
+{
+ if (!layout || (layout->width() != width))
+ {
+ std::string buffer;
+ if (!m_items_list.empty())
+ {
+ if (m_issoft)
+ get_data_sw(buffer);
+ else
+ get_data(buffer);
+ }
+ layout.emplace(ui().create_layout(container(), width));
+ add_info_text(*layout, buffer, ui().colors().text_color());
+ lines = std::numeric_limits<int>::max();
+ }
+}
+
+//-------------------------------------------------
// load data from DATs
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/datmenu.h b/src/frontend/mame/ui/datmenu.h
index 9e81d9e2d2e..79b9bd8c1f6 100644
--- a/src/frontend/mame/ui/datmenu.h
+++ b/src/frontend/mame/ui/datmenu.h
@@ -14,8 +14,8 @@
#pragma once
-#include "ui/menu.h"
#include "ui/text.h"
+#include "ui/textbox.h"
#include <optional>
#include <string>
@@ -33,7 +33,7 @@ namespace ui {
// class dats menu
//-------------------------------------------------
-class menu_dats_view : public menu
+class menu_dats_view : public menu_textbox
{
public:
menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_software_info &swinfo);
@@ -46,6 +46,8 @@ protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_mouse_down() override;
+ virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
+
private:
struct list_items
{
@@ -56,11 +58,8 @@ private:
std::string revision;
};
- // draw dats menu
- virtual void draw(uint32_t flags) override;
-
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
void get_data(std::string &buffer);
void get_data_sw(std::string &buffer);
@@ -68,7 +67,6 @@ private:
ui_system_info const *const m_system;
ui_software_info const *const m_swinfo;
bool const m_issoft;
- std::optional<text_layout> m_layout;
int m_actual;
std::string m_list, m_short, m_long, m_parent;
std::vector<list_items> m_items_list;
diff --git a/src/frontend/mame/ui/devopt.cpp b/src/frontend/mame/ui/devopt.cpp
index 178f0af8d96..fea0f5106d3 100644
--- a/src/frontend/mame/ui/devopt.cpp
+++ b/src/frontend/mame/ui/devopt.cpp
@@ -22,290 +22,337 @@ namespace ui {
menu
-------------------------------------------------*/
-menu_device_config::menu_device_config(mame_ui_manager &mui, render_container &container, device_slot_interface *slot, device_slot_interface::slot_option const *option) : menu(mui, container)
+menu_device_config::menu_device_config(
+ mame_ui_manager &mui,
+ render_container &container,
+ device_slot_interface *slot,
+ device_slot_interface::slot_option const *option)
+ : menu_textbox(mui, container)
+ , m_option(option)
{
- m_option = option;
- m_owner = slot;
- m_mounted = slot->device().subdevice(option->name()) != nullptr;
+ m_mounted = machine().root_device().subdevice(slot->device().subtag(option->name())) != nullptr;
}
-void menu_device_config::populate(float &customtop, float &custombottom)
+menu_device_config::~menu_device_config()
+{
+}
+
+void menu_device_config::populate_text(std::optional<text_layout> &layout, float &width, int &lines)
{
- machine_config &mconfig(const_cast<machine_config &>(machine().config()));
- machine_config::token const tok(mconfig.begin_configuration(mconfig.root_device()));
- device_t *const dev = mconfig.device_add(m_option->name(), m_option->devtype(), 0);
- for (device_t &d : device_enumerator(*dev))
- if (!d.configured())
- d.config_complete();
-
- std::ostringstream str;
- util::stream_format(
- str,
- m_mounted
- ? _("[This option is currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nThe selected option enables the following items:\n")
- : _("[This option is NOT currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nIf you select this option, the following items will be enabled:\n"),
- m_option->name(),
- dev->name());
-
- // loop over all CPUs
- execute_interface_enumerator execiter(*dev);
- if (execiter.count() > 0)
+ if (!layout || (layout->width() != width))
{
- str << _("* CPU:\n");
- std::unordered_set<std::string> exectags;
- for (device_execute_interface &exec : execiter)
+ rgb_t const color = ui().colors().text_color();
+ layout.emplace(ui().create_layout(container(), width));
+
+ machine_config &mconfig(const_cast<machine_config &>(machine().config()));
+ machine_config::token const tok(mconfig.begin_configuration(mconfig.root_device()));
+ device_t *const dev = mconfig.device_add(m_option->name(), m_option->devtype(), 0);
+ for (device_t &d : device_enumerator(*dev))
+ if (!d.configured())
+ d.config_complete();
+
+ layout->add_text(
+ util::string_format(
+ m_mounted
+ ? _("[This option is currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nThe selected option enables the following items:\n")
+ : _("[This option is NOT currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nIf you select this option, the following items will be enabled:\n"),
+ m_option->name(),
+ dev->name()),
+ color);
+
+ // loop over all CPUs
+ execute_interface_enumerator execiter(*dev);
+ if (execiter.count() > 0)
{
- if (!exectags.insert(exec.device().tag()).second)
- continue;
+ layout->add_text(_("* CPU:\n"), color);
+ std::unordered_set<std::string> exectags;
+ for (device_execute_interface &exec : execiter)
+ {
+ if (!exectags.insert(exec.device().tag()).second)
+ continue;
- // get cpu specific clock that takes internal multiplier/dividers into account
- u32 clock = exec.device().clock();
+ // get cpu specific clock that takes internal multiplier/dividers into account
+ u32 clock = exec.device().clock();
- // count how many identical CPUs we have
- int count = 1;
- const char *name = exec.device().name();
- for (device_execute_interface &scan : execiter)
- {
- if (exec.device().type() == scan.device().type() && strcmp(name, scan.device().name()) == 0 && exec.device().clock() == scan.device().clock())
- if (exectags.insert(scan.device().tag()).second)
- count++;
- }
+ // count how many identical CPUs we have
+ int count = 1;
+ const char *name = exec.device().name();
+ for (device_execute_interface &scan : execiter)
+ {
+ if (exec.device().type() == scan.device().type() && strcmp(name, scan.device().name()) == 0 && exec.device().clock() == scan.device().clock())
+ if (exectags.insert(scan.device().tag()).second)
+ count++;
+ }
- std::string hz(std::to_string(clock));
- int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0;
- if (d > 0)
- {
- size_t dpos = hz.length() - d;
- hz.insert(dpos, ".");
- size_t last = hz.find_last_not_of('0');
- hz = hz.substr(0, last + (last != dpos ? 1 : 0));
- }
+ std::string hz(std::to_string(clock));
+ int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0;
+ if (d > 0)
+ {
+ size_t dpos = hz.length() - d;
+ hz.insert(dpos, ".");
+ size_t last = hz.find_last_not_of('0');
+ hz = hz.substr(0, last + (last != dpos ? 1 : 0));
+ }
- // if more than one, prepend a #x in front of the CPU name and display clock
- util::stream_format(str,
- (count > 1)
- ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n")
- : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"),
- count, name, hz,
- (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz"));
+ // if more than one, prepend a #x in front of the CPU name and display clock
+ layout->add_text(
+ util::string_format(
+ (count > 1)
+ ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n")
+ : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"),
+ count, name, hz,
+ (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")),
+ color);
+ }
}
- }
- // display screen information
- screen_device_enumerator scriter(*dev);
- if (scriter.count() > 0)
- {
- str << _("* Video:\n");
- for (screen_device &screen : scriter)
+ // display screen information
+ screen_device_enumerator scriter(*dev);
+ if (scriter.count() > 0)
{
- if (screen.screen_type() == SCREEN_TYPE_VECTOR)
+ layout->add_text(_("* Video:\n"), color);
+ for (screen_device &screen : scriter)
{
- util::stream_format(str, _(" Screen '%1$s': Vector\n"), screen.tag());
+ if (screen.screen_type() == SCREEN_TYPE_VECTOR)
+ {
+ layout->add_text(util::string_format(_(" Screen '%1$s': Vector\n"), screen.tag()), color);
+ }
+ else
+ {
+ std::string hz(std::to_string(float(screen.frame_period().as_hz())));
+ size_t last = hz.find_last_not_of('0');
+ size_t dpos = hz.find_last_of('.');
+ hz = hz.substr(0, last + (last != dpos ? 1 : 0));
+
+ const rectangle &visarea = screen.visible_area();
+ layout->add_text(
+ util::string_format(
+ (screen.orientation() & ORIENTATION_SWAP_XY)
+ ? _(" Screen '%1$s': %2$d \xC3\x97 %3$d (V) %4$s\xC2\xA0Hz\n")
+ : _(" Screen '%1$s': %2$d \xC3\x97 %3$d (H) %4$s\xC2\xA0Hz\n"),
+ screen.tag(),
+ visarea.width(),
+ visarea.height(),
+ hz),
+ color);
+ }
}
- else
+ }
+
+ // loop over all sound chips
+ sound_interface_enumerator snditer(*dev);
+ if (snditer.count() > 0)
+ {
+ layout->add_text(_("* Sound:\n"), color);
+ std::unordered_set<std::string> soundtags;
+ for (device_sound_interface &sound : snditer)
{
- std::string hz(std::to_string(float(screen.frame_period().as_hz())));
- size_t last = hz.find_last_not_of('0');
- size_t dpos = hz.find_last_of('.');
- hz = hz.substr(0, last + (last != dpos ? 1 : 0));
-
- const rectangle &visarea = screen.visible_area();
- util::stream_format(
- str,
- (screen.orientation() & ORIENTATION_SWAP_XY)
- ? _(" Screen '%1$s': %2$d \xC3\x97 %3$d (V) %4$s\xC2\xA0Hz\n")
- : _(" Screen '%1$s': %2$d \xC3\x97 %3$d (H) %4$s\xC2\xA0Hz\n"),
- screen.tag(),
- visarea.width(),
- visarea.height(),
- hz);
+ if (!sound.issound() || !soundtags.insert(sound.device().tag()).second)
+ continue;
+
+ // count how many identical sound chips we have
+ int count = 1;
+ for (device_sound_interface &scan : snditer)
+ {
+ if (sound.device().type() == scan.device().type() && sound.device().clock() == scan.device().clock())
+ if (soundtags.insert(scan.device().tag()).second)
+ count++;
+ }
+
+ const u32 clock = sound.device().clock();
+ std::string hz(std::to_string(clock));
+ int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0;
+ if (d > 0)
+ {
+ size_t dpos = hz.length() - d;
+ hz.insert(dpos, ".");
+ size_t last = hz.find_last_not_of('0');
+ hz = hz.substr(0, last + (last != dpos ? 1 : 0));
+ }
+
+ // if more than one, prepend a #x in front of the name and display clock
+ layout->add_text(
+ util::string_format(
+ (count > 1)
+ ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n")
+ : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"),
+ count, sound.device().name(), hz,
+ (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")),
+ color);
}
}
- }
- // loop over all sound chips
- sound_interface_enumerator snditer(*dev);
- if (snditer.count() > 0)
- {
- str << _("* Sound:\n");
- std::unordered_set<std::string> soundtags;
- for (device_sound_interface &sound : snditer)
+ // scan for BIOS settings
+ int bios = 0;
+ if (dev->rom_region())
{
- if (!sound.issound() || !soundtags.insert(sound.device().tag()).second)
- continue;
-
- // count how many identical sound chips we have
- int count = 1;
- for (device_sound_interface &scan : snditer)
+ // first loop through roms in search of default bios (shortname)
+ char const *bios_str(nullptr);
+ for (const tiny_rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); ++rom)
{
- if (sound.device().type() == scan.device().type() && sound.device().clock() == scan.device().clock())
- if (soundtags.insert(scan.device().tag()).second)
- count++;
+ if (ROMENTRY_ISDEFAULT_BIOS(rom))
+ bios_str = rom->name;
}
- const u32 clock = sound.device().clock();
- std::string hz(std::to_string(clock));
- int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0;
- if (d > 0)
+ // then loop again to count bios options and to get the default bios complete name
+ char const *bios_desc(nullptr);
+ for (romload::system_bios const &rom : romload::entries(dev->rom_region()).get_system_bioses())
{
- size_t dpos = hz.length() - d;
- hz.insert(dpos, ".");
- size_t last = hz.find_last_not_of('0');
- hz = hz.substr(0, last + (last != dpos ? 1 : 0));
+ bios++;
+ if (bios_str && !std::strcmp(bios_str, rom.get_name()))
+ bios_desc = rom.get_description();
}
- // if more than one, prepend a #x in front of the name and display clock
- util::stream_format(str,
- (count > 1)
- ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n")
- : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"),
- count, sound.device().name(), hz,
- (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz"));
- }
- }
-
- // scan for BIOS settings
- int bios = 0;
- if (dev->rom_region())
- {
- // first loop through roms in search of default bios (shortname)
- char const *bios_str(nullptr);
- for (const tiny_rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); ++rom)
- {
- if (ROMENTRY_ISDEFAULT_BIOS(rom))
- bios_str = rom->name;
- }
-
- // then loop again to count bios options and to get the default bios complete name
- char const *bios_desc(nullptr);
- for (romload::system_bios const &rom : romload::entries(dev->rom_region()).get_system_bioses())
- {
- bios++;
- if (bios_str && !std::strcmp(bios_str, rom.get_name()))
- bios_desc = rom.get_description();
+ if (bios)
+ {
+ layout->add_text(
+ util::string_format(
+ _("* BIOS settings:\n %1$d options [default: %2$s]\n"),
+ bios,
+ bios_desc ? bios_desc : bios_str ? bios_str : ""),
+ color);
+ }
}
- if (bios)
- util::stream_format(str, _("* BIOS settings:\n %1$d options [default: %2$s]\n"), bios, bios_desc ? bios_desc : bios_str ? bios_str : "");
- }
-
- int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
- int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0;
- std::string errors;
- std::ostringstream dips_opt, confs_opt;
- ioport_list portlist;
- for (device_t &iptdev : device_enumerator(*dev))
- portlist.append(iptdev, errors);
-
- // check if the device adds inputs to the system
- for (auto &port : portlist)
- for (ioport_field &field : port.second->fields())
- {
- if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST)
- input_mj++;
- else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST)
- input_hana++;
- else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST)
- input_gamble++;
- else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST)
- input_analog++;
- else if (field.type() == IPT_ADJUSTER)
- input_adjust++;
- else if (field.type() == IPT_KEYPAD)
- input_keypad++;
- else if (field.type() == IPT_KEYBOARD)
- input_keyboard++;
- else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST)
- input++;
- else if (field.type() == IPT_DIPSWITCH)
+ int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
+ int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0;
+ std::string errors;
+ std::ostringstream dips_opt, confs_opt;
+ ioport_list portlist;
+ for (device_t &iptdev : device_enumerator(*dev))
+ portlist.append(iptdev, errors);
+
+ // check if the device adds inputs to the system
+ for (auto &port : portlist)
+ for (ioport_field &field : port.second->fields())
{
- dips++;
- bool def(false);
- for (ioport_setting const &setting : field.settings())
+ if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST)
+ input_mj++;
+ else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST)
+ input_hana++;
+ else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST)
+ input_gamble++;
+ else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST)
+ input_analog++;
+ else if (field.type() == IPT_ADJUSTER)
+ input_adjust++;
+ else if (field.type() == IPT_KEYPAD)
+ input_keypad++;
+ else if (field.type() == IPT_KEYBOARD)
+ input_keyboard++;
+ else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST)
+ input++;
+ else if (field.type() == IPT_DIPSWITCH)
{
- if (setting.value() == field.defvalue())
+ dips++;
+ bool def(false);
+ for (ioport_setting const &setting : field.settings())
{
- def = true;
- util::stream_format(dips_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name());
- break;
+ if (setting.value() == field.defvalue())
+ {
+ def = true;
+ util::stream_format(dips_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name());
+ break;
+ }
}
+ if (!def)
+ util::stream_format(dips_opt, _(" %1$s\n"), field.name());
}
- if (!def)
- util::stream_format(dips_opt, _(" %1$s\n"), field.name());
- }
- else if (field.type() == IPT_CONFIG)
- {
- confs++;
- bool def(false);
- for (ioport_setting const &setting : field.settings())
+ else if (field.type() == IPT_CONFIG)
{
- if (setting.value() == field.defvalue())
+ confs++;
+ bool def(false);
+ for (ioport_setting const &setting : field.settings())
{
- def = true;
- util::stream_format(confs_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name());
- break;
+ if (setting.value() == field.defvalue())
+ {
+ def = true;
+ util::stream_format(confs_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name());
+ break;
+ }
}
+ if (!def)
+ util::stream_format(confs_opt, _(" %1$s\n"), field.name());
}
- if (!def)
- util::stream_format(confs_opt, _(" %1$s\n"), field.name());
}
- }
- if (dips)
- str << _("* DIP switch settings:\n") << dips_opt.str();
- if (confs)
- str << _("* Configuration settings:\n") << confs_opt.str();
- if (input || input_mj || input_hana || input_gamble || input_analog || input_adjust || input_keypad || input_keyboard)
- str << _("* Input device(s):\n");
- if (input)
- util::stream_format(str, _(" User inputs [%1$d inputs]\n"), input);
- if (input_mj)
- util::stream_format(str, _(" Mahjong inputs [%1$d inputs]\n"), input_mj);
- if (input_hana)
- util::stream_format(str, _(" Hanafuda inputs [%1$d inputs]\n"), input_hana);
- if (input_gamble)
- util::stream_format(str, _(" Gambling inputs [%1$d inputs]\n"), input_gamble);
- if (input_analog)
- util::stream_format(str, _(" Analog inputs [%1$d inputs]\n"), input_analog);
- if (input_adjust)
- util::stream_format(str, _(" Adjuster inputs [%1$d inputs]\n"), input_adjust);
- if (input_keypad)
- util::stream_format(str, _(" Keypad inputs [%1$d inputs]\n"), input_keypad);
- if (input_keyboard)
- util::stream_format(str, _(" Keyboard inputs [%1$d inputs]\n"), input_keyboard);
-
- image_interface_enumerator imgiter(*dev);
- if (imgiter.count() > 0)
- {
- str << _("* Media Options:\n");
- for (const device_image_interface &imagedev : imgiter)
- util::stream_format(str, _(" %1$s [tag: %2$s]\n"), imagedev.image_type_name(), imagedev.device().tag());
- }
+ if (dips)
+ {
+ layout->add_text(_("* DIP switch settings:\n"), color);
+ layout->add_text(std::move(dips_opt).str(), color);
+ }
+ if (confs)
+ {
+ layout->add_text(_("* Configuration settings:\n"), color);
+ layout->add_text(std::move(confs_opt).str(), color);
+ }
+ if (input || input_mj || input_hana || input_gamble || input_analog || input_adjust || input_keypad || input_keyboard)
+ layout->add_text(_("* Input device(s):\n"), color);
+ if (input)
+ layout->add_text(util::string_format(_(" User inputs [%1$d inputs]\n"), input), color);
+ if (input_mj)
+ layout->add_text(util::string_format(_(" Mahjong inputs [%1$d inputs]\n"), input_mj), color);
+ if (input_hana)
+ layout->add_text(util::string_format(_(" Hanafuda inputs [%1$d inputs]\n"), input_hana), color);
+ if (input_gamble)
+ layout->add_text(util::string_format(_(" Gambling inputs [%1$d inputs]\n"), input_gamble), color);
+ if (input_analog)
+ layout->add_text(util::string_format(_(" Analog inputs [%1$d inputs]\n"), input_analog), color);
+ if (input_adjust)
+ layout->add_text(util::string_format(_(" Adjuster inputs [%1$d inputs]\n"), input_adjust), color);
+ if (input_keypad)
+ layout->add_text(util::string_format(_(" Keypad inputs [%1$d inputs]\n"), input_keypad), color);
+ if (input_keyboard)
+ layout->add_text(util::string_format(_(" Keyboard inputs [%1$d inputs]\n"), input_keyboard), color);
+
+ image_interface_enumerator imgiter(*dev);
+ if (imgiter.count() > 0)
+ {
+ layout->add_text(_("* Media Options:\n"), color);
+ for (const device_image_interface &imagedev : imgiter)
+ {
+ layout->add_text(
+ util::string_format(
+ _(" %1$s [tag: %2$s]\n"),
+ imagedev.image_type_name(),
+ imagedev.device().tag()),
+ color);
+ }
+ }
- slot_interface_enumerator slotiter(*dev);
- if (slotiter.count() > 0)
- {
- str << _("* Slot Options:\n");
- for (const device_slot_interface &slot : slotiter)
- util::stream_format(str, _(" %1$s [default: %2$s]\n"), slot.device().tag(), slot.default_option() ? slot.default_option() : "----");
- }
+ slot_interface_enumerator slotiter(*dev);
+ if (slotiter.count() > 0)
+ {
+ layout->add_text(_("* Slot Options:\n"), color);
+ for (const device_slot_interface &slot : slotiter)
+ {
+ layout->add_text(
+ util::string_format(
+ _(" %1$s [default: %2$s]\n"),
+ slot.device().tag(),
+ slot.default_option() ? slot.default_option() : "----"),
+ color);
+ }
+ }
- if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs
- + input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard) == 0)
- str << _("[None]\n");
+ if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs
+ + input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard) == 0)
+ layout->add_text(_("[None]\n"), color);
- mconfig.device_remove(m_option->name());
- item_append(str.str(), FLAG_MULTILINE, nullptr);
+ mconfig.device_remove(m_option->name());
+ lines = layout->lines();
+ }
+ width = layout->actual_width();
}
-void menu_device_config::handle()
+void menu_device_config::populate(float &customtop, float &custombottom)
{
- /* process the menu */
- process(0);
}
-menu_device_config::~menu_device_config()
+void menu_device_config::handle(event const *ev)
{
+ if (ev)
+ handle_key(ev->iptkey);
}
} // namespace ui
diff --git a/src/frontend/mame/ui/devopt.h b/src/frontend/mame/ui/devopt.h
index 2bb4e24c6c0..b0e7a6a4d39 100644
--- a/src/frontend/mame/ui/devopt.h
+++ b/src/frontend/mame/ui/devopt.h
@@ -8,29 +8,33 @@
***************************************************************************/
-#pragma once
-
#ifndef MAME_FRONTEND_UI_DEVOPT_H
#define MAME_FRONTEND_UI_DEVOPT_H
-#include "ui/menu.h"
+#pragma once
+
+#include "ui/textbox.h"
+
namespace ui {
-class menu_device_config : public menu
+
+class menu_device_config : public menu_textbox
{
public:
menu_device_config(mame_ui_manager &mui, render_container &container, device_slot_interface *slot, device_slot_interface::slot_option const *option);
virtual ~menu_device_config() override;
+protected:
+ virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
+
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
- device_slot_interface *m_owner;
- device_slot_interface::slot_option const *m_option;
+ device_slot_interface::slot_option const *const m_option;
bool m_mounted;
};
} // namespace ui
-#endif /* MAME_FRONTEND_UI_DEVOPT_H */
+#endif // MAME_FRONTEND_UI_DEVOPT_H
diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp
index f610189b771..9a6b3c09b8d 100644
--- a/src/frontend/mame/ui/dirmenu.cpp
+++ b/src/frontend/mame/ui/dirmenu.cpp
@@ -90,12 +90,10 @@ menu_directory::~menu_directory()
// handle
//-------------------------------------------------
-void menu_directory::handle()
+void menu_directory::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr && menu_event->iptkey == IPT_UI_SELECT)
+ if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT)
menu::stack_push<menu_display_actual>(ui(), container(), selected_index());
}
@@ -146,12 +144,11 @@ menu_display_actual::~menu_display_actual()
// handle
//-------------------------------------------------
-void menu_display_actual::handle()
+void menu_display_actual::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
- if (menu_event != nullptr && menu_event->itemref != nullptr && menu_event->iptkey == IPT_UI_SELECT)
- switch ((uintptr_t)menu_event->itemref)
+ if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT)
+ switch ((uintptr_t)ev->itemref)
{
case REMOVE:
menu::stack_push<menu_remove_folder>(ui(), container(), m_ref);
@@ -245,16 +242,14 @@ menu_add_change_folder::~menu_add_change_folder()
// handle
//-------------------------------------------------
-void menu_add_change_folder::handle()
+void menu_add_change_folder::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ if (ev && ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
- int index = (uintptr_t)menu_event->itemref - 1;
+ int index = (uintptr_t)ev->itemref - 1;
const menu_item &pitem = item(index);
// go up to the parent path
@@ -283,11 +278,11 @@ void menu_add_change_folder::handle()
m_search.clear();
reset(reset_options::SELECT_FIRST);
}
- else if (menu_event->iptkey == IPT_SPECIAL)
+ else if (ev->iptkey == IPT_SPECIAL)
{
bool update_selected = false;
- if (menu_event->unichar == 0x09)
+ if (ev->unichar == 0x09)
{
// Tab key, save current path
std::string error_string;
@@ -325,7 +320,7 @@ void menu_add_change_folder::handle()
else
{
// if it's any other key and we're not maxed out, update
- update_selected = input_character(m_search, menu_event->unichar, uchar_is_printable);
+ update_selected = input_character(m_search, ev->unichar, uchar_is_printable);
}
// check for entries which matches our search buffer
@@ -374,7 +369,7 @@ void menu_add_change_folder::handle()
centre_selection();
}
}
- else if (menu_event->iptkey == IPT_UI_CANCEL)
+ else if (ev->iptkey == IPT_UI_CANCEL)
{
// reset the char buffer also in this case
m_search.clear();
@@ -467,11 +462,10 @@ menu_remove_folder::~menu_remove_folder()
// handle
//-------------------------------------------------
-void menu_remove_folder::handle()
+void menu_remove_folder::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
- if (menu_event != nullptr && menu_event->itemref != nullptr && menu_event->iptkey == IPT_UI_SELECT)
+ if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT)
{
std::string tmppath, error_string;
m_folders.erase(m_folders.begin() + selected_index());
diff --git a/src/frontend/mame/ui/dirmenu.h b/src/frontend/mame/ui/dirmenu.h
index 5d794319b7c..556427425e0 100644
--- a/src/frontend/mame/ui/dirmenu.h
+++ b/src/frontend/mame/ui/dirmenu.h
@@ -19,6 +19,7 @@
#include <vector>
namespace ui {
+
//-------------------------------------------------
// class directory menu
//-------------------------------------------------
@@ -34,7 +35,7 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
//-------------------------------------------------
@@ -58,7 +59,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::string m_heading[1], m_searchpath;
std::vector<std::string> m_folders;
@@ -80,7 +81,7 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::string m_searchpath;
int m_ref;
@@ -104,7 +105,7 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
int m_ref;
std::string m_current_path;
@@ -115,4 +116,4 @@ private:
} // namespace ui
-#endif /* MAME_FRONTEND_UI_DIRMENU_H */
+#endif // MAME_FRONTEND_UI_DIRMENU_H
diff --git a/src/frontend/mame/ui/filecreate.cpp b/src/frontend/mame/ui/filecreate.cpp
index 1474c562829..875fe1cd197 100644
--- a/src/frontend/mame/ui/filecreate.cpp
+++ b/src/frontend/mame/ui/filecreate.cpp
@@ -12,19 +12,18 @@
***************************************************************************/
#include "emu.h"
-
#include "ui/filecreate.h"
+
#include "ui/ui.h"
#include "ui/utils.h"
-#include "imagedev/floppy.h"
-
#include "zippath.h"
#include <cstring>
namespace ui {
+
/***************************************************************************
CONSTANTS
***************************************************************************/
@@ -86,15 +85,12 @@ void menu_confirm_save_as::populate(float &customtop, float &custombottom)
// handle - confirm save as menu
//-------------------------------------------------
-void menu_confirm_save_as::handle()
+void menu_confirm_save_as::handle(event const *ev)
{
- // process the menu
- const event *event = process(0);
-
// process the event
- if ((event != nullptr) && (event->iptkey == IPT_UI_SELECT))
+ if (ev && (ev->iptkey == IPT_UI_SELECT))
{
- if (event->itemref == ITEMREF_YES)
+ if (ev->itemref == ITEMREF_YES)
*m_yes = true;
// no matter what, pop out
@@ -190,19 +186,16 @@ void menu_file_create::populate(float &customtop, float &custombottom)
// handle - file creator menu
//-------------------------------------------------
-void menu_file_create::handle()
+void menu_file_create::handle(event const *ev)
{
- // process the menu
- const event *event = process(0);
-
// process the event
- if (event)
+ if (ev)
{
// handle selections
- switch (event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_SELECT:
- if ((event->itemref == ITEMREF_CREATE) || (event->itemref == ITEMREF_NEW_IMAGE_NAME))
+ 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)
@@ -218,7 +211,7 @@ void menu_file_create::handle()
case IPT_SPECIAL:
if (get_selection_ref() == ITEMREF_NEW_IMAGE_NAME)
{
- input_character(m_filename, event->unichar, &osd_is_valid_filename_char);
+ input_character(m_filename, ev->unichar, &osd_is_valid_filename_char);
reset(reset_options::REMEMBER_POSITION);
}
break;
@@ -278,13 +271,12 @@ void menu_select_format::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_select_format::handle()
+void menu_select_format::handle(event const *ev)
{
// process the menu
- const event *event = process(0);
- if (event != nullptr && event->iptkey == IPT_UI_SELECT)
+ if (ev && ev->iptkey == IPT_UI_SELECT)
{
- *m_result = (floppy_image_format_t *)event->itemref;
+ *m_result = (floppy_image_format_t *)ev->itemref;
stack_pop();
}
}
@@ -333,13 +325,12 @@ void menu_select_floppy_init::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_select_floppy_init::handle()
+void menu_select_floppy_init::handle(event const *ev)
{
// process the menu
- const event *event = process(0);
- if (event != nullptr && event->iptkey == IPT_UI_SELECT)
+ if (ev && ev->iptkey == IPT_UI_SELECT)
{
- *m_result = int(uintptr_t(event->itemref));
+ *m_result = int(uintptr_t(ev->itemref));
stack_pop();
}
}
diff --git a/src/frontend/mame/ui/filecreate.h b/src/frontend/mame/ui/filecreate.h
index f4e0b670fbd..2debc892859 100644
--- a/src/frontend/mame/ui/filecreate.h
+++ b/src/frontend/mame/ui/filecreate.h
@@ -14,11 +14,14 @@
#pragma once
#include "ui/menu.h"
+
#include "imagedev/floppy.h"
+
class floppy_image_format_t;
namespace ui {
+
// ======================> menu_confirm_save_as
class menu_confirm_save_as : public menu
@@ -29,7 +32,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
bool *m_yes;
};
@@ -48,7 +51,7 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
bool & m_ok;
device_image_interface * m_image;
@@ -69,7 +72,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// internal state
std::vector<floppy_image_format_t *> m_formats;
@@ -88,7 +91,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// internal state
const std::vector<floppy_image_device::fs_info> &m_fs;
diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp
index 1ef861e5475..029950865d4 100644
--- a/src/frontend/mame/ui/filemngr.cpp
+++ b/src/frontend/mame/ui/filemngr.cpp
@@ -106,7 +106,6 @@ void menu_file_manager::fill_image_line(device_image_interface *img, std::string
void menu_file_manager::populate(float &customtop, float &custombottom)
{
std::string tmp_inst, tmp_name;
- bool first_entry = true;
if (!m_warnings.empty())
{
@@ -132,18 +131,14 @@ void menu_file_manager::populate(float &customtop, float &custombottom)
if (!scan.user_loadable())
continue;
- // if it is a children device, and not something further down the device tree, we want it in the menu!
+ // if it is a child device, and not something further down the device tree, we want it in the menu!
if (strcmp(scan.device().owner()->tag(), dev.tag()) == 0)
if (devtags.insert(scan.device().tag()).second)
{
// check whether we already had some devices with the same owner: if not, output the owner tag!
if (!tag_appended)
{
- if (first_entry)
- first_entry = false;
- else
- item_append(menu_item_type::SEPARATOR);
- item_append(string_format("[root%s]", dev.tag()), 0, nullptr);
+ item_append(string_format(_("[root%1$s]"), dev.tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr);
tag_appended = true;
}
// finally, append the image interface to the menu
@@ -156,7 +151,7 @@ void menu_file_manager::populate(float &customtop, float &custombottom)
item_append(menu_item_type::SEPARATOR);
if (m_warnings.empty() || m_curr_selected)
- item_append("Reset", 0, (void *)1);
+ item_append(_("Reset Machine"), 0, (void *)1);
custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border();
}
@@ -166,19 +161,18 @@ void menu_file_manager::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_file_manager::handle()
+void menu_file_manager::handle(event const *ev)
{
// process the menu
- const event *event = process(0);
- if (event && event->itemref && (event->iptkey == IPT_UI_SELECT))
+ if (ev && ev->itemref && (ev->iptkey == IPT_UI_SELECT))
{
- if ((uintptr_t)event->itemref == 1)
+ if ((uintptr_t)ev->itemref == 1)
{
machine().schedule_hard_reset();
}
else
{
- selected_device = (device_image_interface *) event->itemref;
+ selected_device = (device_image_interface *) ev->itemref;
if (selected_device)
{
m_curr_selected = true;
@@ -199,7 +193,7 @@ void menu_file_manager::handle()
void menu_file_manager::force_file_manager(mame_ui_manager &mui, render_container &container, const char *warnings)
{
// reset the menu stack
- menu::stack_reset(mui.machine());
+ menu::stack_reset(mui);
// add the quit entry followed by the game select entry
menu::stack_push_special_main<menu_quit_game>(mui, container);
diff --git a/src/frontend/mame/ui/filemngr.h b/src/frontend/mame/ui/filemngr.h
index d656bb9e692..a925e24b35e 100644
--- a/src/frontend/mame/ui/filemngr.h
+++ b/src/frontend/mame/ui/filemngr.h
@@ -34,7 +34,7 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
void fill_image_line(device_image_interface *img, std::string &instance, std::string &filename);
@@ -44,4 +44,4 @@ private:
} // namespace ui
-#endif /* MAME_FRONTEND_UI_FILEMNGR_H */
+#endif // MAME_FRONTEND_UI_FILEMNGR_H
diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp
index 1ddabffbb23..ea5c1e02e37 100644
--- a/src/frontend/mame/ui/filesel.cpp
+++ b/src/frontend/mame/ui/filesel.cpp
@@ -478,18 +478,17 @@ void menu_file_selector::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_file_selector::handle()
+void menu_file_selector::handle(event const *ev)
{
// process the menu
- event const *const event = process(0);
- if (event)
+ if (ev)
{
- if (event->iptkey == IPT_SPECIAL)
+ if (ev->iptkey == IPT_SPECIAL)
{
// if it's any other key and we're not maxed out, update
- type_search_char(event->unichar);
+ type_search_char(ev->unichar);
}
- else if (event->iptkey == IPT_UI_CANCEL)
+ else if (ev->iptkey == IPT_UI_CANCEL)
{
// reset the char buffer also in this case
if (!m_filename.empty())
@@ -498,10 +497,10 @@ void menu_file_selector::handle()
ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename);
}
}
- else if (event->itemref && (event->iptkey == IPT_UI_SELECT))
+ else if (ev->itemref && (ev->iptkey == IPT_UI_SELECT))
{
// handle selections
- select_item(*reinterpret_cast<file_selector_entry const *>(event->itemref));
+ select_item(*reinterpret_cast<file_selector_entry const *>(ev->itemref));
// reset the char buffer when pressing IPT_UI_SELECT
m_filename.clear();
@@ -556,13 +555,12 @@ void menu_select_rw::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_select_rw::handle()
+void menu_select_rw::handle(event const *ev)
{
// process the menu
- const event *event = process(0);
- if (event != nullptr && event->iptkey == IPT_UI_SELECT)
+ if (ev && ev->iptkey == IPT_UI_SELECT)
{
- m_result = result_from_itemref(event->itemref);
+ m_result = result_from_itemref(ev->itemref);
stack_pop();
}
}
diff --git a/src/frontend/mame/ui/filesel.h b/src/frontend/mame/ui/filesel.h
index 8eefce9462a..9f7eea7dbea 100644
--- a/src/frontend/mame/ui/filesel.h
+++ b/src/frontend/mame/ui/filesel.h
@@ -82,7 +82,7 @@ private:
std::string m_filename;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// methods
int compare_entries(const file_selector_entry *e1, const file_selector_entry *e2);
@@ -120,7 +120,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// internal state
bool m_can_in_place;
diff --git a/src/frontend/mame/ui/floppycntrl.cpp b/src/frontend/mame/ui/floppycntrl.cpp
index 2f1cc9e0192..d38691831f1 100644
--- a/src/frontend/mame/ui/floppycntrl.cpp
+++ b/src/frontend/mame/ui/floppycntrl.cpp
@@ -93,7 +93,7 @@ void menu_control_floppy_image::hook_load(const std::string &filename)
m_state = SELECT_RW;
}
-void menu_control_floppy_image::handle()
+void menu_control_floppy_image::menu_activated()
{
switch (m_state) {
case DO_CREATE: {
@@ -121,7 +121,7 @@ void menu_control_floppy_image::handle()
case SELECT_FORMAT:
if(!output_format) {
m_state = START_FILE;
- handle();
+ menu_activated();
} else {
const auto &fs = fd.get_create_fs();
output_filename = util::zippath_combine(m_current_directory, m_current_file);
@@ -140,7 +140,7 @@ void menu_control_floppy_image::handle()
case SELECT_INIT:
if(m_submenu_result.i == -1) {
m_state = START_FILE;
- handle();
+ menu_activated();
} else {
create_fs = &fd.get_create_fs()[m_submenu_result.i];
do_load_create();
@@ -179,7 +179,7 @@ void menu_control_floppy_image::handle()
break;
default:
- menu_control_device_image::handle();
+ menu_control_device_image::menu_activated();
}
}
diff --git a/src/frontend/mame/ui/floppycntrl.h b/src/frontend/mame/ui/floppycntrl.h
index 9b80cc7edaa..bdc1104d0a5 100644
--- a/src/frontend/mame/ui/floppycntrl.h
+++ b/src/frontend/mame/ui/floppycntrl.h
@@ -26,6 +26,9 @@ public:
menu_control_floppy_image(mame_ui_manager &ui, render_container &container, device_image_interface &image);
virtual ~menu_control_floppy_image() override;
+protected:
+ virtual void menu_activated() override;
+
private:
enum { SELECT_FORMAT = LAST_ID, SELECT_MEDIA, SELECT_INIT, SELECT_RW };
@@ -34,12 +37,10 @@ private:
const floppy_image_device::fs_info *create_fs;
std::string input_filename, output_filename;
- virtual void handle() override;
-
void do_load_create();
virtual void hook_load(const std::string &filename) override;
};
} // namespace ui
-#endif /* MAME_FRONTEND_UI_FLOPPYCNTRL_H */
+#endif // MAME_FRONTEND_UI_FLOPPYCNTRL_H
diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp
index 43f40603479..d4b00ee3077 100644
--- a/src/frontend/mame/ui/imgcntrl.cpp
+++ b/src/frontend/mame/ui/imgcntrl.cpp
@@ -185,6 +185,7 @@ void menu_control_device_image::hook_load(const std::string &name)
void menu_control_device_image::populate(float &customtop, float &custombottom)
{
+ throw emu_fatalerror("menu_control_device_image::populate: Shouldn't get here!");
}
@@ -192,7 +193,17 @@ void menu_control_device_image::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_control_device_image::handle()
+void menu_control_device_image::handle(event const *ev)
+{
+ throw emu_fatalerror("menu_control_device_image::handle: Shouldn't get here!");
+}
+
+
+//-------------------------------------------------
+// menu_activated
+//-------------------------------------------------
+
+void menu_control_device_image::menu_activated()
{
switch(m_state)
{
@@ -244,28 +255,28 @@ void menu_control_device_image::handle()
break;
case SELECT_ONE_PART:
- switch(m_submenu_result.swparts) {
- case menu_software_parts::result::ENTRY: {
+ switch (m_submenu_result.swparts)
+ {
+ case menu_software_parts::result::ENTRY:
load_software_part();
break;
- }
default: // return to list
m_state = SELECT_SOFTLIST;
break;
-
}
break;
case SELECT_OTHER_PART:
- switch(m_submenu_result.swparts) {
+ switch (m_submenu_result.swparts)
+ {
case menu_software_parts::result::ENTRY:
load_software_part();
break;
case menu_software_parts::result::FMGR:
m_state = START_FILE;
- handle();
+ menu_activated();
break;
case menu_software_parts::result::EMPTY:
@@ -275,18 +286,17 @@ void menu_control_device_image::handle()
case menu_software_parts::result::SWLIST:
m_state = START_SOFTLIST;
- handle();
+ menu_activated();
break;
case menu_software_parts::result::INVALID: // return to system
stack_pop();
break;
-
}
break;
case SELECT_FILE:
- switch(m_submenu_result.filesel)
+ switch (m_submenu_result.filesel)
{
case menu_file_selector::result::EMPTY:
m_image.unload();
@@ -304,7 +314,7 @@ void menu_control_device_image::handle()
case menu_file_selector::result::SOFTLIST:
m_state = START_SOFTLIST;
- handle();
+ menu_activated();
break;
default: // return to system
@@ -313,43 +323,51 @@ void menu_control_device_image::handle()
}
break;
- case CREATE_FILE: {
- bool can_create, need_confirm;
- test_create(can_create, need_confirm);
- if(can_create) {
- if(need_confirm) {
- menu::stack_push<menu_confirm_save_as>(ui(), container(), &m_create_confirmed);
- m_state = CREATE_CONFIRM;
- } else {
- m_state = DO_CREATE;
- handle();
+ case CREATE_FILE:
+ {
+ bool can_create, need_confirm;
+ test_create(can_create, need_confirm);
+ if (can_create)
+ {
+ if (need_confirm)
+ {
+ menu::stack_push<menu_confirm_save_as>(ui(), container(), &m_create_confirmed);
+ m_state = CREATE_CONFIRM;
+ }
+ else
+ {
+ m_state = DO_CREATE;
+ menu_activated();
+ }
+ }
+ else
+ {
+ m_state = START_FILE;
+ menu_activated();
}
- } else {
- m_state = START_FILE;
- handle();
}
break;
- }
case CREATE_CONFIRM:
m_state = m_create_confirmed ? DO_CREATE : START_FILE;
- handle();
+ menu_activated();
break;
case CHECK_CREATE:
m_state = m_create_ok ? CREATE_FILE : START_FILE;
- handle();
+ menu_activated();
break;
- case DO_CREATE: {
- auto path = util::zippath_combine(m_current_directory, m_current_file);
- image_init_result err = m_image.create(path, nullptr, nullptr);
- if (err != image_init_result::PASS)
- machine().popmessage("Error: %s", m_image.error());
- stack_pop();
+ case DO_CREATE:
+ {
+ auto path = util::zippath_combine(m_current_directory, m_current_file);
+ image_init_result err = m_image.create(path, nullptr, nullptr);
+ if (err != image_init_result::PASS)
+ machine().popmessage("Error: %s", m_image.error());
+ stack_pop();
+ }
break;
}
- }
}
} // namespace ui
diff --git a/src/frontend/mame/ui/imgcntrl.h b/src/frontend/mame/ui/imgcntrl.h
index a41a3f85f77..66a5ee5f81a 100644
--- a/src/frontend/mame/ui/imgcntrl.h
+++ b/src/frontend/mame/ui/imgcntrl.h
@@ -8,16 +8,18 @@
***************************************************************************/
-#pragma once
-
#ifndef MAME_FRONTEND_UI_IMAGECNTRL_H
#define MAME_FRONTEND_UI_IMAGECNTRL_H
-#include "ui/menu.h"
+#pragma once
+
#include "ui/filesel.h"
+#include "ui/menu.h"
#include "ui/swlist.h"
+
namespace ui {
+
// ======================> menu_control_device_image
class menu_control_device_image : public menu
@@ -53,8 +55,9 @@ protected:
bool m_create_ok;
// methods
+ virtual void menu_activated() override;
+ virtual void handle(event const *ev) override;
virtual void hook_load(const std::string &filename);
- virtual void handle() override;
private:
// instance variables
@@ -72,4 +75,4 @@ private:
} // namespace ui
-#endif /* MAME_FRONTEND_UI_IMAGECNTRL_H */
+#endif // MAME_FRONTEND_UI_IMAGECNTRL_H
diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp
index 0dc8b8979e9..8c5d1b43d2b 100644
--- a/src/frontend/mame/ui/info.cpp
+++ b/src/frontend/mame/ui/info.cpp
@@ -481,7 +481,7 @@ std::string machine_info::get_screen_desc(screen_device &screen) const
menu_game_info - handle the game information menu
-------------------------------------------------*/
-menu_game_info::menu_game_info(mame_ui_manager &mui, render_container &container) : menu(mui, container)
+menu_game_info::menu_game_info(mame_ui_manager &mui, render_container &container) : menu_textbox(mui, container)
{
}
@@ -489,15 +489,26 @@ menu_game_info::~menu_game_info()
{
}
+void menu_game_info::populate_text(std::optional<text_layout> &layout, float &width, int &lines)
+{
+ if (!layout || (layout->width() != width))
+ {
+ rgb_t const color = ui().colors().text_color();
+ layout.emplace(ui().create_layout(container(), width));
+ layout->add_text(ui().machine_info().game_info_string(), color);
+ lines = layout->lines();
+ }
+ width = layout->actual_width();
+}
+
void menu_game_info::populate(float &customtop, float &custombottom)
{
- item_append(ui().machine_info().game_info_string(), FLAG_MULTILINE, nullptr);
}
-void menu_game_info::handle()
+void menu_game_info::handle(event const *ev)
{
- // process the menu
- process(0);
+ if (ev)
+ handle_key(ev->iptkey);
}
@@ -505,7 +516,7 @@ void menu_game_info::handle()
menu_warn_info - handle the emulation warnings menu
-------------------------------------------------*/
-menu_warn_info::menu_warn_info(mame_ui_manager &mui, render_container &container) : menu(mui, container)
+menu_warn_info::menu_warn_info(mame_ui_manager &mui, render_container &container) : menu_textbox(mui, container)
{
}
@@ -513,15 +524,26 @@ menu_warn_info::~menu_warn_info()
{
}
+void menu_warn_info::populate_text(std::optional<text_layout> &layout, float &width, int &lines)
+{
+ if (!layout || (layout->width() != width))
+ {
+ rgb_t const color = ui().colors().text_color();
+ layout.emplace(ui().create_layout(container(), width));
+ layout->add_text(ui().machine_info().warnings_string(), color);
+ lines = layout->lines();
+ }
+ width = layout->actual_width();
+}
+
void menu_warn_info::populate(float &customtop, float &custombottom)
{
- item_append(ui().machine_info().warnings_string(), FLAG_MULTILINE, nullptr);
}
-void menu_warn_info::handle()
+void menu_warn_info::handle(event const *ev)
{
- // process the menu
- process(0);
+ if (ev)
+ handle_key(ev->iptkey);
}
@@ -537,6 +559,11 @@ menu_image_info::~menu_image_info()
{
}
+void menu_image_info::menu_activated()
+{
+ reset(reset_options::REMEMBER_POSITION);
+}
+
void menu_image_info::populate(float &customtop, float &custombottom)
{
ui_system_info const &system(system_list::instance().systems()[driver_list::find(machine().system().name)]);
@@ -547,10 +574,8 @@ void menu_image_info::populate(float &customtop, float &custombottom)
image_info(&image);
}
-void menu_image_info::handle()
+void menu_image_info::handle(event const *ev)
{
- // process the menu
- process(0);
}
diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h
index 7acb64c2a38..3f9fd7d8edb 100644
--- a/src/frontend/mame/ui/info.h
+++ b/src/frontend/mame/ui/info.h
@@ -13,7 +13,7 @@
#pragma once
-#include "ui/menu.h"
+#include "ui/textbox.h"
namespace ui {
@@ -86,27 +86,33 @@ private:
};
-class menu_game_info : public menu
+class menu_game_info : public menu_textbox
{
public:
menu_game_info(mame_ui_manager &mui, render_container &container);
virtual ~menu_game_info() override;
+protected:
+ virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
+
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
-class menu_warn_info : public menu
+class menu_warn_info : public menu_textbox
{
public:
menu_warn_info(mame_ui_manager &mui, render_container &container);
virtual ~menu_warn_info() override;
+protected:
+ virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
+
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
@@ -116,9 +122,12 @@ public:
menu_image_info(mame_ui_manager &mui, render_container &container);
virtual ~menu_image_info() override;
+protected:
+ virtual void menu_activated() override;
+
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void 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 12c2733af1a..4e541a7988c 100644
--- a/src/frontend/mame/ui/info_pty.cpp
+++ b/src/frontend/mame/ui/info_pty.cpp
@@ -41,9 +41,8 @@ void menu_pty_info::populate(float &customtop, float &custombottom)
}
}
-void menu_pty_info::handle()
+void menu_pty_info::handle(event const *ev)
{
- process(0);
}
} // namespace ui
diff --git a/src/frontend/mame/ui/info_pty.h b/src/frontend/mame/ui/info_pty.h
index 55249a34d34..16f65435be2 100644
--- a/src/frontend/mame/ui/info_pty.h
+++ b/src/frontend/mame/ui/info_pty.h
@@ -16,6 +16,7 @@
#include "ui/menu.h"
namespace ui {
+
class menu_pty_info : public menu
{
public:
@@ -24,7 +25,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
} // namespace ui
diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp
index 5ddf7864adf..a651795ef6c 100644
--- a/src/frontend/mame/ui/inputmap.cpp
+++ b/src/frontend/mame/ui/inputmap.cpp
@@ -45,12 +45,11 @@ void menu_input_groups::populate(float &customtop, float &custombottom)
item_append(menu_item_type::SEPARATOR);
}
-void menu_input_groups::handle()
+void menu_input_groups::handle(event const *ev)
{
// process the menu
- const event *const menu_event = process(0);
- if (menu_event && menu_event->iptkey == IPT_UI_SELECT)
- menu::stack_push<menu_input_general>(ui(), container(), int(uintptr_t(menu_event->itemref) - 1));
+ if (ev && (ev->iptkey == IPT_UI_SELECT))
+ menu::stack_push<menu_input_general>(ui(), container(), int(uintptr_t(ev->itemref) - 1));
}
@@ -243,6 +242,7 @@ void menu_input_specific::update_input(input_item_data &seqchangeditem)
/*-------------------------------------------------
menu_input - display a menu for inputs
-------------------------------------------------*/
+
menu_input::menu_input(mame_ui_manager &mui, render_container &container)
: menu(mui, container)
, data()
@@ -254,12 +254,20 @@ menu_input::menu_input(mame_ui_manager &mui, render_container &container)
, record_next(false)
, modified_ticks(0)
{
+ set_process_flags(PROCESS_LR_ALWAYS);
}
menu_input::~menu_input()
{
}
+void menu_input::menu_activated()
+{
+ // scripts can change settings out from under us
+ reset(reset_options::REMEMBER_REF);
+}
+
+
/*-------------------------------------------------
toggle_none_default - toggle between "NONE"
and the default item
@@ -329,13 +337,12 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float
}
}
-void menu_input::handle()
+void menu_input::handle(event const *ev)
{
input_item_data *seqchangeditem = nullptr;
bool invalidate = false;
// process the menu
- const event *const menu_event = process(pollingitem ? PROCESS_NOKEYS : PROCESS_LR_ALWAYS);
if (pollingitem)
{
// if we are polling, handle as a special case
@@ -349,6 +356,7 @@ void menu_input::handle()
{
// if UI_CANCEL is pressed, abort
pollingitem = nullptr;
+ set_process_flags(PROCESS_LR_ALWAYS);
if (!seq_poll->modified() || modified_ticks == osd_ticks())
{
// cancelled immediately - toggle between default and none
@@ -366,6 +374,7 @@ void menu_input::handle()
else if (seq_poll->poll()) // poll again; if finished, update the sequence
{
pollingitem = nullptr;
+ set_process_flags(PROCESS_LR_ALWAYS);
if (seq_poll->valid())
{
record_next = true;
@@ -382,13 +391,15 @@ void menu_input::handle()
seq_poll.reset();
}
}
- else if (menu_event && menu_event->itemref)
+ else if (ev && ev->itemref)
{
// otherwise, handle the events
- input_item_data &item = *reinterpret_cast<input_item_data *>(menu_event->itemref);
- switch (menu_event->iptkey)
+ input_item_data &item = *reinterpret_cast<input_item_data *>(ev->itemref);
+ input_item_data *newsel = &item;
+ switch (ev->iptkey)
{
case IPT_UI_SELECT: // an item was selected: begin polling
+ set_process_flags(PROCESS_NOKEYS);
errormsg.clear();
erroritem = nullptr;
modified_ticks = 0;
@@ -415,14 +426,63 @@ void menu_input::handle()
break;
case IPT_UI_LEFT: // flip between set and append
- case IPT_UI_RIGHT: // not very discoverable, but with the prompt it isn't opaque
+ case IPT_UI_RIGHT: // not very discoverable, but with the prompt it isn't completely opaque
if (record_next || !item.seq.empty())
record_next = !record_next;
break;
+
+ case IPT_UI_PREV_GROUP:
+ {
+ auto current = std::distance(data.data(), &item);
+ bool found_break = false;
+ while (0 < current)
+ {
+ if (!found_break)
+ {
+ if (data[--current].owner != item.owner)
+ found_break = true;
+ }
+ else if (data[current].owner != data[current - 1].owner)
+ {
+ newsel = &data[current];
+ set_selection(newsel);
+ set_top_line(selected_index() - 1);
+ break;
+ }
+ else
+ {
+ --current;
+ }
+ if (found_break && !current)
+ {
+ newsel = &data[current];
+ set_selection(newsel);
+ set_top_line(selected_index() - 1);
+ break;
+ }
+ }
+ }
+ break;
+
+ case IPT_UI_NEXT_GROUP:
+ {
+ auto current = std::distance(data.data(), &item);
+ while (data.size() > ++current)
+ {
+ if (data[current].owner != item.owner)
+ {
+ newsel = &data[current];
+ set_selection(newsel);
+ set_top_line(selected_index() - 1);
+ break;
+ }
+ }
+ }
+ break;
}
// if the selection changed, reset the "record next" flag
- if (&item != lastitem)
+ if (newsel != lastitem)
{
if (erroritem)
{
@@ -460,15 +520,14 @@ void menu_input::populate_sorted(float &customtop, float &custombottom)
const char *nameformat[INPUT_TYPE_TOTAL] = { nullptr };
// create a mini lookup table for name format based on type
- nameformat[INPUT_TYPE_DIGITAL] = "%s";
- nameformat[INPUT_TYPE_ANALOG] = "%s Analog";
- nameformat[INPUT_TYPE_ANALOG_INC] = "%s Analog Inc";
- nameformat[INPUT_TYPE_ANALOG_DEC] = "%s Analog Dec";
+ nameformat[INPUT_TYPE_DIGITAL] = "%1$s";
+ nameformat[INPUT_TYPE_ANALOG] = _("input-name", "%1$s Analog");
+ nameformat[INPUT_TYPE_ANALOG_INC] = _("input-name", "%1$s Analog Inc");
+ nameformat[INPUT_TYPE_ANALOG_DEC] = _("input-name", "%1$s Analog Dec");
// build the menu
std::string text, subtext;
const device_t *prev_owner = nullptr;
- bool first_entry = true;
for (input_item_data &item : data)
{
// generate the name of the item itself, based off the base name and the type
@@ -476,10 +535,6 @@ void menu_input::populate_sorted(float &customtop, float &custombottom)
if (item.owner && (item.owner != prev_owner))
{
- if (first_entry)
- first_entry = false;
- else
- item_append(menu_item_type::SEPARATOR);
if (item.owner->owner())
item_append(string_format(_("%1$s [root%2$s]"), item.owner->type().fullname(), item.owner->tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr);
else
diff --git a/src/frontend/mame/ui/inputmap.h b/src/frontend/mame/ui/inputmap.h
index 8058342515e..841382daf21 100644
--- a/src/frontend/mame/ui/inputmap.h
+++ b/src/frontend/mame/ui/inputmap.h
@@ -29,7 +29,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
@@ -63,6 +63,9 @@ protected:
using data_vector = std::vector<input_item_data>;
menu_input(mame_ui_manager &mui, render_container &container);
+
+ virtual void menu_activated() override;
+
void populate_sorted(float &customtop, float &custombottom);
void toggle_none_default(input_seq &selected_seq, input_seq &original_seq, const input_seq &selected_defseq);
@@ -81,7 +84,7 @@ private:
input_seq starting_seq;
virtual void custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
virtual void update_input(input_item_data &seqchangeditem) = 0;
};
diff --git a/src/frontend/mame/ui/keyboard.cpp b/src/frontend/mame/ui/keyboard.cpp
index 36f12753e0c..7f6ffefb064 100644
--- a/src/frontend/mame/ui/keyboard.cpp
+++ b/src/frontend/mame/ui/keyboard.cpp
@@ -64,15 +64,14 @@ menu_keyboard_mode::~menu_keyboard_mode()
{
}
-void menu_keyboard_mode::handle()
+void menu_keyboard_mode::handle(event const *ev)
{
- event const *const menu_event(process(0));
- if (menu_event && uintptr_t(menu_event->itemref))
+ if (ev && uintptr_t(ev->itemref))
{
natural_keyboard &natkbd(machine().natkeyboard());
- uintptr_t const ref(uintptr_t(menu_event->itemref));
- bool const left(IPT_UI_LEFT == menu_event->iptkey);
- bool const right(IPT_UI_RIGHT == menu_event->iptkey);
+ uintptr_t const ref(uintptr_t(ev->itemref));
+ bool const left(IPT_UI_LEFT == ev->iptkey);
+ bool const right(IPT_UI_RIGHT == ev->iptkey);
if (ITEM_KBMODE == ref)
{
if ((left || right) && (natkbd.in_use() != right))
diff --git a/src/frontend/mame/ui/keyboard.h b/src/frontend/mame/ui/keyboard.h
index 899385e74c2..22ab3fe759a 100644
--- a/src/frontend/mame/ui/keyboard.h
+++ b/src/frontend/mame/ui/keyboard.h
@@ -25,7 +25,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
} // namespace ui
diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp
index a50c346a1fe..132902b8f81 100644
--- a/src/frontend/mame/ui/mainmenu.cpp
+++ b/src/frontend/mame/ui/mainmenu.cpp
@@ -84,7 +84,7 @@ enum : unsigned {
***************************************************************************/
/*-------------------------------------------------
- menu_main constructor - populate the main menu
+ menu_main constructor/destructor
-------------------------------------------------*/
menu_main::menu_main(mame_ui_manager &mui, render_container &container) : menu(mui, container)
@@ -92,9 +92,30 @@ menu_main::menu_main(mame_ui_manager &mui, render_container &container) : menu(m
set_needs_prev_menu_item(false);
}
+menu_main::~menu_main()
+{
+}
+
+
+/*-------------------------------------------------
+ menu_activated - handle coming to foreground
+-------------------------------------------------*/
+
+void menu_main::menu_activated()
+{
+ if (machine().phase() != m_phase)
+ reset(reset_options::REMEMBER_REF);
+}
+
+
+/*-------------------------------------------------
+ populate - populate main menu items
+-------------------------------------------------*/
+
void menu_main::populate(float &customtop, float &custombottom)
{
- /* add main menu items */
+ m_phase = machine().phase();
+
item_append(_("Input (general)"), 0, (void *)INPUT_GROUPS);
item_append(_("Input (this Machine)"), 0, (void *)INPUT_SPECIFIC);
@@ -156,7 +177,7 @@ void menu_main::populate(float &customtop, float &custombottom)
if (machine().options().cheat())
item_append(_("Cheat"), 0, (void *)CHEAT);
- if (machine().phase() >= machine_phase::RESET)
+ if (machine_phase::RESET <= m_phase)
{
if (machine().options().plugins() && !mame_machine_manager::instance()->lua()->get_menu().empty())
item_append(_("Plugin Options"), 0, (void *)PLUGINS);
@@ -180,7 +201,7 @@ void menu_main::populate(float &customtop, float &custombottom)
// item_append(_("Quit from Machine"), 0, (void *)QUIT_GAME);
- if (machine().phase() == machine_phase::INIT)
+ if (machine_phase::INIT == m_phase)
{
item_append(_("Start Machine"), 0, (void *)DISMISS);
}
@@ -191,20 +212,18 @@ void menu_main::populate(float &customtop, float &custombottom)
}
}
-menu_main::~menu_main()
-{
-}
/*-------------------------------------------------
- menu_main - handle the main menu
+ handle - handle main menu events
-------------------------------------------------*/
-void menu_main::handle()
+void menu_main::handle(event const *ev)
{
- /* process the menu */
- const event *menu_event = process(0);
- if (menu_event != nullptr && menu_event->iptkey == IPT_UI_SELECT) {
- switch(uintptr_t(menu_event->itemref)) {
+ // process the menu
+ if (ev && (ev->iptkey == IPT_UI_SELECT))
+ {
+ switch (uintptr_t(ev->itemref))
+ {
case INPUT_GROUPS:
menu::stack_push<menu_input_groups>(ui(), container());
break;
@@ -314,12 +333,12 @@ void menu_main::handle()
case ADD_FAVORITE:
mame_machine_manager::instance()->favorite().add_favorite(machine());
- reset(reset_options::REMEMBER_POSITION);
+ reset(reset_options::REMEMBER_REF);
break;
case REMOVE_FAVORITE:
mame_machine_manager::instance()->favorite().remove_favorite(machine());
- reset(reset_options::REMEMBER_POSITION);
+ reset(reset_options::REMEMBER_REF);
break;
case QUIT_GAME:
diff --git a/src/frontend/mame/ui/mainmenu.h b/src/frontend/mame/ui/mainmenu.h
index 284655c64c9..6671dd9f554 100644
--- a/src/frontend/mame/ui/mainmenu.h
+++ b/src/frontend/mame/ui/mainmenu.h
@@ -24,11 +24,16 @@ public:
menu_main(mame_ui_manager &mui, render_container &container);
virtual ~menu_main();
+protected:
+ virtual void menu_activated() override;
+
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
+
+ machine_phase m_phase;
};
} // namespace ui
-#endif /* MAME_FRONTEND_UI_MAINMENU_H */
+#endif // MAME_FRONTEND_UI_MAINMENU_H
diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp
index 9e98511a882..4df4731cb4f 100644
--- a/src/frontend/mame/ui/menu.cpp
+++ b/src/frontend/mame/ui/menu.cpp
@@ -33,21 +33,12 @@
namespace ui {
/***************************************************************************
- GLOBAL VARIABLES
-***************************************************************************/
-
-std::mutex menu::s_global_state_guard;
-menu::global_state_map menu::s_global_states;
-
-/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
-menu::global_state_ptr menu::get_global_state(running_machine &machine)
+menu::global_state &menu::get_global_state(mame_ui_manager &ui)
{
- std::lock_guard<std::mutex> guard(s_global_state_guard);
- auto const it(s_global_states.find(&machine));
- return (it != s_global_states.end()) ? it->second : global_state_ptr();
+ return ui.get_session_data<menu, global_state_wrapper>(ui);
}
//-------------------------------------------------
@@ -75,19 +66,20 @@ bool menu::exclusive_input_pressed(int &iptkey, int key, int repeat)
CORE SYSTEM MANAGEMENT
***************************************************************************/
-menu::global_state::global_state(running_machine &machine, ui_options const &options)
- : widgets_manager(machine)
- , m_machine(machine)
+menu::global_state::global_state(mame_ui_manager &ui)
+ : widgets_manager(ui.machine())
+ , m_ui(ui)
, m_bgrnd_bitmap()
- , m_bgrnd_texture(nullptr, machine.render())
+ , m_bgrnd_texture(nullptr, ui.machine().render())
, m_stack()
, m_free()
+ , m_hide(false)
{
- render_manager &render(machine.render());
+ render_manager &render(ui.machine().render());
// create a texture for main menu background
m_bgrnd_texture.reset(render.texture_alloc(render_texture::hq_scale));
- if (options.use_background_image() && (&machine.system() == &GAME_NAME(___empty)))
+ if (ui.options().use_background_image() && (&ui.machine().system() == &GAME_NAME(___empty)))
{
m_bgrnd_bitmap = std::make_unique<bitmap_argb32>(0, 0);
emu_file backgroundfile(".", OPEN_FLAG_READ);
@@ -113,10 +105,6 @@ menu::global_state::global_state(running_machine &machine, ui_options const &opt
menu::global_state::~global_state()
{
- // it shouldn't really be possible to get here with active menus because of reference loops
- assert(!m_stack);
- assert(!m_free);
-
stack_reset();
clear_free_list();
}
@@ -124,6 +112,11 @@ menu::global_state::~global_state()
void menu::global_state::stack_push(std::unique_ptr<menu> &&menu)
{
+ if (m_stack && m_stack->m_active)
+ {
+ m_stack->m_active = false;
+ m_stack->menu_deactivated();
+ }
menu->m_parent = std::move(m_stack);
m_stack = std::move(menu);
m_stack->machine().ui_input().reset();
@@ -134,11 +127,14 @@ void menu::global_state::stack_pop()
{
if (m_stack)
{
+ if (m_stack->m_one_shot)
+ m_hide = true;
+ m_stack->menu_dismissed();
std::unique_ptr<menu> menu(std::move(m_stack));
m_stack = std::move(menu->m_parent);
menu->m_parent = std::move(m_free);
m_free = std::move(menu);
- m_machine.ui_input().reset();
+ m_ui.machine().ui_input().reset();
}
}
@@ -177,40 +173,46 @@ bool menu::global_state::stack_has_special_main_menu() const
}
-
-
-//-------------------------------------------------
-// init - initialize the menu system
-//-------------------------------------------------
-
-void menu::init(running_machine &machine, ui_options &mopt)
+uint32_t menu::global_state::ui_handler(render_container &container)
{
- // initialize the menu stack
+ // if we have no menus stacked up, start with the main menu
+ if (!m_stack)
+ stack_push(std::unique_ptr<menu>(make_unique_clear<menu_main>(m_ui, container)));
+
+ // ensure topmost menu is active - need a loop because it could push another menu
+ while (m_stack && !m_stack->m_active)
{
- std::lock_guard<std::mutex> guard(s_global_state_guard);
- auto const ins(s_global_states.emplace(&machine, std::make_shared<global_state>(machine, mopt)));
- assert(ins.second); // calling init twice is bad
- if (ins.second)
- machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&menu::exit, &machine)); // add an exit callback to free memory
- else
- ins.first->second->stack_reset();
+ m_stack->m_active = true;
+ m_stack->menu_activated();
}
-}
+ // update the menu state
+ m_hide = false;
+ if (m_stack)
+ m_stack->do_handle();
-//-------------------------------------------------
-// exit - clean up after ourselves
-//-------------------------------------------------
+ // clear up anything pending being released
+ clear_free_list();
-void menu::exit(running_machine &machine)
-{
- // free menus
- global_state_ptr const state(get_global_state(machine));
- state->stack_reset();
- state->clear_free_list();
+ // if the menus are to be hidden, return a cancel here
+ if (m_ui.is_menu_active() && (m_hide || !m_stack))
+ {
+ if (m_stack)
+ {
+ if (m_stack->m_one_shot)
+ {
+ stack_pop();
+ }
+ else if (m_stack->m_active)
+ {
+ m_stack->m_active = false;
+ m_stack->menu_deactivated();
+ }
+ }
+ return UI_HANDLER_CANCEL;
+ }
- std::lock_guard<std::mutex> guard(s_global_state_guard);
- s_global_states.erase(&machine);
+ return 0;
}
@@ -224,16 +226,18 @@ void menu::exit(running_machine &machine)
//-------------------------------------------------
menu::menu(mame_ui_manager &mui, render_container &container)
- : m_selected(0)
- , m_items()
- , m_visible_lines(0)
- , m_visible_items(0)
- , m_global_state(get_global_state(mui.machine()))
- , m_special_main_menu(false)
- , m_needs_prev_menu_item(true)
+ : m_global_state(get_global_state(mui))
, m_ui(mui)
, m_container(container)
, m_parent()
+ , m_items()
+ , m_process_flags(0)
+ , m_selected(0)
+ , m_hover(1)
+ , m_special_main_menu(false)
+ , m_one_shot(false)
+ , m_needs_prev_menu_item(true)
+ , m_active(false)
, m_event()
, m_customtop(0.0f)
, m_custombottom(0.0f)
@@ -244,11 +248,11 @@ menu::menu(mame_ui_manager &mui, render_container &container)
, m_mouse_x(-1.0f)
, m_mouse_y(-1.0f)
{
- assert(m_global_state); // not calling init is bad
-
reset(reset_options::SELECT_FIRST);
top_line = 0;
+ m_visible_lines = 0;
+ m_visible_items = 0;
}
@@ -322,11 +326,6 @@ void menu::item_append(menu_item_type type, uint32_t flags)
void menu::item_append(std::string &&text, std::string &&subtext, uint32_t flags, void *ref, menu_item_type type)
{
- if ((flags & FLAG_MULTILINE) != 0) // only allow multiline as the first item
- assert(m_items.size() == 1);
- else if (m_items.size() >= 2) // only allow a single multi-line item
- assert((m_items[0].flags & FLAG_MULTILINE) == 0);
-
// allocate a new item and populate it
menu_item pitem;
pitem.text = std::move(text);
@@ -374,7 +373,7 @@ void menu::item_append_on_off(const std::string &text, bool state, uint32_t flag
// and returning any interesting events
//-------------------------------------------------
-const menu::event *menu::process(uint32_t flags, float x0, float y0)
+const menu::event *menu::process()
{
// reset the event
m_event.iptkey = IPT_INVALID;
@@ -382,21 +381,31 @@ const menu::event *menu::process(uint32_t flags, float x0, float y0)
// first make sure our selection is valid
validate_selection(1);
- // draw the menu
- if (m_items.size() > 1 && (m_items[0].flags & FLAG_MULTILINE) != 0)
- draw_text_box();
- else
- draw(flags);
+ // if we're not running the emulation, draw parent menus in the background
+ auto const draw_parent =
+ [] (auto &self, menu *parent) -> bool
+ {
+ if (!parent || !(parent->is_special_main_menu() || self(self, parent->m_parent.get())))
+ return false;
+ else
+ parent->draw(PROCESS_NOINPUT);
+ return true;
+ };
+ if (draw_parent(draw_parent, m_parent.get()))
+ 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
+ draw(m_process_flags);
// process input
- if (!(flags & PROCESS_NOKEYS) && !(flags & PROCESS_NOINPUT))
+ if (!(m_process_flags & (PROCESS_NOKEYS | PROCESS_NOINPUT)))
{
// read events
- handle_events(flags, m_event);
+ handle_events(m_process_flags, m_event);
// handle the keys if we don't already have an event
if (m_event.iptkey == IPT_INVALID)
- handle_keys(flags, m_event.iptkey);
+ handle_keys(m_process_flags, m_event.iptkey);
}
// update the selected item in the event
@@ -456,7 +465,6 @@ void menu::draw(uint32_t flags)
}
bool const customonly = (flags & PROCESS_CUSTOM_ONLY);
- bool const noimage = (flags & PROCESS_NOIMAGE);
bool const noinput = (flags & PROCESS_NOINPUT);
float const aspect = machine().render().ui_aspect(&container());
float const line_height = ui().get_line_height();
@@ -465,7 +473,7 @@ void menu::draw(uint32_t flags)
float const gutter_width = lr_arrow_width * 1.3f;
float const lr_border = ui().box_lr_border() * aspect;
- if (&machine().system() == &GAME_NAME(___empty) && !noimage)
+ if (is_special_main_menu())
draw_background();
// compute the width and height of the full menu
@@ -778,87 +786,6 @@ void menu::custom_render(void *selectedref, float top, float bottom, float x, fl
{
}
-//-------------------------------------------------
-// draw_text_box - draw a multiline
-// word-wrapped text box with a menu item at the
-// bottom
-//-------------------------------------------------
-
-void menu::draw_text_box()
-{
- std::string_view const text = m_items[0].text;
- std::string_view const backtext = m_items[1].text;
- float const aspect = machine().render().ui_aspect(&container());
- float line_height = ui().get_line_height();
- float lr_arrow_width = 0.4f * line_height * aspect;
- float gutter_width = lr_arrow_width;
- float const lr_border = ui().box_lr_border() * aspect;
- float target_width, target_height, prior_width;
- float target_x, target_y;
-
- // compute the multi-line target width/height
- ui().draw_text_full(
- container(),
- text,
- 0, 0, 1.0f - 2.0f * lr_border - 2.0f * gutter_width,
- text_layout::text_justify::LEFT, text_layout::word_wrapping::WORD,
- mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
- &target_width, &target_height);
- target_height += 2.0f * line_height;
- if (target_height > 1.0f - 2.0f * ui().box_tb_border())
- target_height = floorf((1.0f - 2.0f * ui().box_tb_border()) / line_height) * line_height;
-
- // maximum against "return to prior menu" text
- prior_width = ui().get_string_width(backtext) + 2.0f * gutter_width;
- target_width = std::max(target_width, prior_width);
-
- // determine the target location
- target_x = 0.5f - 0.5f * target_width;
- target_y = 0.5f - 0.5f * target_height;
-
- // make sure we stay on-screen
- if (target_x < lr_border + gutter_width)
- target_x = lr_border + gutter_width;
- if (target_x + target_width + gutter_width + lr_border > 1.0f)
- target_x = 1.0f - lr_border - gutter_width - target_width;
- if (target_y < ui().box_tb_border())
- target_y = ui().box_tb_border();
- if (target_y + target_height + ui().box_tb_border() > 1.0f)
- target_y = 1.0f - ui().box_tb_border() - target_height;
-
- // add a box around that
- ui().draw_outlined_box(
- container(),
- target_x - lr_border - gutter_width, target_y - ui().box_tb_border(),
- target_x + target_width + gutter_width + lr_border, target_y + target_height + ui().box_tb_border(),
- (m_items[0].flags & FLAG_REDTEXT) ? UI_RED_COLOR : ui().colors().background_color());
- ui().draw_text_full(
- container(),
- text,
- target_x, target_y, target_width,
- text_layout::text_justify::LEFT, text_layout::word_wrapping::WORD,
- mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(),
- nullptr, nullptr);
-
- // draw the "return to prior menu" text with a hilight behind it
- highlight(
- target_x + 0.5f * UI_LINE_WIDTH,
- target_y + target_height - line_height,
- target_x + target_width - 0.5f * UI_LINE_WIDTH,
- target_y + target_height,
- ui().colors().selected_bg_color());
- ui().draw_text_full(
- container(),
- backtext,
- target_x, target_y + target_height - line_height, target_width,
- text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
- mame_ui_manager::NORMAL, ui().colors().selected_color(), ui().colors().selected_bg_color(),
- nullptr, nullptr);
-
- // artificially set the hover to the last item so a double-click exits
- m_hover = m_items.size() - 1;
-}
-
//-------------------------------------------------
// map_mouse - map mouse pointer location to menu
@@ -978,16 +905,11 @@ void menu::handle_events(uint32_t flags, event &ev)
// caught scroll event
case ui_event::type::MOUSE_WHEEL:
- if (!(flags & PROCESS_ONLYCHAR))
+ if (!custom_mouse_scroll((0 < local_menu_event.zdelta) ? -local_menu_event.num_lines : local_menu_event.num_lines) && !(flags & (PROCESS_ONLYCHAR | PROCESS_CUSTOM_NAV)))
{
if (local_menu_event.zdelta > 0)
{
- if (flags & PROCESS_CUSTOM_NAV) // FIXME: DAT menu logic - let the derived class handle this
- {
- top_line -= local_menu_event.num_lines;
- return;
- }
- else if (is_first_selected())
+ if (is_first_selected())
{
select_last_item();
}
@@ -1002,12 +924,7 @@ void menu::handle_events(uint32_t flags, event &ev)
}
else
{
- if (flags & PROCESS_CUSTOM_NAV) // FIXME: DAT menu logic - let the derived class handle this
- {
- top_line += local_menu_event.num_lines;
- return;
- }
- else if (is_last_selected())
+ if (is_last_selected())
{
select_first_item();
}
@@ -1045,8 +962,7 @@ void menu::handle_events(uint32_t flags, event &ev)
void menu::handle_keys(uint32_t flags, int &iptkey)
{
- bool ignorepause = stack_has_special_main_menu();
- int code;
+ bool const ignorepause = (flags & PROCESS_IGNOREPAUSE) || stack_has_special_main_menu();
// bail if no items
if (m_items.empty())
@@ -1063,6 +979,16 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
return;
}
+ // UI configure hides the menus
+ if (!(flags & PROCESS_NOKEYS) && exclusive_input_pressed(iptkey, IPT_UI_CONFIGURE, 0) && !m_global_state.stack_has_special_main_menu())
+ {
+ if (m_one_shot)
+ stack_pop();
+ else
+ m_global_state.hide_menu();
+ return;
+ }
+
// bail out
if (flags & PROCESS_ONLYCHAR)
return;
@@ -1082,11 +1008,15 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
bool const ignoreleft = !(flags & PROCESS_LR_ALWAYS) && !(selected_item().flags & FLAG_LEFT_ARROW);
bool const ignoreright = !(flags & PROCESS_LR_ALWAYS) && !(selected_item().flags & FLAG_RIGHT_ARROW);
- // accept left/right keys as-is with repeat
+ // accept left/right/prev/next keys as-is with repeat if appropriate
if (!ignoreleft && exclusive_input_pressed(iptkey, IPT_UI_LEFT, (flags & PROCESS_LR_REPEAT) ? 6 : 0))
return;
if (!ignoreright && exclusive_input_pressed(iptkey, IPT_UI_RIGHT, (flags & PROCESS_LR_REPEAT) ? 6 : 0))
return;
+ if (exclusive_input_pressed(iptkey, IPT_UI_PREV_GROUP, 0))
+ return;
+ if (exclusive_input_pressed(iptkey, IPT_UI_NEXT_GROUP, 0))
+ return;
// up backs up by one item
if (exclusive_input_pressed(iptkey, IPT_UI_UP, 6))
@@ -1187,10 +1117,23 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
// see if any other UI keys are pressed
if (iptkey == IPT_INVALID)
{
- for (code = IPT_UI_FIRST + 1; code < IPT_UI_LAST; code++)
+ for (int code = IPT_UI_FIRST + 1; code < IPT_UI_LAST; code++)
{
- if (code == IPT_UI_CONFIGURE || (code == IPT_UI_LEFT && ignoreleft) || (code == IPT_UI_RIGHT && ignoreright) || (code == IPT_UI_PAUSE && ignorepause))
- continue;
+ switch (code)
+ {
+ case IPT_UI_LEFT:
+ if (ignoreleft)
+ continue;
+ break;
+ case IPT_UI_RIGHT:
+ if (ignoreright)
+ continue;
+ break;
+ case IPT_UI_PAUSE:
+ if (ignorepause)
+ continue;
+ break;
+ }
if (exclusive_input_pressed(iptkey, code, 0))
break;
}
@@ -1258,7 +1201,7 @@ void menu::do_handle()
// let implementation add other items
populate(m_customtop, m_custombottom);
}
- handle();
+ handle(process());
}
@@ -1271,26 +1214,10 @@ void menu::do_handle()
// and calls the menu handler
//-------------------------------------------------
-uint32_t menu::ui_handler(render_container &container, mame_ui_manager &mui)
+delegate<uint32_t (render_container &)> menu::get_ui_handler(mame_ui_manager &mui)
{
- global_state_ptr const state(get_global_state(mui.machine()));
-
- // if we have no menus stacked up, start with the main menu
- if (!state->topmost_menu<menu>())
- state->stack_push(std::unique_ptr<menu>(make_unique_clear<menu_main>(mui, container)));
-
- // update the menu state
- if (state->topmost_menu<menu>())
- state->topmost_menu<menu>()->do_handle();
-
- // clear up anything pending to be released
- state->clear_free_list();
-
- // if the menus are to be hidden, return a cancel here
- if (mui.is_menu_active() && ((mui.machine().ui_input().pressed(IPT_UI_CONFIGURE) && !state->stack_has_special_main_menu()) || !state->topmost_menu<menu>()))
- return UI_HANDLER_CANCEL;
-
- return 0;
+ global_state &state(get_global_state(mui));
+ return delegate<uint32_t (render_container &)>(&global_state::ui_handler, &state);
}
/***************************************************************************
@@ -1303,7 +1230,7 @@ uint32_t menu::ui_handler(render_container &container, mame_ui_manager &mui)
void menu::highlight(float x0, float y0, float x1, float y1, rgb_t bgcolor)
{
- container().add_quad(x0, y0, x1, y1, bgcolor, m_global_state->hilight_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1) | PRIMFLAG_PACKABLE);
+ container().add_quad(x0, y0, x1, y1, bgcolor, m_global_state.hilight_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1) | PRIMFLAG_PACKABLE);
}
@@ -1313,7 +1240,7 @@ void menu::highlight(float x0, float y0, float x1, float y1, rgb_t bgcolor)
void menu::draw_arrow(float x0, float y0, float x1, float y1, rgb_t fgcolor, uint32_t orientation)
{
- container().add_quad(x0, y0, x1, y1, fgcolor, m_global_state->arrow_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(orientation) | PRIMFLAG_PACKABLE);
+ container().add_quad(x0, y0, x1, y1, fgcolor, m_global_state.arrow_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(orientation) | PRIMFLAG_PACKABLE);
}
@@ -1347,8 +1274,8 @@ void menu::extra_text_draw_box(float origx1, float origx2, float origy, float ys
void menu::draw_background()
{
// draw background image if available
- if (ui().options().use_background_image() && m_global_state->bgrnd_bitmap() && m_global_state->bgrnd_bitmap()->valid())
- container().add_quad(0.0f, 0.0f, 1.0f, 1.0f, rgb_t::white(), m_global_state->bgrnd_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+ if (ui().options().use_background_image() && m_global_state.bgrnd_bitmap() && m_global_state.bgrnd_bitmap()->valid())
+ container().add_quad(0.0f, 0.0f, 1.0f, 1.0f, rgb_t::white(), m_global_state.bgrnd_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h
index 958c1e86af8..b2111168dc4 100644
--- a/src/frontend/mame/ui/menu.h
+++ b/src/frontend/mame/ui/menu.h
@@ -42,11 +42,9 @@ public:
FLAG_LEFT_ARROW = 1U << 0,
FLAG_RIGHT_ARROW = 1U << 1,
FLAG_INVERT = 1U << 2,
- FLAG_MULTILINE = 1U << 3,
- FLAG_REDTEXT = 1U << 4,
- FLAG_DISABLE = 1U << 5,
- FLAG_UI_HEADING = 1U << 7,
- FLAG_COLOR_BOX = 1U << 8
+ FLAG_DISABLE = 1U << 4,
+ FLAG_UI_HEADING = 1U << 5,
+ FLAG_COLOR_BOX = 1U << 6
};
virtual ~menu();
@@ -60,11 +58,8 @@ public:
void item_append(menu_item_type type, uint32_t flags = 0);
void item_append_on_off(const std::string &text, bool state, uint32_t flags, void *ref, menu_item_type type = menu_item_type::UNKNOWN);
- // Global initialization
- static void init(running_machine &machine, ui_options &mopt);
-
// reset the menus, clearing everything
- static void stack_reset(running_machine &machine) { get_global_state(machine)->stack_reset(); }
+ static void stack_reset(mame_ui_manager &ui) { get_global_state(ui).stack_reset(); }
// push a new menu onto the stack
template <typename T, typename... Params>
@@ -81,28 +76,24 @@ public:
}
// pop a menu from the stack
- static void stack_pop(running_machine &machine) { get_global_state(machine)->stack_pop(); }
+ static void stack_pop(mame_ui_manager &ui) { get_global_state(ui).stack_pop(); }
// test if one of the menus in the stack requires hide disable
- static bool stack_has_special_main_menu(running_machine &machine) { return get_global_state(machine)->stack_has_special_main_menu(); }
+ static bool stack_has_special_main_menu(mame_ui_manager &ui) { return get_global_state(ui).stack_has_special_main_menu(); }
// master handler
- static uint32_t ui_handler(render_container &container, mame_ui_manager &mui);
+ static delegate<uint32_t (render_container &)> get_ui_handler(mame_ui_manager &mui);
// Used by sliders
void validate_selection(int scandir);
void do_handle();
-private:
- virtual void draw(uint32_t flags);
- void draw_text_box();
-
protected:
using bitmap_ptr = widgets_manager::bitmap_ptr;
using texture_ptr = widgets_manager::texture_ptr;
- // flags to pass to process
+ // flags to pass to set_process_flags
enum
{
PROCESS_NOKEYS = 1 << 0,
@@ -112,7 +103,7 @@ protected:
PROCESS_CUSTOM_ONLY = 1 << 4,
PROCESS_ONLYCHAR = 1 << 5,
PROCESS_NOINPUT = 1 << 6,
- PROCESS_NOIMAGE = 1 << 7
+ PROCESS_IGNOREPAUSE = 1 << 7
};
// options for reset
@@ -139,19 +130,16 @@ protected:
running_machine &machine() const { return m_ui.machine(); }
render_container &container() const { return m_container; }
+ void set_one_shot(bool oneshot) { m_one_shot = oneshot; }
void set_needs_prev_menu_item(bool needs) { m_needs_prev_menu_item = needs; }
void reset(reset_options options);
void reset_parent(reset_options options) { m_parent->reset(options); }
- template <typename T> T *topmost_menu() const { return m_global_state->topmost_menu<T>(); }
- template <typename T> static T *topmost_menu(running_machine &machine) { return get_global_state(machine)->topmost_menu<T>(); }
- void stack_pop() { m_global_state->stack_pop(); }
- void stack_reset() { m_global_state->stack_reset(); }
- bool stack_has_special_main_menu() const { return m_global_state->stack_has_special_main_menu(); }
-
- // process a menu, drawing it and returning any interesting events
- const event *process(uint32_t flags, float x0 = 0.0f, float y0 = 0.0f);
- void process_parent() { m_parent->process(PROCESS_NOINPUT); }
+ template <typename T> T *topmost_menu() const { return m_global_state.topmost_menu<T>(); }
+ template <typename T> static T *topmost_menu(mame_ui_manager &ui) { return get_global_state(ui).topmost_menu<T>(); }
+ void stack_pop() { m_global_state.stack_pop(); }
+ void stack_reset() { m_global_state.stack_reset(); }
+ bool stack_has_special_main_menu() const { return m_global_state.stack_has_special_main_menu(); }
menu_item &item(int index) { return m_items[index]; }
menu_item const &item(int index) const { return m_items[index]; }
@@ -179,6 +167,7 @@ protected:
void clear_hover() { m_hover = m_items.size() + 1; }
// scroll position control
+ void set_top_line(int index) { top_line = (0 < index) ? (index - 1) : index; }
void centre_selection() { top_line = m_selected - (m_visible_lines / 2); }
// test if the given key is pressed and we haven't already reported a key
@@ -190,7 +179,7 @@ protected:
// highlight
void highlight(float x0, float y0, float x1, float y1, rgb_t bgcolor);
- render_texture *hilight_main_texture() { return m_global_state->hilight_main_texture(); }
+ render_texture *hilight_main_texture() { return m_global_state.hilight_main_texture(); }
// draw arrow
void draw_arrow(float x0, float y0, float x1, float y1, rgb_t fgcolor, uint32_t orientation);
@@ -274,14 +263,21 @@ protected:
}
// overridable event handling
+ void set_process_flags(uint32_t flags) { m_process_flags = flags; }
virtual void handle_events(uint32_t flags, event &ev);
virtual void handle_keys(uint32_t flags, int &iptkey);
virtual bool custom_ui_cancel() { return false; }
virtual bool custom_mouse_down() { return false; }
+ virtual bool custom_mouse_scroll(int lines) { return false; }
+
+ // event notifications
+ virtual void menu_activated() { }
+ virtual void menu_deactivated() { }
+ virtual void menu_dismissed() { }
static bool is_selectable(menu_item const &item)
{
- return ((item.flags & (menu::FLAG_MULTILINE | menu::FLAG_DISABLE)) == 0 && item.type != menu_item_type::SEPARATOR);
+ return (!(item.flags & menu::FLAG_DISABLE) && (item.type != menu_item_type::SEPARATOR));
}
// get arrows status
@@ -295,7 +291,7 @@ private:
class global_state : public widgets_manager
{
public:
- global_state(running_machine &machine, ui_options const &options);
+ global_state(mame_ui_manager &ui);
global_state(global_state const &) = delete;
global_state(global_state &&) = delete;
~global_state();
@@ -312,70 +308,88 @@ private:
void clear_free_list();
bool stack_has_special_main_menu() const;
- private:
- running_machine &m_machine;
+ void hide_menu() { m_hide = true; }
+
+ uint32_t ui_handler(render_container &container);
+ protected:
+ mame_ui_manager &m_ui;
+
+ private:
bitmap_ptr m_bgrnd_bitmap;
texture_ptr m_bgrnd_texture;
std::unique_ptr<menu> m_stack;
std::unique_ptr<menu> m_free;
+
+ bool m_hide;
};
- using global_state_ptr = std::shared_ptr<global_state>;
- using global_state_map = std::map<running_machine *, global_state_ptr>;
+
+ // this is to satisfy the std::any requirement that objects be copyable
+ class global_state_wrapper : public global_state
+ {
+ public:
+ global_state_wrapper(mame_ui_manager &ui) : global_state(ui) { }
+ global_state_wrapper(global_state_wrapper const &that) : global_state(that.m_ui) { }
+ };
+
+ // process a menu, drawing it and returning any interesting events
+ const event *process();
+ virtual void draw(uint32_t flags);
// request the specific handling of the game selection main menu
bool is_special_main_menu() const;
void set_special_main_menu(bool disable);
- // To be reimplemented in the menu subclass
+ // to be implemented in derived classes
virtual void populate(float &customtop, float &custombottom) = 0;
- // To be reimplemented in the menu subclass
- virtual void handle() = 0;
+ // to be implemented in derived classes
+ virtual void handle(event const *ev) = 0;
// push a new menu onto the stack
- static void stack_push(std::unique_ptr<menu> &&menu) { get_global_state(menu->machine())->stack_push(std::move(menu)); }
+ static void stack_push(std::unique_ptr<menu> &&menu) { menu->m_global_state.stack_push(std::move(menu)); }
void extra_text_draw_box(float origx1, float origx2, float origy, float yspan, std::string_view text, int direction);
bool first_item_visible() const { return top_line <= 0; }
bool last_item_visible() const { return (top_line + m_visible_lines) >= m_items.size(); }
- static void exit(running_machine &machine);
- static global_state_ptr get_global_state(running_machine &machine);
-
- int m_selected; // which item is selected
- int m_hover; // which item is being hovered over
- std::vector<menu_item> m_items; // array of items
+ static global_state &get_global_state(mame_ui_manager &ui);
-protected: // TODO: remove need to expose these
+protected: // TODO: remove need to expose these - only used here and in selmenu.cpp
int top_line; // main box top line
int m_visible_lines; // main box visible lines
int m_visible_items; // number of visible items
private:
- global_state_ptr const m_global_state;
- bool m_special_main_menu;
- bool m_needs_prev_menu_item;
- mame_ui_manager &m_ui; // UI we are attached to
- render_container &m_container; // render_container we render to
- std::unique_ptr<menu> m_parent; // pointer to parent menu
- event m_event; // the UI event that occurred
+ global_state &m_global_state; // reference to global state for session
+ mame_ui_manager &m_ui; // UI we are attached to
+ render_container &m_container; // render_container we render to
+ std::unique_ptr<menu> m_parent; // pointer to parent menu in the stack
+
+ std::vector<menu_item> m_items; // array of items
- float m_customtop; // amount of extra height to add at the top
- float m_custombottom; // amount of extra height to add at the bottom
+ uint32_t m_process_flags; // event processing options
+ int m_selected; // which item is selected
+ int m_hover; // which item is being hovered over
+ bool m_special_main_menu; // true if no real emulation running under the menu
+ bool m_one_shot; // true for menus outside the normal stack
+ bool m_needs_prev_menu_item; // true to automatically create item to dismiss menu
+ bool m_active; // whether the menu is currently visible and topmost
- int m_resetpos; // reset position
- void *m_resetref; // reset reference
+ event m_event; // the UI event that occurred
+
+ float m_customtop; // amount of extra height to add at the top
+ float m_custombottom; // amount of extra height to add at the bottom
+
+ int m_resetpos; // item index to select after repopulating
+ void *m_resetref; // item reference value to select after repopulating
bool m_mouse_hit;
bool m_mouse_button;
float m_mouse_x;
float m_mouse_y;
-
- static std::mutex s_global_state_guard;
- static global_state_map s_global_states;
};
} // namespace ui
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp
index 135963406ad..42c963ee083 100644
--- a/src/frontend/mame/ui/miscmenu.cpp
+++ b/src/frontend/mame/ui/miscmenu.cpp
@@ -86,21 +86,19 @@ menu_bios_selection::~menu_bios_selection()
menu_bios_selection - menu that
-------------------------------------------------*/
-void menu_bios_selection::handle()
+void menu_bios_selection::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ if (ev && ev->itemref)
{
- if ((uintptr_t)menu_event->itemref == 1 && menu_event->iptkey == IPT_UI_SELECT)
+ if ((uintptr_t)ev->itemref == 1 && ev->iptkey == IPT_UI_SELECT)
machine().schedule_hard_reset();
else
{
- device_t *dev = (device_t *)menu_event->itemref;
+ device_t *dev = (device_t *)ev->itemref;
int bios_val = 0;
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
// reset to default
case IPT_UI_SELECT:
@@ -111,7 +109,7 @@ void menu_bios_selection::handle()
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() + ((menu_event->iptkey == IPT_UI_LEFT) ? -1 : +1);
+ bios_val = dev->system_bios() + ((ev->iptkey == IPT_UI_LEFT) ? -1 : +1);
// wrap
if (bios_val < 1)
@@ -181,18 +179,21 @@ void menu_network_devices::populate(float &customtop, float &custombottom)
menu_network_devices - menu that
-------------------------------------------------*/
-void menu_network_devices::handle()
+void menu_network_devices::handle(event const *ev)
{
- /* process the menu */
- const event *menu_event = process(0);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ // process the menu
+ if (ev && ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) {
- device_network_interface *network = (device_network_interface *)menu_event->itemref;
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
+ {
+ device_network_interface *network = (device_network_interface *)ev->itemref;
int curr = network->get_interface();
- if (menu_event->iptkey == IPT_UI_LEFT) curr--; else curr++;
- if (curr==-2) curr = netdev_count() - 1;
+ 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);
}
@@ -205,7 +206,7 @@ void menu_network_devices::handle()
information menu
-------------------------------------------------*/
-menu_bookkeeping::menu_bookkeeping(mame_ui_manager &mui, render_container &container) : menu(mui, container)
+menu_bookkeeping::menu_bookkeeping(mame_ui_manager &mui, render_container &container) : menu_textbox(mui, container)
{
}
@@ -213,71 +214,86 @@ menu_bookkeeping::~menu_bookkeeping()
{
}
-void menu_bookkeeping::handle()
+void menu_bookkeeping::menu_activated()
{
- /* process the menu */
- process(0);
-
- /* if the time has rolled over another second, regenerate */
- attotime const curtime = machine().time();
- if (prevtime.seconds() != curtime.seconds())
- reset(reset_options::REMEMBER_POSITION);
+ // stuff can change while the menu is hidden
+ reset_layout();
}
-void menu_bookkeeping::populate(float &customtop, float &custombottom)
+void menu_bookkeeping::populate_text(std::optional<text_layout> &layout, float &width, int &lines)
{
- int tickets = machine().bookkeeping().get_dispensed_tickets();
- std::ostringstream tempstring;
- int ctrnum;
+ if (!layout || (layout->width() != width))
+ {
+ rgb_t const color = ui().colors().text_color();
+ layout.emplace(ui().create_layout(container(), width));
- /* show total time first */
- prevtime = machine().time();
- if (prevtime.seconds() >= (60 * 60))
- util::stream_format(tempstring, _("Uptime: %1$d:%2$02d:%3$02d\n\n"), prevtime.seconds() / (60 * 60), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60);
- else
- util::stream_format(tempstring, _("Uptime: %1$d:%2$02d\n\n"), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60);
+ // show total time first
+ prevtime = machine().time();
+ if (prevtime.seconds() >= (60 * 60))
+ layout->add_text(util::string_format(_("Uptime: %1$d:%2$02d:%3$02d\n\n"), prevtime.seconds() / (60 * 60), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60), color);
+ else
+ layout->add_text(util::string_format(_("Uptime: %1$d:%2$02d\n\n"), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60), color);
- /* show tickets at the top */
- if (tickets > 0)
- util::stream_format(tempstring, _("Tickets dispensed: %1$d\n\n"), tickets);
+ // show tickets at the top
+ int const tickets = machine().bookkeeping().get_dispensed_tickets();
+ if (tickets > 0)
+ layout->add_text(util::string_format(_("Tickets dispensed: %1$d\n\n"), tickets), color);
- /* loop over coin counters */
- for (ctrnum = 0; ctrnum < bookkeeping_manager::COIN_COUNTERS; ctrnum++)
- {
- int count = machine().bookkeeping().coin_counter_get_count(ctrnum);
-
- /* display the coin counter number */
- /* display how many coins */
- /* display whether or not we are locked out */
- util::stream_format(tempstring,
- (count == 0) ? _("Coin %1$c: NA%3$s\n") : _("Coin %1$c: %2$d%3$s\n"),
- ctrnum + 'A',
- count,
- machine().bookkeeping().coin_lockout_get_state(ctrnum) ? _(" (locked)") : "");
+ // loop over coin counters
+ for (int ctrnum = 0; ctrnum < bookkeeping_manager::COIN_COUNTERS; ctrnum++)
+ {
+ int const count = machine().bookkeeping().coin_counter_get_count(ctrnum);
+ bool const locked = machine().bookkeeping().coin_lockout_get_state(ctrnum);
+
+ // display the coin counter number
+ // display how many coins
+ // display whether or not we are locked out
+ layout->add_text(
+ util::string_format(
+ (count == 0) ? _("Coin %1$c: NA%3$s\n") : _("Coin %1$c: %2$d%3$s\n"),
+ ctrnum + 'A',
+ count,
+ locked ? _(" (locked)") : ""),
+ color);
+ }
+
+ lines = layout->lines();
}
+ width = layout->actual_width();
+}
- /* append the single item */
- item_append(tempstring.str(), FLAG_MULTILINE, nullptr);
+void menu_bookkeeping::populate(float &customtop, float &custombottom)
+{
}
+void 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);
+}
+
+
/*-------------------------------------------------
menu_crosshair - handle the crosshair settings
menu
-------------------------------------------------*/
-void menu_crosshair::handle()
+void menu_crosshair::handle(event const *ev)
{
- // process the menu
- event const *const menu_event(process(PROCESS_LR_REPEAT));
-
// handle events
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
- crosshair_item_data &data(*reinterpret_cast<crosshair_item_data *>(menu_event->itemref));
+ crosshair_item_data &data(*reinterpret_cast<crosshair_item_data *>(ev->itemref));
bool changed(false);
int newval(data.cur);
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
// if selected, reset to default value
case IPT_UI_SELECT:
@@ -325,7 +341,7 @@ void menu_crosshair::handle()
// crosshair graphic name
if (data.type == CROSSHAIR_ITEM_PIC)
{
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_SELECT:
{
@@ -371,6 +387,7 @@ void menu_crosshair::handle()
menu_crosshair::menu_crosshair(mame_ui_manager &mui, render_container &container) : menu(mui, container)
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
void menu_crosshair::populate(float &customtop, float &custombottom)
@@ -559,12 +576,12 @@ void menu_quit_game::populate(float &customtop, float &custombottom)
{
}
-void menu_quit_game::handle()
+void menu_quit_game::handle(event const *ev)
{
- /* request a reset */
+ // request a reset
machine().schedule_exit();
- /* reset the menu stack */
+ // reset the menu stack
stack_reset();
}
@@ -582,21 +599,19 @@ menu_export::~menu_export()
}
//-------------------------------------------------
-// handlethe options menu
+// handle the export menu
//-------------------------------------------------
-void menu_export::handle()
+void menu_export::handle(event const *ev)
{
// process the menu
- process_parent();
- const event *const menu_event = process(PROCESS_NOIMAGE);
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
- switch (uintptr_t(menu_event->itemref))
+ switch (uintptr_t(ev->itemref))
{
case 1:
case 3:
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
std::string filename("exported");
emu_file infile(ui().options().ui_path(), OPEN_FLAG_READ);
@@ -631,7 +646,7 @@ void menu_export::handle()
};
// do we want to show devices?
- bool include_devices = uintptr_t(menu_event->itemref) == 1;
+ bool include_devices = uintptr_t(ev->itemref) == 1;
// and do the dirty work
info_xml_creator creator(machine().options());
@@ -641,7 +656,7 @@ void menu_export::handle()
}
break;
case 2:
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
std::string filename("exported");
emu_file infile(ui().options().ui_path(), OPEN_FLAG_READ);
@@ -704,13 +719,10 @@ menu_machine_configure::menu_machine_configure(
mame_ui_manager &mui,
render_container &container,
ui_system_info const &info,
- std::function<void (bool, bool)> &&handler,
- float x0, float y0)
+ std::function<void (bool, bool)> &&handler)
: menu(mui, container)
, m_handler(std::move(handler))
, m_sys(info)
- , m_x0(x0)
- , m_y0(y0)
, m_curbios(0)
, m_was_favorite(mame_machine_manager::instance()->favorite().is_favorite_system(*info.driver))
, m_want_favorite(m_was_favorite)
@@ -737,19 +749,18 @@ menu_machine_configure::~menu_machine_configure()
}
//-------------------------------------------------
-// handlethe options menu
+// handle the machine options menu
//-------------------------------------------------
-void menu_machine_configure::handle()
+void menu_machine_configure::handle(event const *ev)
{
// process the menu
- process_parent();
- const event *menu_event = process(PROCESS_NOIMAGE, m_x0, m_y0);
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ //process_parent(); FIXME: drawn in the wrong order, can't see menu
+ if (ev && ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
- switch ((uintptr_t)menu_event->itemref)
+ switch ((uintptr_t)ev->itemref)
{
case SAVE:
{
@@ -773,24 +784,24 @@ void menu_machine_configure::handle()
reset(reset_options::REMEMBER_POSITION);
break;
case CONTROLLER:
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
menu::stack_push<submenu>(ui(), container(), submenu::control_options(), m_sys.driver, &m_opts);
break;
case VIDEO:
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
menu::stack_push<submenu>(ui(), container(), submenu::video_options(), m_sys.driver, &m_opts);
break;
case ADVANCED:
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
menu::stack_push<submenu>(ui(), container(), submenu::advanced_options(), m_sys.driver, &m_opts);
break;
default:
break;
}
}
- else if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
- (menu_event->iptkey == IPT_UI_LEFT) ? --m_curbios : ++m_curbios;
+ (ev->iptkey == IPT_UI_LEFT) ? --m_curbios : ++m_curbios;
m_opts.set_value(OPTION_BIOS, m_bios[m_curbios].second, OPTION_PRIORITY_CMDLINE);
reset(reset_options::REMEMBER_POSITION);
}
@@ -903,21 +914,19 @@ menu_plugins_configure::~menu_plugins_configure()
}
//-------------------------------------------------
-// handlethe options menu
+// handle the plugins menu
//-------------------------------------------------
-void menu_plugins_configure::handle()
+void menu_plugins_configure::handle(event const *ev)
{
// process the menu
bool changed = false;
- plugin_options& plugins = mame_machine_manager::instance()->plugins();
- process_parent();
- const event *menu_event = process(PROCESS_NOIMAGE);
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ plugin_options &plugins = mame_machine_manager::instance()->plugins();
+ if (ev && ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT || menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT)
{
- plugin_options::plugin *p = plugins.find((const char*)menu_event->itemref);
+ plugin_options::plugin *p = plugins.find((const char*)ev->itemref);
if (p)
{
p->m_start = !p->m_start;
diff --git a/src/frontend/mame/ui/miscmenu.h b/src/frontend/mame/ui/miscmenu.h
index 78ed68cc35a..1b19b4c5d45 100644
--- a/src/frontend/mame/ui/miscmenu.h
+++ b/src/frontend/mame/ui/miscmenu.h
@@ -12,7 +12,7 @@
#pragma once
-#include "ui/menu.h"
+#include "ui/textbox.h"
#include "crsshair.h"
#include "emuopts.h"
@@ -34,18 +34,22 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
-class menu_bookkeeping : public menu
+class menu_bookkeeping : public menu_textbox
{
public:
menu_bookkeeping(mame_ui_manager &mui, render_container &container);
virtual ~menu_bookkeeping();
+protected:
+ virtual void menu_activated() override;
+ virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
+
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
attotime prevtime;
};
@@ -77,7 +81,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::vector<crosshair_item_data> m_data;
std::vector<std::string> m_pics;
@@ -91,7 +95,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
class menu_bios_selection : public menu
@@ -102,7 +106,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
@@ -118,7 +122,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::vector<const game_driver*> m_list;
};
@@ -134,8 +138,7 @@ public:
mame_ui_manager &mui,
render_container &container,
ui_system_info const &info,
- std::function<void (bool, bool)> &&handler = nullptr,
- float x0 = 0.0f, float y0 = 0.0f);
+ std::function<void (bool, bool)> &&handler = nullptr);
virtual ~menu_machine_configure();
protected:
@@ -157,15 +160,13 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
void setup_bios();
std::function<void (bool, bool)> const m_handler;
ui_system_info const &m_sys;
emu_options m_opts;
- float const m_x0;
- float const m_y0;
s_bios m_bios;
std::size_t m_curbios;
bool const m_was_favorite;
@@ -184,7 +185,7 @@ public:
protected:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
};
diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp
index 998c8d17c23..d21f069f6f7 100644
--- a/src/frontend/mame/ui/optsmenu.cpp
+++ b/src/frontend/mame/ui/optsmenu.cpp
@@ -38,6 +38,7 @@ menu_simple_game_options::menu_simple_game_options(
: menu(mui, container)
, m_handler(std::move(handler))
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
//-------------------------------------------------
@@ -55,12 +56,11 @@ menu_simple_game_options::~menu_simple_game_options()
// handle
//-------------------------------------------------
-void menu_simple_game_options::handle()
+void menu_simple_game_options::handle(event const *ev)
{
// process the menu
- event const *const menu_event(process(PROCESS_LR_REPEAT));
- if (menu_event && menu_event->itemref)
- handle_item_event(*menu_event);
+ if (ev && ev->itemref)
+ handle_item_event(*ev);
}
//-------------------------------------------------
@@ -167,6 +167,7 @@ menu_game_options::menu_game_options(
, m_filter_data(filter_data)
, m_main_filter(filter_data.get_current_filter_type())
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
//-------------------------------------------------
@@ -182,13 +183,11 @@ menu_game_options::~menu_game_options()
// handle
//-------------------------------------------------
-void menu_game_options::handle()
+void menu_game_options::handle(event const *ev)
{
// process the menu
- process_parent();
- event const *const menu_event(process(PROCESS_LR_REPEAT | PROCESS_NOIMAGE));
- if (menu_event && menu_event->itemref)
- handle_item_event(*menu_event);
+ if (ev && ev->itemref)
+ handle_item_event(*ev);
}
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/optsmenu.h b/src/frontend/mame/ui/optsmenu.h
index 1809f1bd204..297ec7aa64f 100644
--- a/src/frontend/mame/ui/optsmenu.h
+++ b/src/frontend/mame/ui/optsmenu.h
@@ -29,7 +29,7 @@ public:
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
virtual void populate(float &customtop, float &custombottom) override;
void handle_item_event(event const &menu_event);
@@ -62,7 +62,7 @@ public:
virtual ~menu_game_options() override;
protected:
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
virtual void populate(float &customtop, float &custombottom) override;
void handle_item_event(event const &menu_event);
diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp
index 4bc726c9aea..f21511f1645 100644
--- a/src/frontend/mame/ui/pluginopt.cpp
+++ b/src/frontend/mame/ui/pluginopt.cpp
@@ -19,14 +19,12 @@
namespace ui {
-void menu_plugin::handle()
+void menu_plugin::handle(event const *ev)
{
- const event *menu_event = process(0);
-
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_SELECT)
- menu::stack_push<menu_plugin_opt>(ui(), container(), (char *)menu_event->itemref);
+ if (ev->iptkey == IPT_UI_SELECT)
+ menu::stack_push<menu_plugin_opt>(ui(), container(), (char *)ev->itemref);
}
}
@@ -46,7 +44,7 @@ void menu_plugin::populate(float &customtop, float &custombottom)
void menu_plugin::show_menu(mame_ui_manager &mui, render_container &container, char *menu)
{
// reset the menu stack
- menu::stack_reset(mui.machine());
+ menu::stack_reset(mui);
// add the plugin menu entry
menu::stack_push<menu_plugin_opt>(mui, container, menu);
@@ -65,19 +63,17 @@ menu_plugin::~menu_plugin()
menu_plugin_opt::menu_plugin_opt(mame_ui_manager &mui, render_container &container, std::string_view menu) :
ui::menu(mui, container),
m_menu(menu),
- m_process_flags(0U),
m_need_idle(false)
{
}
-void menu_plugin_opt::handle()
+void menu_plugin_opt::handle(event const *ev)
{
- event const *const menu_event = process(m_process_flags);
- void *const itemref = menu_event ? menu_event->itemref : get_selection_ref();
+ void *const itemref = ev ? ev->itemref : get_selection_ref();
std::string key;
- if (menu_event)
+ if (ev)
{
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_UP:
key = "up";
@@ -91,6 +87,12 @@ void menu_plugin_opt::handle()
case IPT_UI_RIGHT:
key = "right";
break;
+ case IPT_UI_PREV_GROUP:
+ key = "prevgroup";
+ break;
+ case IPT_UI_NEXT_GROUP:
+ key = "nextgroup";
+ break;
case IPT_UI_SELECT:
key = "select";
break;
@@ -104,7 +106,7 @@ void menu_plugin_opt::handle()
key = "cancel";
break;
case IPT_SPECIAL:
- key = std::to_string((u32)menu_event->unichar);
+ key = std::to_string((u32)ev->unichar);
break;
default:
break;
@@ -117,7 +119,7 @@ void menu_plugin_opt::handle()
set_selection(reinterpret_cast<void *>(uintptr_t(*result.second)));
if (result.first)
reset(reset_options::REMEMBER_REF);
- else if (menu_event && (menu_event->iptkey == IPT_UI_CANCEL))
+ else if (ev && (ev->iptkey == IPT_UI_CANCEL))
stack_pop();
}
}
@@ -173,7 +175,7 @@ void menu_plugin_opt::populate(float &customtop, float &custombottom)
if (sel)
set_selection(reinterpret_cast<void *>(uintptr_t(*sel)));
- m_process_flags = 0U;
+ uint32_t process_flags = 0U;
m_need_idle = false;
if (!flags.empty())
{
@@ -188,15 +190,20 @@ void menu_plugin_opt::populate(float &customtop, float &custombottom)
flag_start = mflags.find_first_not_of(' ');
if (flag == "lralways")
- m_process_flags |= PROCESS_LR_ALWAYS;
+ process_flags |= PROCESS_LR_ALWAYS;
else if (flag == "lrrepeat")
- m_process_flags |= PROCESS_LR_REPEAT;
+ process_flags |= PROCESS_LR_REPEAT;
else if (flag == "customnav")
- m_process_flags |= PROCESS_CUSTOM_NAV;
+ process_flags |= PROCESS_CUSTOM_NAV;
else if (flag == "idle")
m_need_idle = true;
+ else if (flag == "nokeys")
+ process_flags |= PROCESS_NOKEYS;
}
+ if (process_flags & PROCESS_NOKEYS)
+ m_need_idle = true;
}
+ set_process_flags(process_flags);
}
menu_plugin_opt::~menu_plugin_opt()
diff --git a/src/frontend/mame/ui/pluginopt.h b/src/frontend/mame/ui/pluginopt.h
index c639c3caa15..15196c1ca2d 100644
--- a/src/frontend/mame/ui/pluginopt.h
+++ b/src/frontend/mame/ui/pluginopt.h
@@ -33,7 +33,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::vector<std::string> &m_plugins;
};
@@ -49,10 +49,9 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::string const m_menu;
- uint32_t m_process_flags;
bool m_need_idle;
};
diff --git a/src/frontend/mame/ui/selector.cpp b/src/frontend/mame/ui/selector.cpp
index bbc1bf357c5..6a583346400 100644
--- a/src/frontend/mame/ui/selector.cpp
+++ b/src/frontend/mame/ui/selector.cpp
@@ -47,32 +47,30 @@ menu_selector::~menu_selector()
// handle
//-------------------------------------------------
-void menu_selector::handle()
+void menu_selector::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ if (ev && ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
int selection(-1);
for (size_t idx = 0; (m_str_items.size() > idx) && (0 > selection); ++idx)
- if ((void*)&m_str_items[idx] == menu_event->itemref)
+ if ((void*)&m_str_items[idx] == ev->itemref)
selection = int(unsigned(idx));
m_handler(selection);
stack_pop();
}
- else if (menu_event->iptkey == IPT_SPECIAL)
+ else if (ev->iptkey == IPT_SPECIAL)
{
- if (input_character(m_search, menu_event->unichar, uchar_is_printable))
+ if (input_character(m_search, ev->unichar, uchar_is_printable))
reset(reset_options::SELECT_FIRST);
}
// escape pressed with non-empty text clears the text
- else if (menu_event->iptkey == IPT_UI_CANCEL && !m_search.empty())
+ else if (ev->iptkey == IPT_UI_CANCEL && !m_search.empty())
{
m_search.clear();
reset(reset_options::SELECT_FIRST);
diff --git a/src/frontend/mame/ui/selector.h b/src/frontend/mame/ui/selector.h
index 1f53a244bfb..d8b0abc0472 100644
--- a/src/frontend/mame/ui/selector.h
+++ b/src/frontend/mame/ui/selector.h
@@ -41,7 +41,7 @@ private:
enum { VISIBLE_GAMES_IN_SEARCH = 200 };
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void 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 f748f872f72..0572b1dcf86 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -147,14 +147,11 @@ menu_select_game::~menu_select_game()
}
//-------------------------------------------------
-// handle
+// menu_activated
//-------------------------------------------------
-void menu_select_game::handle()
+void menu_select_game::menu_activated()
{
- if (!m_prev_selected)
- m_prev_selected = item(0).ref;
-
// if I have to load datfile, perform a hard reset
if (ui_globals::reset)
{
@@ -167,10 +164,21 @@ void menu_select_game::handle()
stack_reset();
return;
}
+}
+
+//-------------------------------------------------
+// handle
+//-------------------------------------------------
+
+void menu_select_game::handle(event const *ev)
+{
+ if (!m_prev_selected)
+ m_prev_selected = item(0).ref;
// if I have to select software, force software list submenu
if (reselect_last::get())
{
+ // FIXME: this is never hit, need a better way to return to software selection if necessary
const ui_system_info *system;
const ui_software_info *software;
get_selection(software, system);
@@ -178,18 +186,16 @@ void menu_select_game::handle()
return;
}
- // ignore pause keys by swallowing them before we process the menu
- machine().ui_input().pressed(IPT_UI_PAUSE);
+ // FIXME: everything above here used to run before events were processed
// process the menu
- const event *menu_event = process(PROCESS_LR_REPEAT);
- if (menu_event)
+ if (ev)
{
if (dismiss_error())
{
- // reset the error on any future menu_event
+ // reset the error on any subsequent menu event
}
- else switch (menu_event->iptkey)
+ else switch (ev->iptkey)
{
case IPT_UI_UP:
if ((get_focus() == focused_menu::LEFT) && (machine_filter::FIRST < m_filter_highlight))
@@ -220,17 +226,17 @@ void menu_select_game::handle()
break;
default:
- if (menu_event->itemref)
+ if (ev->itemref)
{
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_SELECT:
if (get_focus() == focused_menu::MAIN)
{
if (m_populated_favorites)
- inkey_select_favorite(menu_event);
+ inkey_select_favorite(ev);
else
- inkey_select(menu_event);
+ inkey_select(ev);
}
break;
@@ -242,8 +248,7 @@ void menu_select_game::handle()
ui(),
container(),
*reinterpret_cast<ui_system_info const *>(m_prev_selected),
- nullptr,
- menu_event->mouse.x0, menu_event->mouse.y0);
+ nullptr);
}
else
{
@@ -257,8 +262,7 @@ void menu_select_game::handle()
{
if (changed)
reset(empty ? reset_options::SELECT_FIRST : reset_options::REMEMBER_REF);
- },
- menu_event->mouse.x0, menu_event->mouse.y0);
+ });
}
break;
@@ -289,12 +293,12 @@ void menu_select_game::handle()
break;
case IPT_UI_FAVORITES:
- if (uintptr_t(menu_event->itemref) > skip_main_items)
+ if (uintptr_t(ev->itemref) > skip_main_items)
{
favorite_manager &mfav(mame_machine_manager::instance()->favorite());
if (!m_populated_favorites)
{
- auto const &info(*reinterpret_cast<ui_system_info const *>(menu_event->itemref));
+ auto const &info(*reinterpret_cast<ui_system_info const *>(ev->itemref));
auto const &driver(*info.driver);
if (!mfav.is_favorite_system(driver))
{
@@ -309,7 +313,7 @@ void menu_select_game::handle()
}
else
{
- ui_software_info const *const swinfo(reinterpret_cast<ui_software_info const *>(menu_event->itemref));
+ ui_software_info const *const swinfo(reinterpret_cast<ui_software_info const *>(ev->itemref));
machine().popmessage(_("%s\n removed from favorites list."), swinfo->longname);
mfav.remove_favorite_software(*swinfo);
reset(reset_options::SELECT_FIRST);
@@ -573,7 +577,7 @@ void menu_select_game::build_available_list()
void menu_select_game::force_game_select(mame_ui_manager &mui, render_container &container)
{
// reset the menu stack
- menu::stack_reset(mui.machine());
+ menu::stack_reset(mui);
// add the quit entry followed by the game select entry
menu::stack_push_special_main<menu_quit_game>(mui, container);
diff --git a/src/frontend/mame/ui/selgame.h b/src/frontend/mame/ui/selgame.h
index 8b54024ece1..4099e248f54 100644
--- a/src/frontend/mame/ui/selgame.h
+++ b/src/frontend/mame/ui/selgame.h
@@ -32,6 +32,9 @@ public:
// force game select menu
static void force_game_select(mame_ui_manager &mui, render_container &container);
+protected:
+ void menu_activated() override;
+
private:
enum
{
@@ -53,7 +56,7 @@ private:
static bool s_first_start;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// drawing
virtual float draw_left_panel(float x1, float y1, float x2, float y2) override;
diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp
index 2228f7b1b60..d55009623e8 100644
--- a/src/frontend/mame/ui/selmenu.cpp
+++ b/src/frontend/mame/ui/selmenu.cpp
@@ -171,7 +171,7 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
ui_software_info const &m_uiinfo;
s_parts const m_parts;
@@ -191,7 +191,7 @@ private:
bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, void const *driver, bool software, bool inlist);
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
void const *m_driver;
bool m_software, m_inlist;
@@ -294,15 +294,14 @@ void menu_select_launch::software_parts::populate(float &customtop, float &custo
// handle
//-------------------------------------------------
-void menu_select_launch::software_parts::handle()
+void menu_select_launch::software_parts::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
- if (menu_event && (menu_event->iptkey) == IPT_UI_SELECT && menu_event->itemref)
+ if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref)
{
for (auto const &elem : m_parts)
{
- if ((void*)&elem == menu_event->itemref)
+ if ((void*)&elem == ev->itemref)
{
launch_system(ui(), *m_uiinfo.driver, &m_uiinfo, &elem.first, nullptr);
break;
@@ -374,15 +373,14 @@ void menu_select_launch::bios_selection::populate(float &customtop, float &custo
// handle
//-------------------------------------------------
-void menu_select_launch::bios_selection::handle()
+void menu_select_launch::bios_selection::handle(event const *ev)
{
// process the menu
- const event *menu_event = process(0);
- if (menu_event && menu_event->iptkey == IPT_UI_SELECT && menu_event->itemref)
+ if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref)
{
for (auto & elem : m_bios)
{
- if ((void*)&elem.first == menu_event->itemref)
+ if ((void*)&elem.first == ev->itemref)
{
if (!m_software)
{
@@ -541,6 +539,7 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c
, m_flags(256)
{
set_needs_prev_menu_item(false);
+ set_process_flags(PROCESS_LR_REPEAT);
}
@@ -636,7 +635,7 @@ void menu_select_launch::launch_system(mame_ui_manager &mui, game_driver const &
mame_machine_manager::instance()->schedule_new_driver(driver);
mui.machine().schedule_hard_reset();
- stack_reset(mui.machine());
+ stack_reset(mui);
}
@@ -675,11 +674,11 @@ void menu_select_launch::custom_render(void *selectedref, float top, float botto
tempbuf[0] = make_software_description(*swinfo, system);
// next line is year, publisher
- tempbuf[1] = string_format(_("%1$s, %2$-.100s"), swinfo->year, swinfo->publisher);
+ tempbuf[1] = string_format(_("%1$s, %2$s"), swinfo->year, swinfo->publisher);
// next line is parent/clone
if (!swinfo->parentname.empty())
- tempbuf[2] = string_format(_("Software is clone of: %1$-.100s"), !swinfo->parentlongname.empty() ? swinfo->parentlongname : swinfo->parentname);
+ tempbuf[2] = string_format(_("Software is clone of: %1$s"), !swinfo->parentlongname.empty() ? swinfo->parentlongname : swinfo->parentname);
else
tempbuf[2] = _("Software is parent");
@@ -706,7 +705,7 @@ void menu_select_launch::custom_render(void *selectedref, float top, float botto
isstar = mame_machine_manager::instance()->favorite().is_favorite_system(driver);
// first line is year, manufacturer
- tempbuf[0] = string_format(_("%1$s, %2$-.100s"), driver.year, driver.manufacturer);
+ tempbuf[0] = string_format(_("%1$s, %2$s"), driver.year, driver.manufacturer);
// next line is clone/parent status
int cloneof = driver_list::non_bios_clone(driver);
@@ -714,9 +713,9 @@ void menu_select_launch::custom_render(void *selectedref, float top, float botto
if (0 > cloneof)
tempbuf[1] = _("Driver is parent");
else if (system)
- tempbuf[1] = string_format(_("Driver is clone of: %1$-.100s"), system->parent);
+ tempbuf[1] = string_format(_("Driver is clone of: %1$s"), system->parent);
else
- tempbuf[1] = string_format(_("Driver is clone of: %1$-.100s"), driver_list::driver(cloneof).type.fullname());
+ tempbuf[1] = string_format(_("Driver is clone of: %1$s"), driver_list::driver(cloneof).type.fullname());
// next line is overall driver status
system_flags const &flags(get_system_flags(driver));
@@ -1278,7 +1277,7 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
float const ypos = y2 + ui().get_line_height() + 2.0f * ui().box_tb_border();
ui().draw_text_box(
container(),
- have_parent ? _("Return to previous menu") : _("Exit"),
+ have_parent ? _("Return to Previous Menu") : _("Exit"),
text_layout::text_justify::RIGHT, 1.0f - lr_border, ypos,
ui().colors().background_color());
}
@@ -1407,8 +1406,6 @@ void menu_select_launch::get_title_search(std::string &snaptext, std::string &se
void menu_select_launch::handle_keys(uint32_t flags, int &iptkey)
{
- bool const ignorepause = stack_has_special_main_menu();
-
// bail if no items
if (item_count() == 0)
return;
@@ -1603,15 +1600,6 @@ void menu_select_launch::handle_keys(uint32_t flags, int &iptkey)
rotate_focus(-1);
}
- // pause enables/disables pause
- if (!m_ui_error && !ignorepause && exclusive_input_pressed(iptkey, IPT_UI_PAUSE, 0))
- {
- if (machine().paused())
- machine().resume();
- else
- machine().pause();
- }
-
// handle a toggle cheats request
if (!m_ui_error && machine().ui_input().pressed_repeat(IPT_UI_TOGGLE_CHEAT, 0))
mame_machine_manager::instance()->cheat().set_enable(!mame_machine_manager::instance()->cheat().enabled());
@@ -1628,6 +1616,7 @@ void menu_select_launch::handle_keys(uint32_t flags, int &iptkey)
{
case IPT_UI_FOCUS_NEXT:
case IPT_UI_FOCUS_PREV:
+ case IPT_UI_PAUSE:
continue;
case IPT_UI_LEFT:
if (ignoreleft)
@@ -1637,10 +1626,6 @@ void menu_select_launch::handle_keys(uint32_t flags, int &iptkey)
if (ignoreright)
continue;
break;
- case IPT_UI_PAUSE:
- if (ignorepause)
- continue;
- break;
}
if (exclusive_input_pressed(iptkey, code, 0))
diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp
index 05ce1302a70..e0d3023050a 100644
--- a/src/frontend/mame/ui/selsoft.cpp
+++ b/src/frontend/mame/ui/selsoft.cpp
@@ -394,27 +394,25 @@ menu_select_software::~menu_select_software()
// handle
//-------------------------------------------------
-void menu_select_software::handle()
+void menu_select_software::handle(event const *ev)
{
if (m_prev_selected == nullptr)
m_prev_selected = item(0).ref;
- // ignore pause keys by swallowing them before we process the menu
- machine().ui_input().pressed(IPT_UI_PAUSE);
+ // FIXME: everything above here used run before events were processed
// process the menu
- const event *menu_event = process(PROCESS_LR_REPEAT);
- if (menu_event)
+ if (ev)
{
if (dismiss_error())
{
- // reset the error on any future event
+ // reset the error on any subsequent menu event
}
- else switch (menu_event->iptkey)
+ else switch (ev->iptkey)
{
case IPT_UI_SELECT:
- if ((get_focus() == focused_menu::MAIN) && menu_event->itemref)
- inkey_select(menu_event);
+ if ((get_focus() == focused_menu::MAIN) && ev->itemref)
+ inkey_select(ev);
break;
case IPT_UI_LEFT:
@@ -470,12 +468,12 @@ void menu_select_software::handle()
break;
default:
- if (menu_event->itemref)
+ if (ev->itemref)
{
- if (menu_event->iptkey == IPT_UI_FAVORITES)
+ if (ev->iptkey == IPT_UI_FAVORITES)
{
// handle UI_FAVORITES
- ui_software_info *swinfo = (ui_software_info *)menu_event->itemref;
+ ui_software_info *swinfo = (ui_software_info *)ev->itemref;
if ((uintptr_t)swinfo > 2)
{
diff --git a/src/frontend/mame/ui/selsoft.h b/src/frontend/mame/ui/selsoft.h
index d3b2d88f71b..c91495d568d 100644
--- a/src/frontend/mame/ui/selsoft.h
+++ b/src/frontend/mame/ui/selsoft.h
@@ -40,7 +40,7 @@ private:
class machine_data;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// drawing
virtual float draw_left_panel(float x1, float y1, float x2, float y2) override;
diff --git a/src/frontend/mame/ui/simpleselgame.cpp b/src/frontend/mame/ui/simpleselgame.cpp
index 9ad2fe62dc3..4803b390247 100644
--- a/src/frontend/mame/ui/simpleselgame.cpp
+++ b/src/frontend/mame/ui/simpleselgame.cpp
@@ -35,7 +35,7 @@ namespace ui {
simple_menu_select_game::simple_menu_select_game(mame_ui_manager &mui, render_container &container, const char *gamename)
: menu(mui, container)
- , m_error(false), m_rerandomize(false)
+ , m_nomatch(false), m_error(false), m_rerandomize(false)
, m_search()
, m_driverlist(driver_list::total() + 1)
, m_drivlist()
@@ -44,6 +44,7 @@ simple_menu_select_game::simple_menu_select_game(mame_ui_manager &mui, render_co
, m_cached_unemulated(device_t::feature::NONE), m_cached_imperfect(device_t::feature::NONE)
, m_cached_color(ui().colors().background_color())
{
+ set_process_flags(PROCESS_IGNOREPAUSE);
set_needs_prev_menu_item(false);
build_driver_list();
if (gamename)
@@ -109,34 +110,30 @@ void simple_menu_select_game::build_driver_list()
// handle - handle the game select menu
//-------------------------------------------------
-void simple_menu_select_game::handle()
+void simple_menu_select_game::handle(event const *ev)
{
- // ignore pause keys by swallowing them before we process the menu
- machine().ui_input().pressed(IPT_UI_PAUSE);
-
// process the menu
- const event *menu_event = process(0);
- if (menu_event)
+ if (ev)
{
if (m_error)
{
- // reset the error on any future menu_event
+ // reset the error on any subsequent menu event
m_error = false;
machine().ui_input().reset();
}
else
{
// handle selections
- switch(menu_event->iptkey)
+ switch(ev->iptkey)
{
case IPT_UI_SELECT:
- inkey_select(menu_event);
+ inkey_select(*ev);
break;
case IPT_UI_CANCEL:
inkey_cancel();
break;
case IPT_SPECIAL:
- inkey_special(menu_event);
+ inkey_special(*ev);
break;
}
}
@@ -158,9 +155,9 @@ void simple_menu_select_game::handle()
// inkey_select
//-------------------------------------------------
-void simple_menu_select_game::inkey_select(const event *menu_event)
+void simple_menu_select_game::inkey_select(const event &menu_event)
{
- const game_driver *driver = (const game_driver *)menu_event->itemref;
+ const game_driver *driver = (const game_driver *)menu_event.itemref;
if ((uintptr_t)driver == 1) // special case for configure inputs
{
@@ -217,11 +214,11 @@ void simple_menu_select_game::inkey_cancel()
// inkey_special - typed characters append to the buffer
//-------------------------------------------------
-void simple_menu_select_game::inkey_special(const event *menu_event)
+void simple_menu_select_game::inkey_special(const event &menu_event)
{
// typed characters append to the buffer
size_t old_size = m_search.size();
- if (input_character(m_search, menu_event->unichar, uchar_is_printable))
+ if (input_character(m_search, menu_event.unichar, uchar_is_printable))
{
if (m_search.size() < old_size)
m_rerandomize = true;
@@ -243,49 +240,41 @@ void simple_menu_select_game::populate(float &customtop, float &custombottom)
matchcount++;
// if nothing there, add a single multiline item and return
- if (matchcount == 0)
- {
- std::string txt = string_format(
- _("No machines found. Please check the rompath specified in the %1$s.ini file.\n\n"
- "If this is your first time using %2$s, please see the config.txt file in "
- "the docs directory for information on configuring %2$s."),
- emulator_info::get_configname(),
- emulator_info::get_appname());
- item_append(txt, FLAG_MULTILINE | FLAG_REDTEXT, nullptr);
- return;
- }
+ m_nomatch = !matchcount;
// otherwise, rebuild the match list
- assert(m_drivlist != nullptr);
- if (!m_search.empty() || m_matchlist[0] == -1 || m_rerandomize)
- m_drivlist->find_approximate_matches(m_search, matchcount, m_matchlist);
- m_rerandomize = false;
-
- // iterate over entries
- for (curitem = 0; curitem < matchcount; curitem++)
+ if (matchcount)
{
- int curmatch = m_matchlist[curitem];
- if (curmatch != -1)
+ assert(m_drivlist != nullptr);
+ if (!m_search.empty() || m_matchlist[0] == -1 || m_rerandomize)
+ m_drivlist->find_approximate_matches(m_search, matchcount, m_matchlist);
+ m_rerandomize = false;
+
+ // iterate over entries
+ for (curitem = 0; curitem < matchcount; curitem++)
{
- int cloneof = m_drivlist->non_bios_clone(curmatch);
- item_append(
- m_drivlist->driver(curmatch).type.fullname(),
- m_drivlist->driver(curmatch).name,
- (cloneof == -1) ? 0 : FLAG_INVERT,
- (void *)&m_drivlist->driver(curmatch));
+ int curmatch = m_matchlist[curitem];
+ if (curmatch != -1)
+ {
+ int cloneof = m_drivlist->non_bios_clone(curmatch);
+ item_append(
+ m_drivlist->driver(curmatch).type.fullname(),
+ m_drivlist->driver(curmatch).name,
+ (cloneof == -1) ? 0 : FLAG_INVERT,
+ (void *)&m_drivlist->driver(curmatch));
+ }
}
+ item_append(menu_item_type::SEPARATOR);
}
// if we're forced into this, allow general input configuration as well
if (stack_has_special_main_menu())
{
- item_append(menu_item_type::SEPARATOR);
item_append(_("Configure Options"), 0, (void *)1);
item_append(_("Exit"), 0, nullptr);
}
else
{
- item_append(menu_item_type::SEPARATOR);
item_append(_("Return to Previous Menu"), 0, nullptr);
}
@@ -301,6 +290,23 @@ void simple_menu_select_game::populate(float &customtop, float &custombottom)
void simple_menu_select_game::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
+ // if no matches, display the error message
+ if (m_nomatch)
+ {
+ ui().draw_text_box(
+ container(),
+ string_format(
+ _("No machines found. Please check the rompath specified in the %1$s.ini file.\n\n"
+ "If this is your first time using %2$s, please see the config.txt file in "
+ "the docs directory for information on configuring %2$s."),
+ emulator_info::get_configname(),
+ emulator_info::get_appname()),
+ text_layout::text_justify::CENTER,
+ 0.5f, origy2 + ui().box_tb_border() + (0.5f * (bottom - ui().box_tb_border())),
+ UI_RED_COLOR);
+ return;
+ }
+
const game_driver *driver;
std::string tempbuf[5];
@@ -328,7 +334,7 @@ void simple_menu_select_game::custom_render(void *selectedref, float top, float
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), driver->year, driver->manufacturer);
// next line source path
- tempbuf[2] = string_format(_("Driver: %1$-.100s"), core_filename_extract_base(driver->type.source()));
+ tempbuf[2] = string_format(_("Driver: %1$s"), core_filename_extract_base(driver->type.source()));
// update cached values if selection changed
if (driver != m_cached_driver)
@@ -411,7 +417,7 @@ void simple_menu_select_game::force_game_select(mame_ui_manager &mui, render_con
char *gamename = (char *)mui.machine().options().system_name();
// reset the menu stack
- menu::stack_reset(mui.machine());
+ menu::stack_reset(mui);
// add the quit entry followed by the game select entry
menu::stack_push_special_main<menu_quit_game>(mui, container);
diff --git a/src/frontend/mame/ui/simpleselgame.h b/src/frontend/mame/ui/simpleselgame.h
index 7a581b5ea32..e5ea310c7ec 100644
--- a/src/frontend/mame/ui/simpleselgame.h
+++ b/src/frontend/mame/ui/simpleselgame.h
@@ -36,15 +36,16 @@ private:
enum { VISIBLE_GAMES_IN_LIST = 15 };
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// internal methods
void build_driver_list();
- void inkey_select(const event *menu_event);
+ void inkey_select(const event &menu_event);
void inkey_cancel();
- void inkey_special(const event *menu_event);
+ void inkey_special(const event &menu_event);
// internal state
+ bool m_nomatch;
bool m_error;
bool m_rerandomize;
std::string m_search;
diff --git a/src/frontend/mame/ui/sliders.cpp b/src/frontend/mame/ui/sliders.cpp
index 99b3756bfec..e26b76e2302 100644
--- a/src/frontend/mame/ui/sliders.cpp
+++ b/src/frontend/mame/ui/sliders.cpp
@@ -19,9 +19,13 @@
namespace ui {
-menu_sliders::menu_sliders(mame_ui_manager &mui, render_container &container, bool menuless_mode) : menu(mui, container)
+menu_sliders::menu_sliders(mame_ui_manager &mui, render_container &container, bool menuless_mode)
+ : menu(mui, container)
+ , m_menuless_mode(menuless_mode)
+ , m_hidden(menuless_mode)
{
- m_menuless_mode = m_hidden = menuless_mode;
+ set_one_shot(menuless_mode);
+ set_process_flags(PROCESS_LR_REPEAT | (m_hidden ? PROCESS_CUSTOM_ONLY : 0));
}
menu_sliders::~menu_sliders()
@@ -32,32 +36,34 @@ menu_sliders::~menu_sliders()
// menu_sliders - handle the sliders menu
//-------------------------------------------------
-void menu_sliders::handle()
+void menu_sliders::handle(event const *ev)
{
- const event *menu_event;
-
// process the menu
- menu_event = process(PROCESS_LR_REPEAT | (m_hidden ? PROCESS_CUSTOM_ONLY : 0));
- if (menu_event != nullptr)
+ if (ev)
{
// handle keys if there is a valid item selected
- if (menu_event->itemref != nullptr && menu_event->type == menu_item_type::SLIDER)
+ if (ev->itemref && (ev->type == menu_item_type::SLIDER))
{
- const slider_state *slider = (const slider_state *)menu_event->itemref;
+ const slider_state *slider = (const slider_state *)ev->itemref;
int32_t curvalue = slider->update(nullptr, SLIDER_NOCHANGE);
int32_t increment = 0;
bool alt_pressed = machine().input().code_pressed(KEYCODE_LALT) || machine().input().code_pressed(KEYCODE_RALT);
bool ctrl_pressed = machine().input().code_pressed(KEYCODE_LCONTROL) || machine().input().code_pressed(KEYCODE_RCONTROL);
bool shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT);
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
// toggle visibility
case IPT_UI_ON_SCREEN_DISPLAY:
if (m_menuless_mode)
+ {
stack_pop();
+ }
else
+ {
m_hidden = !m_hidden;
+ set_process_flags(PROCESS_LR_REPEAT | (m_hidden ? PROCESS_CUSTOM_ONLY : 0));
+ }
break;
// decrease value
@@ -114,9 +120,9 @@ void menu_sliders::handle()
// if we are selecting an invalid item and we are hidden, skip to the next one
else if (m_hidden)
{
- // if we got here via up or page up, select the previous item
- if (menu_event->iptkey == IPT_UI_UP || menu_event->iptkey == IPT_UI_PAGE_UP)
+ 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
@@ -125,10 +131,9 @@ void menu_sliders::handle()
validate_selection(-1);
}
}
-
- // otherwise select the next item
- else if (menu_event->iptkey == IPT_UI_DOWN || menu_event->iptkey == IPT_UI_PAGE_DOWN)
+ 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
@@ -157,7 +162,7 @@ void menu_sliders::populate(float &customtop, float &custombottom)
{
if (item.type == menu_item_type::SLIDER)
{
- slider_state* slider = reinterpret_cast<slider_state *>(item.ref);
+ slider_state *const slider = reinterpret_cast<slider_state *>(item.ref);
bool display(true);
#if 0
// FIXME: this test should be reimplemented in a dedicated menu
@@ -286,30 +291,4 @@ void menu_sliders::custom_render(void *selectedref, float top, float bottom, flo
}
}
-
-//-------------------------------------------------
-// slider_ui_handler - pushes the slider
-// menu on the stack and hands off to the
-// standard menu handler
-//-------------------------------------------------
-
-uint32_t menu_sliders::ui_handler(render_container &container, mame_ui_manager &mui)
-{
- uint32_t result;
-
- // if this is the first call, push the sliders menu
- if (topmost_menu<menu_sliders>(mui.machine()) == nullptr)
- menu::stack_push<menu_sliders>(mui, container, true);
-
- // handle standard menus
- result = menu::ui_handler(container, mui);
-
- // if we are cancelled, pop the sliders menu
- if (result == UI_HANDLER_CANCEL)
- menu::stack_pop(mui.machine());
-
- menu_sliders *uim = topmost_menu<menu_sliders>(mui.machine());
- return uim && uim->m_menuless_mode ? 0 : UI_HANDLER_CANCEL;
-}
-
} // namespace ui
diff --git a/src/frontend/mame/ui/sliders.h b/src/frontend/mame/ui/sliders.h
index 4ef399173e3..6dd763b9c2f 100644
--- a/src/frontend/mame/ui/sliders.h
+++ b/src/frontend/mame/ui/sliders.h
@@ -8,38 +8,33 @@
***************************************************************************/
-#pragma once
-
#ifndef MAME_FRONTEND_UI_SLIDERS_H
#define MAME_FRONTEND_UI_SLIDERS_H
+#pragma once
+
#include "ui/menu.h"
+
namespace ui {
+
class menu_sliders : public menu
{
public:
menu_sliders(mame_ui_manager &mui, render_container &container, bool menuless_mode = false);
virtual ~menu_sliders() override;
- static uint32_t ui_handler(render_container &container, mame_ui_manager &mui);
-
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
- enum {
- INPUT_GROUPS,
- INPUT_SPECIFIC,
- };
-
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
- bool m_menuless_mode;
+ bool const m_menuless_mode;
bool m_hidden;
};
} // namespace ui
-#endif /* MAME_FRONTEND_UI_SLIDERS_H */
+#endif // MAME_FRONTEND_UI_SLIDERS_H
diff --git a/src/frontend/mame/ui/slotopt.cpp b/src/frontend/mame/ui/slotopt.cpp
index b21a039f86a..e27e6261c63 100644
--- a/src/frontend/mame/ui/slotopt.cpp
+++ b/src/frontend/mame/ui/slotopt.cpp
@@ -200,7 +200,7 @@ void menu_slot_devices::populate(float &customtop, float &custombottom)
item_append(slot.slot_name(), opt_name, item_flags, (void *)&slot);
}
item_append(menu_item_type::SEPARATOR);
- item_append(_("Reset"), 0, ITEMREF_RESET);
+ item_append(_("Reset Machine"), 0, ITEMREF_RESET);
// leave space for the name of the current option at the bottom
custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border();
@@ -231,26 +231,24 @@ void menu_slot_devices::custom_render(void *selectedref, float top, float bottom
// handle - process an input event
//-------------------------------------------------
-void menu_slot_devices::handle()
+void menu_slot_devices::handle(event const *ev)
{
// process the menu
- event const *const menu_event(process(0));
-
- if (menu_event && menu_event->itemref != nullptr)
+ if (ev && ev->itemref != nullptr)
{
- if (menu_event->itemref == ITEMREF_RESET)
+ if (ev->itemref == ITEMREF_RESET)
{
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
machine().schedule_hard_reset();
}
- else if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
- device_slot_interface *slot = (device_slot_interface *)menu_event->itemref;
- rotate_slot_device(*slot, menu_event->iptkey == IPT_UI_LEFT ? step_t::PREVIOUS : step_t::NEXT);
+ 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 (menu_event->iptkey == IPT_UI_SELECT)
+ else if (ev->iptkey == IPT_UI_SELECT)
{
- device_slot_interface *slot = (device_slot_interface *)menu_event->itemref;
+ 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<menu_device_config>(ui(), container(), slot, option);
diff --git a/src/frontend/mame/ui/slotopt.h b/src/frontend/mame/ui/slotopt.h
index ec8c08416cf..449d22627aa 100644
--- a/src/frontend/mame/ui/slotopt.h
+++ b/src/frontend/mame/ui/slotopt.h
@@ -34,7 +34,7 @@ private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) override;
- virtual void handle() override;
+ virtual void 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 8eff1ed1b92..b1842969f8f 100644
--- a/src/frontend/mame/ui/sndmenu.cpp
+++ b/src/frontend/mame/ui/sndmenu.cpp
@@ -9,12 +9,16 @@
*********************************************************************/
#include "emu.h"
-#include "ui/ui.h"
#include "ui/sndmenu.h"
+
#include "ui/selector.h"
+#include "ui/ui.h"
+
#include "../osd/modules/lib/osdobj_common.h" // TODO: remove
+
namespace ui {
+
const int menu_sound_options::m_sound_rate[] = { 11025, 22050, 44100, 48000 };
//-------------------------------------------------
@@ -70,19 +74,17 @@ menu_sound_options::~menu_sound_options()
// handle
//-------------------------------------------------
-void menu_sound_options::handle()
+void menu_sound_options::handle(event const *ev)
{
bool changed = false;
// process the menu
- const event *menu_event = process(0);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr)
+ if (ev && ev->itemref)
{
- switch ((uintptr_t)menu_event->itemref)
+ switch ((uintptr_t)ev->itemref)
{
case ENABLE_SOUND:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT || menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT)
{
m_sound = !m_sound;
changed = true;
@@ -90,7 +92,7 @@ void menu_sound_options::handle()
break;
case ENABLE_COMPRESSOR:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT || menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT)
{
m_compressor = !m_compressor;
changed = true;
@@ -98,12 +100,12 @@ void menu_sound_options::handle()
break;
case SAMPLE_RATE:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
- (menu_event->iptkey == IPT_UI_LEFT) ? m_cur_rates-- : m_cur_rates++;
+ (ev->iptkey == IPT_UI_LEFT) ? m_cur_rates-- : m_cur_rates++;
changed = true;
}
- else if (menu_event->iptkey == IPT_UI_SELECT)
+ else if (ev->iptkey == IPT_UI_SELECT)
{
int total = std::size(m_sound_rate);
std::vector<std::string> s_sel(total);
@@ -121,7 +123,7 @@ void menu_sound_options::handle()
break;
case ENABLE_SAMPLES:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT || menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT)
{
m_samples = !m_samples;
changed = true;
diff --git a/src/frontend/mame/ui/sndmenu.h b/src/frontend/mame/ui/sndmenu.h
index 2684f9c7854..35ac73981df 100644
--- a/src/frontend/mame/ui/sndmenu.h
+++ b/src/frontend/mame/ui/sndmenu.h
@@ -16,9 +16,11 @@
#include "ui/menu.h"
namespace ui {
+
//-------------------------------------------------
// class sound options menu
//-------------------------------------------------
+
class menu_sound_options : public menu
{
public:
@@ -38,7 +40,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
uint16_t m_cur_rates;
static const int m_sound_rate[];
@@ -48,4 +50,4 @@ private:
} // namespace ui
-#endif /* MAME_FRONTEND_UI_SNDMENU_H */
+#endif // MAME_FRONTEND_UI_SNDMENU_H
diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp
index af56b28e298..72ed3941196 100644
--- a/src/frontend/mame/ui/state.cpp
+++ b/src/frontend/mame/ui/state.cpp
@@ -82,17 +82,26 @@ menu_load_save_state_base::file_entry::file_entry(std::string &&file_name, std::
// ctor
//-------------------------------------------------
-menu_load_save_state_base::menu_load_save_state_base(mame_ui_manager &mui, render_container &container, std::string_view header, std::string_view footer, bool must_exist)
+menu_load_save_state_base::menu_load_save_state_base(
+ mame_ui_manager &mui,
+ render_container &container,
+ std::string_view header,
+ std::string_view footer,
+ bool must_exist,
+ bool one_shot)
: menu(mui, container)
, m_switch_poller(machine().input())
, m_header(header)
, m_footer(footer)
, m_confirm_delete(nullptr)
, m_must_exist(must_exist)
+ , m_one_shot(one_shot)
, m_first_time(true)
, m_was_paused(false)
, m_keys_released(false)
{
+ set_one_shot(one_shot);
+ set_needs_prev_menu_item(!one_shot);
}
@@ -212,10 +221,12 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom)
if (m_entries_vec.empty())
{
- item_append(_("No save states found"), 0, nullptr);
+ item_append(_("[no saved states found]"), FLAG_DISABLE, nullptr);
set_selection(nullptr);
}
item_append(menu_item_type::SEPARATOR);
+ if (m_one_shot)
+ item_append(_("Cancel"), 0, nullptr);
// set up custom render proc
customtop = ui().get_line_height() + (3.0f * ui().box_tb_border());
@@ -240,27 +251,28 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_load_save_state_base::handle()
+void menu_load_save_state_base::handle(event const *ev)
{
- // process the menu
- event const *const event = process(0);
-
// process the event
- if (event && (event->iptkey == IPT_UI_SELECT))
+ if (ev && (ev->iptkey == IPT_UI_SELECT))
{
- if (event->itemref)
+ if (ev->itemref)
{
// user selected one of the entries
- file_entry const &entry = file_entry_from_itemref(event->itemref);
+ file_entry const &entry = file_entry_from_itemref(ev->itemref);
slot_selected(std::string(entry.file_name()));
}
+ else
+ {
+ stack_pop();
+ }
}
- else if (event && (event->iptkey == IPT_UI_CLEAR))
+ else if (ev && (ev->iptkey == IPT_UI_CLEAR))
{
- if (event->itemref)
+ if (ev->itemref)
{
// prompt to confirm delete
- m_confirm_delete = &file_entry_from_itemref(event->itemref);
+ m_confirm_delete = &file_entry_from_itemref(ev->itemref);
m_confirm_prompt = util::string_format(
_("Delete saved state %1$s?\nPress %2$s to delete\nPress %3$s to cancel"),
m_confirm_delete->visible_name(),
@@ -344,7 +356,7 @@ void menu_load_save_state_base::slot_selected(std::string &&name)
s_last_file_selected = std::move(name);
// no matter what, pop out
- menu::stack_pop(machine());
+ menu::stack_pop();
}
@@ -409,7 +421,13 @@ void menu_load_save_state_base::handle_keys(uint32_t flags, int &iptkey)
void menu_load_save_state_base::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
- extra_text_render(top, bottom, origx1, origy1, origx2, origy2, m_header, std::string_view());
+ // draw menu title
+ draw_text_box(
+ &m_header, &m_header + 1,
+ origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
+ ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
+
std::string_view text[2];
unsigned count(0U);
@@ -493,8 +511,8 @@ bool menu_load_save_state_base::is_present(const std::string &name) const
// ctor
//-------------------------------------------------
-menu_load_state::menu_load_state(mame_ui_manager &mui, render_container &container)
- : menu_load_save_state_base(mui, container, _("Load State"), _("Select state to load"), true)
+menu_load_state::menu_load_state(mame_ui_manager &mui, render_container &container, bool one_shot)
+ : menu_load_save_state_base(mui, container, _("Load State"), _("Select state to load"), true, one_shot)
{
}
@@ -517,8 +535,8 @@ void menu_load_state::process_file(std::string &&file_name)
// ctor
//-------------------------------------------------
-menu_save_state::menu_save_state(mame_ui_manager &mui, render_container &container)
- : menu_load_save_state_base(mui, container, _("Save State"), _("Press a key or joystick button, or select state to overwrite"), false)
+menu_save_state::menu_save_state(mame_ui_manager &mui, render_container &container, bool one_shot)
+ : menu_load_save_state_base(mui, container, _("Save State"), _("Press a key or joystick button, or select state to overwrite"), false, one_shot)
{
}
diff --git a/src/frontend/mame/ui/state.h b/src/frontend/mame/ui/state.h
index 4ad3ebcd26f..f6a48331981 100644
--- a/src/frontend/mame/ui/state.h
+++ b/src/frontend/mame/ui/state.h
@@ -28,12 +28,18 @@ public:
virtual ~menu_load_save_state_base() override;
protected:
- menu_load_save_state_base(mame_ui_manager &mui, render_container &container, std::string_view header, std::string_view footer, bool must_exist);
+ menu_load_save_state_base(
+ mame_ui_manager &mui,
+ render_container &container,
+ std::string_view header,
+ std::string_view footer,
+ bool must_exist,
+ bool one_shot);
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(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
virtual void process_file(std::string &&file_name) = 0;
@@ -67,6 +73,7 @@ private:
std::string m_confirm_prompt;
file_entry const * m_confirm_delete;
bool const m_must_exist;
+ bool const m_one_shot;
bool m_first_time;
bool m_was_paused;
bool m_keys_released;
@@ -86,7 +93,7 @@ private:
class menu_load_state : public menu_load_save_state_base
{
public:
- menu_load_state(mame_ui_manager &mui, render_container &container);
+ menu_load_state(mame_ui_manager &mui, render_container &container, bool one_shot);
protected:
virtual void process_file(std::string &&file_name) override;
@@ -96,7 +103,7 @@ protected:
class menu_save_state : public menu_load_save_state_base
{
public:
- menu_save_state(mame_ui_manager &mui, render_container &container);
+ menu_save_state(mame_ui_manager &mui, render_container &container, bool one_shot);
protected:
virtual void process_file(std::string &&file_name) override;
diff --git a/src/frontend/mame/ui/submenu.cpp b/src/frontend/mame/ui/submenu.cpp
index e4bd44763d4..1b55556f564 100644
--- a/src/frontend/mame/ui/submenu.cpp
+++ b/src/frontend/mame/ui/submenu.cpp
@@ -150,6 +150,8 @@ submenu::submenu(mame_ui_manager &mui, render_container &container, std::vector<
, m_options(std::move(suboptions))
, m_driver(drv)
{
+ set_process_flags(PROCESS_LR_REPEAT);
+
core_options *opts = nullptr;
if (m_driver == nullptr)
opts = dynamic_cast<core_options *>(&mui.machine().options());
@@ -234,19 +236,16 @@ submenu::~submenu()
// handle the options menu
//-------------------------------------------------
-void submenu::handle()
+void submenu::handle(event const *ev)
{
bool changed = false;
std::string error_string, tmptxt;
float f_cur, f_step;
// process the menu
- const event *menu_event = process(PROCESS_LR_REPEAT);
-
- if (menu_event != nullptr && menu_event->itemref != nullptr &&
- (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT || menu_event->iptkey == IPT_UI_SELECT))
+ if (ev && ev->itemref && (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT))
{
- option &sm_option = *reinterpret_cast<option *>(menu_event->itemref);
+ option &sm_option = *reinterpret_cast<option *>(ev->itemref);
switch (sm_option.type)
{
@@ -260,16 +259,16 @@ void submenu::handle()
sm_option.options->set_value(sm_option.name, !strcmp(sm_option.entry->value(),"1") ? "0" : "1", OPTION_PRIORITY_CMDLINE);
break;
case OPTION_INTEGER:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
changed = true;
int i_cur = atoi(sm_option.entry->value());
- (menu_event->iptkey == IPT_UI_LEFT) ? i_cur-- : i_cur++;
+ (ev->iptkey == IPT_UI_LEFT) ? i_cur-- : i_cur++;
sm_option.options->set_value(sm_option.name, i_cur, OPTION_PRIORITY_CMDLINE);
}
break;
case OPTION_FLOAT:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
changed = true;
f_cur = atof(sm_option.entry->value());
@@ -291,7 +290,7 @@ void submenu::handle()
tmptxt = '1' + std::string(precision, '0');
f_step = 1 / atof(tmptxt.c_str());
}
- if (menu_event->iptkey == IPT_UI_LEFT)
+ if (ev->iptkey == IPT_UI_LEFT)
f_cur -= f_step;
else
f_cur += f_step;
@@ -300,12 +299,12 @@ void submenu::handle()
}
break;
case OPTION_STRING:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
changed = true;
std::string v_cur(sm_option.entry->value());
int cur_value = std::distance(sm_option.value.begin(), std::find(sm_option.value.begin(), sm_option.value.end(), v_cur));
- if (menu_event->iptkey == IPT_UI_LEFT)
+ if (ev->iptkey == IPT_UI_LEFT)
v_cur = sm_option.value[--cur_value];
else
v_cur = sm_option.value[++cur_value];
diff --git a/src/frontend/mame/ui/submenu.h b/src/frontend/mame/ui/submenu.h
index f5c26c7eecb..4f2a5352715 100644
--- a/src/frontend/mame/ui/submenu.h
+++ b/src/frontend/mame/ui/submenu.h
@@ -64,7 +64,7 @@ protected:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
std::vector<option> m_options;
game_driver const *m_driver;
diff --git a/src/frontend/mame/ui/swlist.cpp b/src/frontend/mame/ui/swlist.cpp
index ac7235c1b1c..72e076df67c 100644
--- a/src/frontend/mame/ui/swlist.cpp
+++ b/src/frontend/mame/ui/swlist.cpp
@@ -124,14 +124,12 @@ void menu_software_parts::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_software_parts::handle()
+void menu_software_parts::handle(event const *ev)
{
// process the menu
- const event *event = process(0);
-
- if (event != nullptr && event->iptkey == IPT_UI_SELECT && event->itemref != nullptr)
+ if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref)
{
- software_part_menu_entry *entry = (software_part_menu_entry *) event->itemref;
+ software_part_menu_entry *entry = (software_part_menu_entry *)ev->itemref;
m_result = entry->type;
*m_selected_part = entry->part;
stack_pop();
@@ -239,16 +237,14 @@ void menu_software_list::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_software_list::handle()
+void menu_software_list::handle(event const *ev)
{
// process the menu
- const event *event = process(0);
-
- if (event)
+ if (ev)
{
- if (event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
- if (event->itemref == ITEMREF_SWITCH_ITEM_ORDERING)
+ if (ev->itemref == ITEMREF_SWITCH_ITEM_ORDERING)
{
m_ordered_by_shortname = !m_ordered_by_shortname;
@@ -262,23 +258,23 @@ void menu_software_list::handle()
? _("Switched Order: entries now ordered by shortname")
: _("Switched Order: entries now ordered by description"));
}
- else if (event->itemref)
+ else if (ev->itemref)
{
// handle selections
- entry_info *info = (entry_info *) event->itemref;
+ entry_info *info = (entry_info *)ev->itemref;
m_result = info->short_name;
stack_pop();
}
}
- else if (event->iptkey == IPT_SPECIAL)
+ else if (ev->iptkey == IPT_SPECIAL)
{
- if (input_character(m_search, event->unichar, m_ordered_by_shortname ? is_valid_softlist_part_char : [] (char32_t ch) { return true; }))
+ if (input_character(m_search, ev->unichar, m_ordered_by_shortname ? is_valid_softlist_part_char : [] (char32_t ch) { return true; }))
{
// display the popup
ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_search);
// identify the selected entry
- entry_info const *const cur_selected = (uintptr_t(event->itemref) != 1)
+ entry_info const *const cur_selected = (uintptr_t(ev->itemref) != 1)
? reinterpret_cast<entry_info const *>(get_selection_ref())
: nullptr;
@@ -315,7 +311,7 @@ void menu_software_list::handle()
}
}
}
- else if (event->iptkey == IPT_UI_CANCEL)
+ else if (ev->iptkey == IPT_UI_CANCEL)
{
// reset the char buffer also in this case
if (!m_search.empty())
@@ -410,15 +406,13 @@ void menu_software::populate(float &customtop, float &custombottom)
// handle
//-------------------------------------------------
-void menu_software::handle()
+void menu_software::handle(event const *ev)
{
// process the menu
- const event *event = process(0);
-
- if (event != nullptr && event->iptkey == IPT_UI_SELECT)
+ if (ev && (ev->iptkey == IPT_UI_SELECT))
{
- //menu::stack_push<menu_software_list>(ui(), container(), (software_list_config *)event->itemref, image);
- *m_result = reinterpret_cast<software_list_device *>(event->itemref);
+ //menu::stack_push<menu_software_list>(ui(), container(), (software_list_config *)ev->itemref, image);
+ *m_result = reinterpret_cast<software_list_device *>(ev->itemref);
stack_pop();
}
}
diff --git a/src/frontend/mame/ui/swlist.h b/src/frontend/mame/ui/swlist.h
index b62ec167b02..36e5d3c6eaf 100644
--- a/src/frontend/mame/ui/swlist.h
+++ b/src/frontend/mame/ui/swlist.h
@@ -44,7 +44,7 @@ private:
using entry_list = std::list<software_part_menu_entry>;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// variables
entry_list m_entries;
@@ -89,7 +89,7 @@ private:
bool m_ordered_by_shortname;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
// functions
void append_software_entry(const software_info &swinfo);
@@ -104,7 +104,7 @@ public:
menu_software(mame_ui_manager &mui, render_container &container, const char *interface, software_list_device **result);
virtual ~menu_software() override;
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
private:
const char * m_interface;
@@ -113,4 +113,4 @@ private:
} // namespace ui
-#endif /* MAME_FRONTEND_UI_SWLIST_H */
+#endif // MAME_FRONTEND_UI_SWLIST_H
diff --git a/src/frontend/mame/ui/tapectrl.cpp b/src/frontend/mame/ui/tapectrl.cpp
index 7881ac420db..aad554982f5 100644
--- a/src/frontend/mame/ui/tapectrl.cpp
+++ b/src/frontend/mame/ui/tapectrl.cpp
@@ -38,6 +38,7 @@ namespace ui {
menu_tape_control::menu_tape_control(mame_ui_manager &mui, render_container &container, cassette_image_device *device)
: menu_device_control<cassette_image_device>(mui, container, device)
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
@@ -116,40 +117,39 @@ void menu_tape_control::populate(float &customtop, float &custombottom)
// handle - main tape control menu
//-------------------------------------------------
-void menu_tape_control::handle()
+void menu_tape_control::handle(event const *ev)
{
// process the menu
- const event *event = process(PROCESS_LR_REPEAT);
- if (event != nullptr)
+ if (ev)
{
- switch (event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_LEFT:
- if (event->itemref == TAPECMD_SLIDER)
+ if (ev->itemref == TAPECMD_SLIDER)
current_device()->seek(-1, SEEK_CUR);
- else if (event->itemref == TAPECMD_SELECT)
+ else if (ev->itemref == TAPECMD_SELECT)
previous();
break;
case IPT_UI_RIGHT:
- if (event->itemref == TAPECMD_SLIDER)
+ if (ev->itemref == TAPECMD_SLIDER)
current_device()->seek(+1, SEEK_CUR);
- else if (event->itemref == TAPECMD_SELECT)
+ else if (ev->itemref == TAPECMD_SELECT)
next();
break;
case IPT_UI_SELECT:
- if (event->itemref == TAPECMD_STOP)
+ if (ev->itemref == TAPECMD_STOP)
current_device()->change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
- else if (event->itemref == TAPECMD_PLAY)
+ else if (ev->itemref == TAPECMD_PLAY)
current_device()->change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
- else if (event->itemref == TAPECMD_RECORD)
+ else if (ev->itemref == TAPECMD_RECORD)
current_device()->change_state(CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
- else if (event->itemref == TAPECMD_REWIND)
+ else if (ev->itemref == TAPECMD_REWIND)
current_device()->seek(-30, SEEK_CUR);
- else if (event->itemref == TAPECMD_FAST_FORWARD)
+ else if (ev->itemref == TAPECMD_FAST_FORWARD)
current_device()->seek(30, SEEK_CUR);
- else if (event->itemref == TAPECMD_SLIDER)
+ else if (ev->itemref == TAPECMD_SLIDER)
current_device()->seek(0, SEEK_SET);
break;
}
diff --git a/src/frontend/mame/ui/tapectrl.h b/src/frontend/mame/ui/tapectrl.h
index 11ac3bbfc7d..1117e88ef5e 100644
--- a/src/frontend/mame/ui/tapectrl.h
+++ b/src/frontend/mame/ui/tapectrl.h
@@ -8,15 +8,16 @@
***************************************************************************/
-#pragma once
-
#ifndef MAME_FRONTEND_UI_TAPECTRL_H
#define MAME_FRONTEND_UI_TAPECTRL_H
+#pragma once
+
#include "imagedev/cassette.h"
#include "ui/devctrl.h"
namespace ui {
+
class menu_tape_control : public menu_device_control<cassette_image_device>
{
public:
@@ -25,11 +26,11 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
static void get_time_string(std::string &dest, cassette_image_device *cassette, int *curpos, int *endpos);
};
} // namespace ui
-#endif /* MAME_FRONTEND_UI_TAPECTRL_H */
+#endif // MAME_FRONTEND_UI_TAPECTRL_H
diff --git a/src/frontend/mame/ui/textbox.cpp b/src/frontend/mame/ui/textbox.cpp
new file mode 100644
index 00000000000..177f39a0f53
--- /dev/null
+++ b/src/frontend/mame/ui/textbox.cpp
@@ -0,0 +1,237 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ui/textbox.cpp
+
+ Menu that displays a non-interactive text box
+
+***************************************************************************/
+
+#include "emu.h"
+#include "textbox.h"
+
+#include "ui/ui.h"
+#include "ui/utils.h"
+
+#include <string_view>
+
+
+namespace ui {
+
+//-------------------------------------------------
+// constructor
+//-------------------------------------------------
+
+menu_textbox::menu_textbox(mame_ui_manager &mui, render_container &container)
+ : menu(mui, container)
+ , m_layout()
+ , m_layout_width(-1.0f)
+ , m_desired_width(-1.0f)
+ , m_desired_lines(-1)
+ , m_top_line(0)
+{
+}
+
+
+//-------------------------------------------------
+// destructor
+//-------------------------------------------------
+
+menu_textbox::~menu_textbox()
+{
+}
+
+
+//-------------------------------------------------
+// reset_layout - force repopulate and scroll to
+// top
+//-------------------------------------------------
+
+void menu_textbox::reset_layout()
+{
+ m_layout = std::nullopt;
+ m_top_line = 0;
+}
+
+
+//-------------------------------------------------
+// handle_key - handle basic navigation keys
+//-------------------------------------------------
+
+void menu_textbox::handle_key(int key)
+{
+ switch (key)
+ {
+ case IPT_UI_UP:
+ --m_top_line;
+ break;
+
+ case IPT_UI_DOWN:
+ ++m_top_line;
+ break;
+
+ case IPT_UI_PAGE_UP:
+ m_top_line -= m_window_lines - 3;
+ break;
+
+ case IPT_UI_PAGE_DOWN:
+ m_top_line += m_window_lines - 3;
+ break;
+
+ case IPT_UI_HOME:
+ m_top_line = 0;
+ break;
+
+ case IPT_UI_END:
+ m_top_line = m_layout->lines() - m_window_lines;
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// custom_mouse_scroll - handle scroll events
+//-------------------------------------------------
+
+bool menu_textbox::custom_mouse_scroll(int lines)
+{
+ m_top_line += lines;
+ return true;
+}
+
+
+//-------------------------------------------------
+// draw - draw the menu
+//-------------------------------------------------
+
+void menu_textbox::draw(uint32_t flags)
+{
+ float const aspect = machine().render().ui_aspect(&container());
+ float const line_height = ui().get_line_height();
+ float const ud_arrow_width = line_height * aspect;
+ float const gutter_width = 0.52f * line_height * aspect;
+ float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
+ float const visible_left = (1.0f - visible_width) * 0.5f;
+ float const extra_height = 2.0f * line_height;
+ float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
+
+ // determine effective positions taking into account the hilighting arrows
+ float const maximum_width = visible_width - 2.0f * gutter_width;
+
+ draw_background();
+ map_mouse();
+
+ // account for extra space at the top and bottom and the separator/item for closing
+ float visible_main_menu_height = 1.0f - 2.0f * ui().box_tb_border() - visible_extra_menu_height;
+ m_window_lines = int(std::trunc(visible_main_menu_height / line_height));
+
+ // lay out the text if necessary
+ if (!m_layout || (m_layout_width != maximum_width))
+ {
+ m_desired_width = maximum_width;
+ populate_text(m_layout, m_desired_width, m_desired_lines);
+ m_layout_width = maximum_width;
+ }
+ m_window_lines = (std::min)(m_desired_lines, m_window_lines);
+ visible_main_menu_height = float(m_window_lines) * line_height;
+
+ // compute top/left of inner menu area by centering, if the menu is at the bottom of the extra, adjust
+ float const visible_top = ((1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f) + get_customtop();
+
+ // get width required to draw the sole menu item
+ menu_item const &pitem = item(0);
+ std::string_view const itemtext = pitem.text;
+ float const itemwidth = gutter_width + ui().get_string_width(itemtext) + gutter_width;
+ float const draw_width = std::min(maximum_width, std::max(itemwidth, m_desired_width));
+
+ // compute text box size
+ float const x1 = visible_left + ((maximum_width - draw_width) * 0.5f);
+ float const y1 = visible_top - ui().box_tb_border();
+ float const x2 = visible_left + visible_width - ((maximum_width - draw_width) * 0.5f);
+ float const y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
+ float const effective_left = x1 + gutter_width;
+ float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
+ float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
+ float const separator = visible_top + float(m_window_lines) * line_height;
+
+ ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
+
+ int const visible_items = m_layout->lines();
+ m_window_lines = (std::min)(visible_items, m_window_lines);
+ m_top_line = (std::max)(0, m_top_line);
+ if (m_top_line + m_window_lines >= visible_items)
+ m_top_line = visible_items - m_window_lines;
+
+ clear_hover();
+ if (m_top_line)
+ {
+ // if we're on the top line, display the up arrow
+ rgb_t fgcolor = ui().colors().text_color();
+ if (mouse_in_rect(line_x0, visible_top, line_x1, visible_top + line_height))
+ {
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, visible_top,
+ line_x1, visible_top + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_UP);
+ }
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, visible_top + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, visible_top + 0.75f * line_height,
+ fgcolor, ROT0);
+ }
+ if ((m_top_line + m_window_lines) < visible_items)
+ {
+ // if we're on the bottom line, display the down arrow
+ float const line_y = visible_top + float(m_window_lines - 1) * line_height;
+ rgb_t fgcolor = ui().colors().text_color();
+ if (mouse_in_rect(line_x0, line_y, line_x1, line_y + line_height))
+ {
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, line_y,
+ line_x1, line_y + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_DOWN);
+ }
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
+ fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
+ }
+
+ // draw visible lines, minus 1 for top arrow and 1 for bottom arrow
+ auto const text_lines = m_window_lines - (m_top_line ? 1 : 0) - (m_top_line + m_window_lines != visible_items);
+ m_layout->emit(
+ container(),
+ m_top_line ? (m_top_line + 1) : 0, text_lines,
+ effective_left, visible_top + (m_top_line ? line_height : 0.0f));
+
+ // add visual separator before the "return to prevous menu" item
+ container().add_line(
+ x1, separator + (0.5f * line_height),
+ x2, separator + (0.5f * line_height),
+ UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+
+ float const line_y0 = separator + line_height;
+ float const line_y1 = line_y0 + line_height;
+
+ if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
+ set_hover(0);
+
+ highlight(line_x0, line_y0, line_x1, line_y1, ui().colors().selected_bg_color());
+ ui().draw_text_full(
+ container(), itemtext,
+ effective_left, line_y0, draw_width,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL,
+ ui().colors().selected_color(), ui().colors().selected_bg_color(),
+ nullptr, nullptr);
+
+ // if there is something special to add, do it by calling the virtual method
+ custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
+}
+
+} // namespace ui
diff --git a/src/frontend/mame/ui/textbox.h b/src/frontend/mame/ui/textbox.h
new file mode 100644
index 00000000000..bdbb63f934a
--- /dev/null
+++ b/src/frontend/mame/ui/textbox.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ui/textbox.h
+
+ Menu that displays a non-interactive text box
+
+***************************************************************************/
+#ifndef MAME_FRONTEND_UI_TEXTBOX_H
+#define MAME_FRONTEND_UI_TEXTBOX_H
+
+#include "ui/menu.h"
+#include "ui/text.h"
+
+#include <optional>
+
+
+namespace ui {
+
+class menu_textbox : public menu
+{
+public:
+ virtual ~menu_textbox() override;
+
+protected:
+ menu_textbox(mame_ui_manager &mui, render_container &container);
+
+ void reset_layout();
+ void handle_key(int key);
+
+ virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) = 0;
+
+ virtual bool custom_mouse_scroll(int lines) override;
+
+private:
+ virtual void draw(uint32_t flags) override;
+
+ std::optional<text_layout> m_layout;
+ float m_layout_width;
+ float m_desired_width;
+ int m_desired_lines;
+ int m_window_lines;
+ int m_top_line;
+};
+
+} // namespace ui
+
+#endif // MAME_FRONTEND_UI_TEXTBOX_H
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index 8c8f44224a8..87e0caadf9d 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -42,6 +42,7 @@
#include "../osd/modules/lib/osdobj_common.h"
#include <chrono>
+#include <functional>
#include <type_traits>
@@ -166,7 +167,7 @@ static uint32_t const mouse_bitmap[32*32] =
mame_ui_manager::mame_ui_manager(running_machine &machine)
: ui_manager(machine)
, m_font()
- , m_handler_callback(nullptr)
+ , m_handler_callback()
, m_handler_callback_type(ui_callback_type::GENERAL)
, m_handler_param(0)
, m_single_step(false)
@@ -199,7 +200,6 @@ void mame_ui_manager::init()
ui::system_list::instance().cache_data(options());
// initialize the other UI bits
- ui::menu::init(machine(), options());
ui_gfx_init(machine());
m_ui_colors.refresh(options());
@@ -210,11 +210,12 @@ void mame_ui_manager::init()
// more initialization
set_handler(
ui_callback_type::GENERAL,
- [this] (render_container &container) -> uint32_t
- {
- draw_text_box(container, messagebox_text, ui::text_layout::text_justify::LEFT, 0.5f, 0.5f, colors().background_color());
- return 0;
- });
+ handler_callback_func(
+ [this] (render_container &container) -> uint32_t
+ {
+ draw_text_box(container, messagebox_text, ui::text_layout::text_justify::LEFT, 0.5f, 0.5f, colors().background_color());
+ return 0;
+ }));
m_non_char_keys_down = std::make_unique<uint8_t[]>((std::size(non_char_keys) + 7) / 8);
m_mouse_show = machine().system().flags & machine_flags::CLICKABLE_ARTWORK ? true : false;
@@ -376,7 +377,7 @@ void mame_ui_manager::initialize(running_machine &machine)
// pair for the current UI handler
//-------------------------------------------------
-void mame_ui_manager::set_handler(ui_callback_type callback_type, const std::function<uint32_t (render_container &)> &&callback)
+void mame_ui_manager::set_handler(ui_callback_type callback_type, handler_callback_func &&callback)
{
m_handler_callback = std::move(callback);
m_handler_callback_type = callback_type;
@@ -427,7 +428,6 @@ void mame_ui_manager::display_startup_screens(bool first_time)
#endif
// set up event handlers
- using namespace std::placeholders;
switch_code_poller poller(machine().input());
std::string warning_text;
rgb_t warning_color;
@@ -457,10 +457,10 @@ void mame_ui_manager::display_startup_screens(bool first_time)
return 0;
};
- set_handler(ui_callback_type::GENERAL, std::bind(&mame_ui_manager::handler_ingame, this, _1));
+ set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_ingame, this));
// loop over states
- for (int state = 0; state < maxstate && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(machine()); state++)
+ for (int state = 0; state < maxstate && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(*this); state++)
{
// default to standard colors
warning_color = colors().background_color();
@@ -475,7 +475,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
if (!warning_text.empty())
{
warning_text.append(_("\n\nPress any key to continue"));
- set_handler(ui_callback_type::MODAL, handler_messagebox_anykey);
+ set_handler(ui_callback_type::MODAL, handler_callback_func(handler_messagebox_anykey));
}
break;
@@ -548,7 +548,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
if (need_warning)
{
warning_text.append(_("\n\nPress any key to continue"));
- set_handler(ui_callback_type::MODAL, handler_messagebox_anykey);
+ set_handler(ui_callback_type::MODAL, handler_callback_func(handler_messagebox_anykey));
warning_color = machine_info().warnings_color();
}
}
@@ -579,12 +579,12 @@ void mame_ui_manager::display_startup_screens(bool first_time)
config_menu = false;
// loop while we have a handler
- while (m_handler_callback_type == ui_callback_type::MODAL && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(machine()))
+ while (m_handler_callback_type == ui_callback_type::MODAL && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(*this))
machine().video().frame_update();
}
// clear the handler and force an update
- set_handler(ui_callback_type::GENERAL, std::bind(&mame_ui_manager::handler_ingame, this, _1));
+ set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_ingame, this));
machine().video().frame_update();
}
@@ -593,7 +593,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
m_last_launch_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
// if we're the empty driver, force the menus on
- if (ui::menu::stack_has_special_main_menu(machine()))
+ if (ui::menu::stack_has_special_main_menu(*this))
show_menu();
else if (config_menu)
{
@@ -642,7 +642,7 @@ void mame_ui_manager::update_and_render(render_container &container)
if (machine().phase() >= machine_phase::RESET && (single_step() || machine().paused()))
{
int alpha = (1.0f - machine().options().pause_brightness()) * 255.0f;
- if (ui::menu::stack_has_special_main_menu(machine()))
+ if (ui::menu::stack_has_special_main_menu(*this))
alpha = 255;
if (alpha > 255)
alpha = 255;
@@ -698,8 +698,7 @@ void mame_ui_manager::update_and_render(render_container &container)
// cancel takes us back to the ingame handler
if (m_handler_param == UI_HANDLER_CANCEL)
{
- using namespace std::placeholders;
- set_handler(ui_callback_type::GENERAL, std::bind(&mame_ui_manager::handler_ingame, this, _1));
+ set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_ingame, this));
}
}
@@ -994,8 +993,7 @@ bool mame_ui_manager::show_profiler() const
void mame_ui_manager::show_menu()
{
- using namespace std::placeholders;
- set_handler(ui_callback_type::MENU, std::bind(&ui::menu::ui_handler, _1, std::ref(*this)));
+ set_handler(ui_callback_type::MENU, ui::menu::get_ui_handler(*this));
}
@@ -1188,9 +1186,8 @@ void mame_ui_manager::draw_profiler(render_container &container)
void mame_ui_manager::start_save_state()
{
- ui::menu::stack_reset(machine());
show_menu();
- ui::menu::stack_push<ui::menu_save_state>(*this, machine().render().ui_container());
+ ui::menu::stack_push<ui::menu_save_state>(*this, machine().render().ui_container(), true);
}
@@ -1200,9 +1197,8 @@ void mame_ui_manager::start_save_state()
void mame_ui_manager::start_load_state()
{
- ui::menu::stack_reset(machine());
show_menu();
- ui::menu::stack_push<ui::menu_load_state>(*this, machine().render().ui_container());
+ ui::menu::stack_push<ui::menu_load_state>(*this, machine().render().ui_container(), true);
}
@@ -1327,10 +1323,10 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
}
// if the on-screen display isn't up and the user has toggled it, turn it on
- if ((machine().debug_flags & DEBUG_FLAG_ENABLED) == 0 && machine().ui_input().pressed(IPT_UI_ON_SCREEN_DISPLAY))
+ if (!(machine().debug_flags & DEBUG_FLAG_ENABLED) && machine().ui_input().pressed(IPT_UI_ON_SCREEN_DISPLAY))
{
- using namespace std::placeholders;
- set_handler(ui_callback_type::MENU, std::bind(&ui::menu_sliders::ui_handler, _1, std::ref(*this)));
+ ui::menu::stack_push<ui::menu_sliders>(*this, machine().render().ui_container(), true);
+ set_handler(ui_callback_type::MENU, ui::menu::get_ui_handler(*this));
return 1;
}
@@ -1346,7 +1342,13 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
if (!is_paused)
machine().pause();
using namespace std::placeholders;
- set_handler(ui_callback_type::VIEWER, std::bind(&ui_gfx_ui_handler, _1, std::ref(*this), is_paused));
+ set_handler(
+ ui_callback_type::VIEWER,
+ handler_callback_func(
+ [this, is_paused] (render_container &container) -> uint32_t
+ {
+ return ui_gfx_ui_handler(container, *this, is_paused);
+ }));
return is_paused ? 1 : 0;
}
@@ -1458,11 +1460,10 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
void mame_ui_manager::request_quit()
{
- using namespace std::placeholders;
if (!machine().options().confirm_quit())
machine().schedule_exit();
else
- set_handler(ui_callback_type::GENERAL, std::bind(&mame_ui_manager::handler_confirm_quit, this, _1));
+ set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_confirm_quit, this));
}
@@ -2256,7 +2257,7 @@ void mame_ui_manager::save_main_option()
void mame_ui_manager::menu_reset()
{
- ui::menu::stack_reset(machine());
+ ui::menu::stack_reset(*this);
}
diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h
index a81278f3333..8374cbac5db 100644
--- a/src/frontend/mame/ui/ui.h
+++ b/src/frontend/mame/ui/ui.h
@@ -24,7 +24,6 @@
#include <any>
#include <cassert>
#include <ctime>
-#include <functional>
#include <map>
#include <set>
#include <string_view>
@@ -66,7 +65,6 @@ class laserdisc_device;
***************************************************************************/
class mame_ui_manager;
-typedef uint32_t (*ui_callback)(mame_ui_manager &, render_container &, uint32_t);
enum class ui_callback_type
{
@@ -151,8 +149,6 @@ public:
void initialize(running_machine &machine);
std::vector<ui::menu_item> slider_init(running_machine &machine);
- void set_handler(ui_callback_type callback_type, const std::function<uint32_t (render_container &)> &&callback);
-
void display_startup_screens(bool first_time);
virtual void set_startup_text(const char *text, bool force) override;
void update_and_render(render_container &container);
@@ -231,7 +227,7 @@ public:
std::string get_general_input_setting(ioport_type type, int player = 0, input_seq_type seqtype = SEQ_TYPE_STANDARD);
private:
- using handler_callback_func = std::function<uint32_t (render_container &)>;
+ using handler_callback_func = delegate<uint32_t (render_container &)>;
using device_feature_set = std::set<std::pair<std::string, std::string> >;
using session_data_map = std::map<std::type_index, std::any>;
@@ -276,6 +272,7 @@ private:
uint32_t handler_confirm_quit(render_container &container);
// private methods
+ void set_handler(ui_callback_type callback_type, handler_callback_func &&callback);
void exit();
void config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp
index 35aef723b13..27a27b45678 100644
--- a/src/frontend/mame/ui/utils.cpp
+++ b/src/frontend/mame/ui/utils.cpp
@@ -385,6 +385,7 @@ private:
, m_handler(std::move(handler))
, m_added(false)
{
+ set_process_flags(PROCESS_LR_REPEAT);
}
virtual ~menu_configure() override { m_handler(m_parent); }
@@ -412,7 +413,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
bool set_filter_type(unsigned pos, typename Base::type n)
{
@@ -567,15 +568,14 @@ void composite_filter_impl_base<Impl, Base, Type>::menu_configure::populate(floa
}
template <class Impl, class Base, typename Base::type Type>
-void composite_filter_impl_base<Impl, Base, Type>::menu_configure::handle()
+void composite_filter_impl_base<Impl, Base, Type>::menu_configure::handle(event const *ev)
{
- const event *menu_event = process(PROCESS_LR_REPEAT);
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
m_added = false;
bool changed(false);
- uintptr_t const ref(reinterpret_cast<uintptr_t>(menu_event->itemref));
- switch (menu_event->iptkey)
+ uintptr_t const ref(reinterpret_cast<uintptr_t>(ev->itemref));
+ switch (ev->iptkey)
{
case IPT_UI_LEFT:
case IPT_UI_RIGHT:
@@ -584,7 +584,7 @@ void composite_filter_impl_base<Impl, Base, Type>::menu_configure::handle()
// change filter type
unsigned const pos(ref - FILTER_FIRST);
typename Base::type const current(m_parent.m_filters[pos]->get_type());
- if (IPT_UI_LEFT == menu_event->iptkey)
+ if (IPT_UI_LEFT == ev->iptkey)
{
typename Base::type n(current);
while ((Base::FIRST < n) && !changed)
@@ -607,7 +607,7 @@ void composite_filter_impl_base<Impl, Base, Type>::menu_configure::handle()
{
// change filter value
Base &pos(*m_parent.m_filters[ref - ADJUST_FIRST]);
- changed = (IPT_UI_LEFT == menu_event->iptkey) ? pos.adjust_left() : pos.adjust_right();
+ changed = (IPT_UI_LEFT == ev->iptkey) ? pos.adjust_left() : pos.adjust_right();
}
break;
@@ -971,6 +971,7 @@ private:
, m_state(std::make_unique<std::pair<unsigned, bool> []>(mame_machine_manager::instance()->inifile().get_file_count()))
, m_ini(parent.m_ini)
{
+ set_process_flags(PROCESS_LR_REPEAT);
inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
for (size_t i = 0; mgr.get_file_count() > i; ++i)
{
@@ -1015,7 +1016,7 @@ private:
};
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
category_machine_filter &m_parent;
std::function<void (machine_filter &)> m_handler;
@@ -1093,15 +1094,14 @@ void category_machine_filter::menu_configure::populate(float &customtop, float &
customtop = ui().get_line_height() + 3.0f * ui().box_tb_border();
}
-void category_machine_filter::menu_configure::handle()
+void category_machine_filter::menu_configure::handle(event const *ev)
{
- const event *menu_event = process(PROCESS_LR_REPEAT);
- if (menu_event && menu_event->itemref)
+ if (ev && ev->itemref)
{
bool changed(false);
- uintptr_t const ref(reinterpret_cast<uintptr_t>(menu_event->itemref));
+ uintptr_t const ref(reinterpret_cast<uintptr_t>(ev->itemref));
inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
- switch (menu_event->iptkey)
+ switch (ev->iptkey)
{
case IPT_UI_LEFT:
if ((INI_FILE == ref) && m_ini)
diff --git a/src/frontend/mame/ui/videoopt.cpp b/src/frontend/mame/ui/videoopt.cpp
index 8d5ccbca88c..60d2b25c66b 100644
--- a/src/frontend/mame/ui/videoopt.cpp
+++ b/src/frontend/mame/ui/videoopt.cpp
@@ -67,12 +67,11 @@ void menu_video_targets::populate(float &customtop, float &custombottom)
menu
-------------------------------------------------*/
-void menu_video_targets::handle()
+void menu_video_targets::handle(event const *ev)
{
- event const *const menu_event = process(0);
- if (menu_event && (menu_event->iptkey == IPT_UI_SELECT))
+ if (ev && (ev->iptkey == IPT_UI_SELECT))
{
- render_target *const target = reinterpret_cast<render_target *>(menu_event->itemref);
+ render_target *const target = reinterpret_cast<render_target *>(ev->itemref);
menu::stack_push<menu_video_options>(
ui(),
container(),
@@ -223,25 +222,24 @@ void menu_video_options::populate(float &customtop, float &custombottom)
menu
-------------------------------------------------*/
-void menu_video_options::handle()
+void menu_video_options::handle(event const *ev)
{
auto const lockout_popup([this] () { machine().popmessage(_("Cannot change options while recording!")); });
bool const snap_lockout(m_snapshot && machine().video().is_recording());
bool changed(false);
// process the menu
- event const *const menu_event(process(0));
- if (menu_event && uintptr_t(menu_event->itemref))
+ if (ev && uintptr_t(ev->itemref))
{
- switch (reinterpret_cast<uintptr_t>(menu_event->itemref))
+ switch (reinterpret_cast<uintptr_t>(ev->itemref))
{
// rotate adds rotation depending on the direction
case ITEM_ROTATE:
- if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
+ if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
if (snap_lockout)
return lockout_popup();
- int const delta((menu_event->iptkey == IPT_UI_LEFT) ? ROT270 : ROT90);
+ int const delta((ev->iptkey == IPT_UI_LEFT) ? ROT270 : ROT90);
m_target.set_orientation(orientation_add(delta, m_target.orientation()));
if (m_target.is_ui_target())
{
@@ -255,18 +253,18 @@ void menu_video_options::handle()
// layer config bitmasks handle left/right keys the same (toggle)
case ITEM_ZOOM:
- if ((menu_event->iptkey == IPT_UI_LEFT) || (menu_event->iptkey == IPT_UI_RIGHT))
+ if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT))
{
if (snap_lockout)
return lockout_popup();
- m_target.set_zoom_to_screen(menu_event->iptkey == IPT_UI_RIGHT);
+ m_target.set_zoom_to_screen(ev->iptkey == IPT_UI_RIGHT);
changed = true;
}
break;
// non-integer scaling: rotate through options
case ITEM_UNEVENSTRETCH:
- if (menu_event->iptkey == IPT_UI_LEFT)
+ if (ev->iptkey == IPT_UI_LEFT)
{
if (snap_lockout)
return lockout_popup();
@@ -294,7 +292,7 @@ void menu_video_options::handle()
}
changed = true;
}
- else if (menu_event->iptkey == IPT_UI_RIGHT)
+ else if (ev->iptkey == IPT_UI_RIGHT)
{
if (snap_lockout)
return lockout_popup();
@@ -326,34 +324,34 @@ void menu_video_options::handle()
// keep aspect handles left/right keys the same (toggle)
case ITEM_KEEPASPECT:
- if ((menu_event->iptkey == IPT_UI_LEFT) || (menu_event->iptkey == IPT_UI_RIGHT))
+ if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT))
{
if (snap_lockout)
return lockout_popup();
- m_target.set_keepaspect(menu_event->iptkey == IPT_UI_RIGHT);
+ m_target.set_keepaspect(ev->iptkey == IPT_UI_RIGHT);
changed = true;
}
break;
// anything else is a view item
default:
- if (reinterpret_cast<uintptr_t>(menu_event->itemref) >= ITEM_VIEW_FIRST)
+ if (reinterpret_cast<uintptr_t>(ev->itemref) >= ITEM_VIEW_FIRST)
{
if (snap_lockout)
return lockout_popup();
- if (menu_event->iptkey == IPT_UI_SELECT)
+ if (ev->iptkey == IPT_UI_SELECT)
{
- m_target.set_view(reinterpret_cast<uintptr_t>(menu_event->itemref) - ITEM_VIEW_FIRST);
+ m_target.set_view(reinterpret_cast<uintptr_t>(ev->itemref) - ITEM_VIEW_FIRST);
changed = true;
}
}
- else if (reinterpret_cast<uintptr_t>(menu_event->itemref) >= ITEM_TOGGLE_FIRST)
+ else if (reinterpret_cast<uintptr_t>(ev->itemref) >= ITEM_TOGGLE_FIRST)
{
if (snap_lockout)
return lockout_popup();
- if ((menu_event->iptkey == IPT_UI_LEFT) || (menu_event->iptkey == IPT_UI_RIGHT))
+ if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT))
{
- m_target.set_visibility_toggle(reinterpret_cast<uintptr_t>(menu_event->itemref) - ITEM_TOGGLE_FIRST, menu_event->iptkey == IPT_UI_RIGHT);
+ m_target.set_visibility_toggle(reinterpret_cast<uintptr_t>(ev->itemref) - ITEM_TOGGLE_FIRST, ev->iptkey == IPT_UI_RIGHT);
changed = true;
}
}
diff --git a/src/frontend/mame/ui/videoopt.h b/src/frontend/mame/ui/videoopt.h
index 44a172cf8f5..be539cf4aa0 100644
--- a/src/frontend/mame/ui/videoopt.h
+++ b/src/frontend/mame/ui/videoopt.h
@@ -25,7 +25,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
};
@@ -38,7 +38,7 @@ public:
private:
virtual void populate(float &customtop, float &custombottom) override;
- virtual void handle() override;
+ virtual void handle(event const *ev) override;
render_target &m_target;
std::string const m_title;