From d43bf65b16f08413d9ec7886962de262d849d407 Mon Sep 17 00:00:00 2001 From: dankan1890 Date: Thu, 25 Feb 2016 16:25:22 +0100 Subject: [PATCH] ui: Enabled user interface navigation through UI_CONFIGURE button (tab key by default). [Maurizio Petrarota] --- src/emu/ui/menu.cpp | 81 ++++++++++++---- src/emu/ui/menu.h | 12 +++ src/emu/ui/miscmenu.cpp | 129 +++++++++++++++++++++++++ src/emu/ui/miscmenu.h | 11 +++ src/emu/ui/optsmenu.cpp | 16 ++-- src/emu/ui/optsmenu.h | 2 + src/emu/ui/selgame.cpp | 202 +++++++++++++++++++++------------------- src/emu/ui/selgame.h | 5 +- src/emu/ui/selsoft.cpp | 127 +++++++++++++++++-------- src/emu/ui/selsoft.h | 2 + 10 files changed, 424 insertions(+), 163 deletions(-) diff --git a/src/emu/ui/menu.cpp b/src/emu/ui/menu.cpp index 4772b39e6fd..4f63b69b7e4 100644 --- a/src/emu/ui/menu.cpp +++ b/src/emu/ui/menu.cpp @@ -255,9 +255,20 @@ void ui_menu::reset(ui_menu_reset_options options) if (parent == nullptr) item_append(backtext.c_str(), nullptr, 0, nullptr); else if (parent->is_special_main_menu()) - item_append("Exit", nullptr, 0, nullptr); + { + if (strcmp(machine().options().ui(), "simple") == 0) + item_append("Exit", nullptr, 0, nullptr); + else + item_append("Exit", nullptr, MENU_FLAG_UI | MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW, nullptr); + } else - item_append("Return to Previous Menu", nullptr, 0, nullptr); + { + if (strcmp(machine().options().ui(), "simple") == 0) + item_append("Return to Previous Menu", nullptr, 0, nullptr); + else if (ui_menu::stack_has_special_main_menu()) + item_append("Return to Previous Menu", nullptr, MENU_FLAG_UI | MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW, nullptr); + } + } @@ -1441,7 +1452,6 @@ void ui_menu::draw_select_game(bool noinput) //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B)); mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR); - if (visible_items < visible_lines) visible_lines = visible_items; if (top_line < 0 || selected == 0) @@ -1454,6 +1464,8 @@ void ui_menu::draw_select_game(bool noinput) float effective_left = visible_left + gutter_width; int n_loop = (visible_items >= visible_lines) ? visible_lines : visible_items; + if (m_prev_selected != nullptr && m_focus == focused_menu::main && selected < visible_items) + m_prev_selected = nullptr; for (int linenum = 0; linenum < n_loop; linenum++) { @@ -1474,23 +1486,28 @@ void ui_menu::draw_select_game(bool noinput) hover = itemnum; // if we're selected, draw with a different background - if (itemnum == selected) + if (itemnum == selected && m_focus == focused_menu::main) { fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); fgcolor3 = rgb_t(0xff, 0xcc, 0xcc, 0x00); + mui.draw_textured_box(container, line_x0 + 0.01f, line_y0, line_x1 - 0.01f, line_y1, bgcolor, rgb_t(255, 43, 43, 43), + hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); } // else if the mouse is over this item, draw with a different background else if (itemnum == hover) { fgcolor = fgcolor3 = UI_MOUSEOVER_COLOR; bgcolor = UI_MOUSEOVER_BG_COLOR; + highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor); } - - // if we have some background hilighting to do, add a quad behind everything else - if (bgcolor != UI_TEXT_BG_COLOR) + else if (pitem.ref == m_prev_selected) + { + fgcolor = fgcolor3 = UI_MOUSEOVER_COLOR; + bgcolor = UI_MOUSEOVER_BG_COLOR; mui.draw_textured_box(container, line_x0 + 0.01f, line_y0, line_x1 - 0.01f, line_y1, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); + } // if we're on the top line, display the up arrow if (linenum == 0 && top_line != 0) @@ -1572,7 +1589,7 @@ void ui_menu::draw_select_game(bool noinput) hover = count; // if we're selected, draw with a different background - if (count == selected) + if (count == selected && m_focus == focused_menu::main) { fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); @@ -1615,6 +1632,16 @@ void ui_menu::draw_select_game(bool noinput) // reset redraw icon stage if (!is_swlist) ui_globals::redraw_icon = false; + + // noinput + if (noinput) + { + int alpha = (1.0f - machine().options().pause_brightness()) * 255.0f; + if (alpha > 255) + alpha = 255; + if (alpha >= 0) + container->add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(alpha, 0x00, 0x00, 0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + } } //------------------------------------------------- @@ -1660,7 +1687,7 @@ void ui_menu::handle_main_keys(UINT32 flags) // if we hit select, return TRUE or pop the stack, depending on the item if (exclusive_input_pressed(IPT_UI_SELECT, 0)) { - if (selected == item.size() - 1) + if (selected == item.size() - 1 && m_focus == focused_menu::main) { menu_event.iptkey = IPT_UI_CANCEL; ui_menu::stack_pop(machine()); @@ -1684,8 +1711,7 @@ void ui_menu::handle_main_keys(UINT32 flags) // swallow left/right keys if they are not appropriate bool ignoreleft = ((item[selected].flags & MENU_FLAG_LEFT_ARROW) == 0 || ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL); bool ignoreright = ((item[selected].flags & MENU_FLAG_RIGHT_ARROW) == 0 || ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL); - bool ignoreup = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_LEFT_PANEL); - bool ignoredown = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_LEFT_PANEL); + bool leftclose = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_LEFT_PANEL); input_manager &minput = machine().input(); // accept left/right keys as-is with repeat @@ -1704,7 +1730,7 @@ void ui_menu::handle_main_keys(UINT32 flags) if (exclusive_input_pressed(IPT_UI_UP, 6)) { // Filter - if (!ignoreup && (minput.code_pressed(KEYCODE_LALT) || minput.code_pressed(JOYCODE_BUTTON2))) + if (!leftclose && m_focus == focused_menu::left) { menu_event.iptkey = IPT_UI_UP_FILTER; return; @@ -1731,7 +1757,7 @@ void ui_menu::handle_main_keys(UINT32 flags) if (exclusive_input_pressed(IPT_UI_DOWN, 6)) { // Filter - if (!ignoredown && (minput.code_pressed(KEYCODE_LALT) || minput.code_pressed(JOYCODE_BUTTON2))) + if (!leftclose && m_focus == focused_menu::left) { menu_event.iptkey = IPT_UI_DOWN_FILTER; return; @@ -1881,7 +1907,10 @@ void ui_menu::handle_main_events(UINT32 flags) else { if (hover >= 0 && hover < item.size()) + { selected = hover; + m_focus = focused_menu::main; + } else if (hover == HOVER_ARROW_UP) { selected -= visitems; @@ -2014,9 +2043,17 @@ void ui_menu::handle_main_events(UINT32 flags) // translate CHAR events into specials case UI_EVENT_CHAR: - menu_event.iptkey = IPT_SPECIAL; - menu_event.unichar = local_menu_event.ch; - stop = true; + if (exclusive_input_pressed(IPT_UI_CONFIGURE, 0)) + { + menu_event.iptkey = IPT_UI_CONFIGURE; + stop = true; + } + else + { + menu_event.iptkey = IPT_SPECIAL; + menu_event.unichar = local_menu_event.ch; + stop = true; + } break; // ignore everything else @@ -2097,13 +2134,21 @@ std::string ui_menu::arts_render_common(float origx1, float origy1, float origx2 for (int x = FIRST_VIEW; x < LAST_VIEW; x++) { machine().ui().draw_text_full(container, arts_info[x].title, origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, - WRAP_TRUNCATE, DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_lenght, nullptr); + WRAP_TRUNCATE, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &txt_lenght, nullptr); txt_lenght += 0.01f; title_size = MAX(txt_lenght, title_size); } + rgb_t fgcolor = UI_TEXT_COLOR; + rgb_t bgcolor = UI_TEXT_BG_COLOR; + if (m_focus == focused_menu::rightbottom) + { + fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); + bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); + } + machine().ui().draw_text_full(container, snaptext.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE, - DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); + DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr); draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::curimage_view, FIRST_VIEW, LAST_VIEW, title_size); diff --git a/src/emu/ui/menu.h b/src/emu/ui/menu.h index a19cb0b23dc..56992660f59 100644 --- a/src/emu/ui/menu.h +++ b/src/emu/ui/menu.h @@ -192,6 +192,18 @@ private: static void render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param); public: + // tab navigation + enum focused_menu + { + main, + left, + righttop, + rightbottom + }; + + focused_menu m_focus; + void *m_prev_selected; + int visible_items; bool ui_error; diff --git a/src/emu/ui/miscmenu.cpp b/src/emu/ui/miscmenu.cpp index cd99d0b6820..2c4ff3d7b8c 100644 --- a/src/emu/ui/miscmenu.cpp +++ b/src/emu/ui/miscmenu.cpp @@ -16,6 +16,7 @@ #include "ui/menu.h" #include "ui/miscmenu.h" #include "ui/utils.h" +#include "../info.h" /*************************************************************************** MENU HANDLERS @@ -673,3 +674,131 @@ void ui_menu_misc_options::custom_render(void *selectedref, float top, float bot mui.draw_text_full(container, _("Miscellaneous Options"), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); } + +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_export::ui_menu_export(running_machine &machine, render_container *container, std::vector drvlist) + : ui_menu(machine, container), m_list(drvlist) +{ +} + +ui_menu_export::~ui_menu_export() +{ +} + +//------------------------------------------------- +// handlethe options menu +//------------------------------------------------- + +void ui_menu_export::handle() +{ + // process the menu + ui_menu::menu_stack->parent->process(UI_MENU_PROCESS_NOINPUT); + const ui_menu_event *m_event = process(UI_MENU_PROCESS_NOIMAGE); + if (m_event != nullptr && m_event->itemref != nullptr) + { + switch ((FPTR)m_event->itemref) + { + case 1: + { + if (m_event->iptkey == IPT_UI_SELECT) + { + std::string filename("exported"); + emu_file infile(machine().ui().options().ui_path(), OPEN_FLAG_READ); + if (infile.open(filename.c_str(), ".xml") == FILERR_NONE) + for (int seq = 0; ; ++seq) + { + std::string seqtext; + strprintf(seqtext, "%s_%04d", filename.c_str(), seq); + if (infile.open(seqtext.c_str(), ".xml") != FILERR_NONE) + { + filename = seqtext; + break; + } + } + + // attempt to open the output file + emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file.open(filename.c_str(), ".xml") == FILERR_NONE) + { + FILE *pfile; + std::string fullpath(file.fullpath()); + file.close(); + pfile = fopen(fullpath.c_str(), "w"); + + // create the XML and save to file + driver_enumerator drvlist(machine().options()); + drvlist.exclude_all(); + for (auto & elem : m_list) + drvlist.include(driver_list::find(*elem)); + + info_xml_creator creator(drvlist); + creator.output(pfile, false); + fclose(pfile); + machine().popmessage(_("%s.xml saved under ui folder."), filename.c_str()); + } + } + break; + } + case 2: + { + if (m_event->iptkey == IPT_UI_SELECT) + { + std::string filename("exported"); + std::string buffer; + emu_file infile(machine().ui().options().ui_path(), OPEN_FLAG_READ); + if (infile.open(filename.c_str(), ".txt") == FILERR_NONE) + for (int seq = 0; ; ++seq) + { + std::string seqtext; + strprintf(seqtext, "%s_%04d", filename.c_str(), seq); + if (infile.open(seqtext.c_str(), ".txt") != FILERR_NONE) + { + filename = seqtext; + break; + } + } + + // attempt to open the output file + emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file.open(filename.c_str(), ".txt") == FILERR_NONE) + { + // print the header + buffer.assign(_("Name: Description:\n")); + driver_enumerator drvlist(machine().options()); + drvlist.exclude_all(); + for (auto & elem : m_list) + drvlist.include(driver_list::find(*elem)); + + // iterate through drivers and output the info + while (drvlist.next()) + if ((drvlist.driver().flags & MACHINE_NO_STANDALONE) == 0) + strcatprintf(buffer, "%-18s\"%s\"\n", drvlist.driver().name, drvlist.driver().description); + file.puts(buffer.c_str()); + file.close(); + machine().popmessage(_("%s.txt saved under ui folder."), filename.c_str()); + } + } + break; + } + + default: + break; + } + } +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_export::populate() +{ + + // add options items + item_append(_("Export XML format"), nullptr, 0, (void *)(FPTR)1); + item_append(_("Export TXT format"), nullptr, 0, (void *)(FPTR)2); + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); +} diff --git a/src/emu/ui/miscmenu.h b/src/emu/ui/miscmenu.h index f43c4a6b2ba..06115807925 100644 --- a/src/emu/ui/miscmenu.h +++ b/src/emu/ui/miscmenu.h @@ -108,4 +108,15 @@ private: static misc_option m_options[]; }; +class ui_menu_export : public ui_menu +{ +public: + ui_menu_export(running_machine &machine, render_container *container, std::vector list); + virtual ~ui_menu_export(); + virtual void populate() override; + virtual void handle() override; + +private: + std::vector m_list; +}; #endif /* __UI_MISCMENU_H__ */ diff --git a/src/emu/ui/optsmenu.cpp b/src/emu/ui/optsmenu.cpp index 29ada94b08e..66750483c43 100644 --- a/src/emu/ui/optsmenu.cpp +++ b/src/emu/ui/optsmenu.cpp @@ -30,6 +30,7 @@ ui_menu_game_options::ui_menu_game_options(running_machine &machine, render_container *container) : ui_menu(machine, container) { + m_main = main_filters::actual; } //------------------------------------------------- @@ -38,6 +39,7 @@ ui_menu_game_options::ui_menu_game_options(running_machine &machine, render_cont ui_menu_game_options::~ui_menu_game_options() { + main_filters::actual = m_main; ui_menu::menu_stack->reset(UI_MENU_RESET_SELECT_FIRST); save_ui_options(machine()); ui_globals::switch_image = true; @@ -52,9 +54,9 @@ void ui_menu_game_options::handle() bool changed = false; // process the menu -// ui_menu::menu_stack->parent->process(UI_MENU_PROCESS_NOINPUT); -// const ui_menu_event *m_event = process(UI_MENU_PROCESS_LR_REPEAT | UI_MENU_PROCESS_NOIMAGE); - const ui_menu_event *m_event = process(UI_MENU_PROCESS_LR_REPEAT); + ui_menu::menu_stack->parent->process(UI_MENU_PROCESS_NOINPUT); + const ui_menu_event *m_event = process(UI_MENU_PROCESS_LR_REPEAT | UI_MENU_PROCESS_NOIMAGE); +// const ui_menu_event *m_event = process(UI_MENU_PROCESS_LR_REPEAT); if (m_event != nullptr && m_event->itemref != nullptr) switch ((FPTR)m_event->itemref) @@ -63,7 +65,7 @@ void ui_menu_game_options::handle() { if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT) { - (m_event->iptkey == IPT_UI_RIGHT) ? ++main_filters::actual : --main_filters::actual; + (m_event->iptkey == IPT_UI_RIGHT) ? ++m_main : --m_main; changed = true; } else if (m_event->iptkey == IPT_UI_SELECT) @@ -73,7 +75,7 @@ void ui_menu_game_options::handle() for (int index = 0; index < total; ++index) s_sel[index] = main_filters::text[index]; - ui_menu::stack_push(global_alloc_clear(machine(), container, s_sel, main_filters::actual)); + ui_menu::stack_push(global_alloc_clear(machine(), container, s_sel, m_main)); } break; } @@ -197,8 +199,8 @@ void ui_menu_game_options::populate() std::string fbuff; // add filter item - UINT32 arrow_flags = get_arrow_flags((int)FILTER_FIRST, (int)FILTER_LAST, main_filters::actual); - item_append(_("Filter"), main_filters::text[main_filters::actual], arrow_flags, (void *)(FPTR)FILTER_MENU); + UINT32 arrow_flags = get_arrow_flags((int)FILTER_FIRST, (int)FILTER_LAST, m_main); + item_append(_("Filter"), main_filters::text[m_main], arrow_flags, (void *)(FPTR)FILTER_MENU); // add category subitem if (main_filters::actual == FILTER_CATEGORY && !machine().inifile().ini_index.empty()) diff --git a/src/emu/ui/optsmenu.h b/src/emu/ui/optsmenu.h index 13e857ec7ba..73b8f0f20f4 100644 --- a/src/emu/ui/optsmenu.h +++ b/src/emu/ui/optsmenu.h @@ -23,6 +23,8 @@ public: virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; private: + UINT16 m_main; + enum { FILTER_MENU = 1, diff --git a/src/emu/ui/selgame.cpp b/src/emu/ui/selgame.cpp index 8aebd63772b..90d2c64f2f4 100644 --- a/src/emu/ui/selgame.cpp +++ b/src/emu/ui/selgame.cpp @@ -161,6 +161,8 @@ void save_main_option(running_machine &machine) ui_menu_select_game::ui_menu_select_game(running_machine &machine, render_container *container, const char *gamename) : ui_menu(machine, container) { + m_focus = focused_menu::main; + highlight = 0; std::string error_string, last_filter, sub_filter; ui_options &moptions = machine.ui().options(); @@ -278,6 +280,9 @@ ui_menu_select_game::~ui_menu_select_game() void ui_menu_select_game::handle() { + if (m_prev_selected == nullptr) + m_prev_selected = item[0].ref; + bool check_filter = false; bool enabled_dats = machine().ui().options().enabled_dats(); @@ -312,10 +317,19 @@ void ui_menu_select_game::handle() // handle selections else if (m_event->iptkey == IPT_UI_SELECT) { - if (isfavorite()) - inkey_select_favorite(m_event); - else - inkey_select(m_event); + if (m_focus == focused_menu::main) + { + if (isfavorite()) + inkey_select_favorite(m_event); + else + inkey_select(m_event); + } + else if (m_focus == focused_menu::left) + { + l_hover = highlight; + check_filter = true; + m_prev_selected = nullptr; + } } // handle UI_LEFT @@ -357,17 +371,15 @@ void ui_menu_select_game::handle() } // handle UI_UP_FILTER - else if (m_event->iptkey == IPT_UI_UP_FILTER && main_filters::actual > FILTER_FIRST) + else if (m_event->iptkey == IPT_UI_UP_FILTER && highlight > FILTER_FIRST) { - l_hover = main_filters::actual - 1; - check_filter = true; + highlight--; } // handle UI_DOWN_FILTER - else if (m_event->iptkey == IPT_UI_DOWN_FILTER && main_filters::actual < FILTER_LAST) + else if (m_event->iptkey == IPT_UI_DOWN_FILTER && highlight < FILTER_LAST) { - l_hover = main_filters::actual + 1; - check_filter = true; + highlight++; } // handle UI_LEFT_PANEL @@ -456,30 +468,38 @@ void ui_menu_select_game::handle() else if (m_event->iptkey == IPT_SPECIAL) inkey_special(m_event); + else if (m_event->iptkey == IPT_UI_CONFIGURE) + inkey_configure(m_event); + else if (m_event->iptkey == IPT_OTHER) + { + m_prev_selected = nullptr; check_filter = true; + highlight = l_hover; + } } if (m_event != nullptr && m_event->itemref == nullptr) { if (m_event->iptkey == IPT_SPECIAL && m_event->unichar == 0x09) - selected = m_prev_selected; - - // handle UI_UP_FILTER - else if (m_event->iptkey == IPT_UI_UP_FILTER && main_filters::actual > FILTER_FIRST) + inkey_special(m_event); + else if (m_event->iptkey == IPT_UI_SELECT && m_focus == focused_menu::left) { - l_hover = main_filters::actual - 1; + m_prev_selected = nullptr; + l_hover = highlight; check_filter = true; } + // handle UI_UP_FILTER + else if (m_event->iptkey == IPT_UI_UP_FILTER && highlight > FILTER_FIRST) + { + highlight--; + } // handle UI_DOWN_FILTER - else if (m_event->iptkey == IPT_UI_DOWN_FILTER && main_filters::actual < FILTER_LAST) + else if (m_event->iptkey == IPT_UI_DOWN_FILTER && highlight < FILTER_LAST) { - l_hover = main_filters::actual + 1; - check_filter = true; + highlight++; } - else if (m_event->iptkey == IPT_OTHER) - check_filter = true; } // if we're in an error state, overlay an error message @@ -620,9 +640,10 @@ void ui_menu_select_game::populate() // add special items if (ui_menu::stack_has_special_main_menu()) { - item_append(_("Configure Options"), nullptr, MENU_FLAG_UI, (void *)(FPTR)1); - item_append(_("Configure Directories"), nullptr, MENU_FLAG_UI, (void *)(FPTR)2); - item_append(_("Save Configuration"), nullptr, MENU_FLAG_UI, (void *)(FPTR)3); + UINT32 flags_ui = MENU_FLAG_UI | MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW; + item_append(_("Configure Options"), nullptr, flags_ui, (void *)(FPTR)1); + item_append(_("Configure Directories"), nullptr, flags_ui, (void *)(FPTR)2); + item_append(_("Save Configuration"), nullptr, flags_ui, (void *)(FPTR)3); skip_main_items = 3; } else @@ -689,7 +710,15 @@ void ui_menu_select_game::build_available_list() continue; const rom_entry *rom = driver_list::driver(x).rom; - if (ROMENTRY_ISREGION(rom) && ROMENTRY_ISEND(++rom)) + bool noroms = true; + for (; !ROMENTRY_ISEND(rom); ++rom) + if (!ROMENTRY_ISREGION(rom)) + { + noroms = false; + break; + } + + if (noroms) { m_availsortedlist.push_back(&driver_list::driver(x)); m_included[x] = true; @@ -778,15 +807,15 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott // determine the text to render below if (!isfavorite()) - driver = ((FPTR)selectedref > skip_main_items) ? (const game_driver *)selectedref : nullptr; + driver = ((FPTR)selectedref > skip_main_items) ? (const game_driver *)selectedref : ((m_prev_selected != nullptr) ? (const game_driver *)m_prev_selected : nullptr); else { - swinfo = ((FPTR)selectedref > skip_main_items) ? (ui_software_info *)selectedref : nullptr; - if (swinfo && swinfo->startempty == 1) + swinfo = ((FPTR)selectedref > skip_main_items) ? (ui_software_info *)selectedref : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr); + if (swinfo != nullptr && swinfo->startempty == 1) driver = swinfo->driver; } - if ((FPTR)driver > 3) + if (driver != nullptr) { isstar = machine().favorite().isgame_favorite(driver); @@ -835,7 +864,7 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott color = UI_RED_COLOR; } - else if ((FPTR)swinfo > 3) + else if (swinfo != nullptr) { isstar = machine().favorite().isgame_favorite(*swinfo); @@ -1146,29 +1175,40 @@ void ui_menu_select_game::inkey_special(const ui_menu_event *m_event) *(char *)utf8_previous_char(&m_search[buflen]) = 0; reset(UI_MENU_RESET_SELECT_FIRST); } - - // if it's any other key and we're not maxed out, update else if ((m_event->unichar >= ' ' && m_event->unichar < 0x7f) && !isfavorite()) { + // if it's any other key and we're not maxed out, update buflen += utf8_from_uchar(&m_search[buflen], ARRAY_LENGTH(m_search) - buflen, m_event->unichar); m_search[buflen] = 0; reset(UI_MENU_RESET_SELECT_FIRST); } +} - // Tab key - else if (m_event->unichar == 0x09) + +void ui_menu_select_game::inkey_configure(const ui_menu_event *m_event) +{ + if (selected <= visible_items && m_focus == focused_menu::main) { - // if the selection is in the main screen, save and go to submenu - if (selected <= visible_items) + m_prev_selected = item[selected].ref; + selected = visible_items + 1; + } + else if (selected > visible_items && m_focus == focused_menu::main) + m_focus = focused_menu::left; + else if (m_focus == focused_menu::left) + { + m_focus = focused_menu::main; + if (m_prev_selected == nullptr) { - m_prev_selected = selected; - selected = visible_items + 1; + selected = 0; + return; } - // otherwise, retrieve the previous position - else - selected = m_prev_selected; + for (int x = 0; x < item.size(); ++x) + if (item[x].ref == m_prev_selected) + selected = x; } + else if (m_focus == focused_menu::rightbottom) + m_focus = focused_menu::main; } //------------------------------------------------- @@ -1502,54 +1542,19 @@ void ui_menu_select_game::general_info(const game_driver *driver, std::string &b void ui_menu_select_game::inkey_export() { - std::string filename("exported"); - emu_file infile(machine().ui().options().ui_path(), OPEN_FLAG_READ); - if (infile.open(filename.c_str(), ".xml") == FILERR_NONE) - for (int seq = 0; ; ++seq) - { - std::string seqtext; - strprintf(seqtext, "%s_%04d", filename.c_str(), seq); - if (infile.open(seqtext.c_str(), ".xml") != FILERR_NONE) - { - filename = seqtext; - break; - } - } - - // attempt to open the output file - emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(filename.c_str(), ".xml") == FILERR_NONE) + std::vector list; + if (m_search[0] != 0) { - FILE *pfile; - std::string fullpath(file.fullpath()); - file.close(); - pfile = fopen(fullpath.c_str() , "w"); - driver_enumerator drivlist(machine().options()); - drivlist.exclude_all(); - - if (m_search[0] != 0) + for (int curitem = 0; m_searchlist[curitem]; ++curitem) { - for (int curitem = 0; m_searchlist[curitem]; ++curitem) - { - int f = driver_list::find(m_searchlist[curitem]->name); - drivlist.include(f); - } + list.push_back(m_searchlist[curitem]); } - else - { - for (auto & elem : m_displaylist) - { - int f = driver_list::find(elem->name); - drivlist.include(f); - } - } - - // create the XML and save to file - info_xml_creator creator(drivlist); - creator.output(pfile, false); - fclose(pfile); - machine().popmessage("%s.xml saved under ui folder.", filename.c_str()); } + else + { + list = m_displaylist; + } + ui_menu::stack_push(global_alloc_clear(machine(), container, list)); } //------------------------------------------------- @@ -1758,14 +1763,15 @@ float ui_menu_select_game::draw_left_panel(float x1, float y1, float x2, float y hover = phover + filter; } -/* if (afilter == filter) - { - bgcolor = UI_SELECTED_BG_COLOR; - fgcolor = UI_SELECTED_COLOR; - } -*/ + if (highlight == filter && m_focus == focused_menu::left) + { + fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); + bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); + } + if (bgcolor != UI_TEXT_BG_COLOR) - container->add_rect(x1, y1, x2, y1 + line_height_max, bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); + mui.draw_textured_box(container, x1, y1, x2, y1 + line_height_max, bgcolor, rgb_t(255, 43, 43, 43), + hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); float x1t = x1 + text_sign; if (afilter == FILTER_CUSTOM) @@ -1792,7 +1798,7 @@ float ui_menu_select_game::draw_left_panel(float x1, float y1, float x2, float y } else if (filter == main_filters::actual) { - str.assign("@custom1 ").append(text[filter]); + str.assign("_> ").append(text[filter]); x1t -= text_sign; convert_command_glyph(str); } @@ -1872,7 +1878,7 @@ void ui_menu_select_game::infos_render(void *selectedref, float origx1, float or if (is_favorites) { - soft = ((FPTR)selectedref > skip_main_items) ? (ui_software_info *)selectedref : nullptr; + soft = ((FPTR)selectedref > skip_main_items) ? (ui_software_info *)selectedref : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr); if (soft && soft->startempty == 1) { driver = soft->driver; @@ -1883,7 +1889,7 @@ void ui_menu_select_game::infos_render(void *selectedref, float origx1, float or } else { - driver = ((FPTR)selectedref > skip_main_items) ? (const game_driver *)selectedref : nullptr; + driver = ((FPTR)selectedref > skip_main_items) ? (const game_driver *)selectedref : ((m_prev_selected != nullptr) ? (const game_driver *)m_prev_selected : nullptr); oldsoft = nullptr; } @@ -2192,7 +2198,7 @@ void ui_menu_select_game::arts_render(void *selectedref, float origx1, float ori if (is_favorites) { - soft = ((FPTR)selectedref > skip_main_items) ? (ui_software_info *)selectedref : nullptr; + soft = ((FPTR)selectedref > skip_main_items) ? (ui_software_info *)selectedref : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr); if (soft && soft->startempty == 1) { driver = soft->driver; @@ -2203,11 +2209,11 @@ void ui_menu_select_game::arts_render(void *selectedref, float origx1, float ori } else { - driver = ((FPTR)selectedref > skip_main_items) ? (const game_driver *)selectedref : nullptr; + driver = ((FPTR)selectedref > skip_main_items) ? (const game_driver *)selectedref : ((m_prev_selected != nullptr) ? (const game_driver *)m_prev_selected : nullptr); oldsoft = nullptr; } - if (driver) + if (driver != nullptr) { if (ui_globals::default_image) ((driver->flags & MACHINE_TYPE_ARCADE) == 0) ? ui_globals::curimage_view = CABINETS_VIEW : ui_globals::curimage_view = SNAPSHOT_VIEW; @@ -2285,7 +2291,7 @@ void ui_menu_select_game::arts_render(void *selectedref, float origx1, float ori container->add_quad( x1, y1, x2, y2, ARGB_WHITE, snapx_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } } - else if (soft) + else if (soft != nullptr) { std::string fullname, pathname; diff --git a/src/emu/ui/selgame.h b/src/emu/ui/selgame.h index 4c1cf548d60..cf2fc8666ab 100644 --- a/src/emu/ui/selgame.h +++ b/src/emu/ui/selgame.h @@ -39,8 +39,8 @@ public: private: enum { VISIBLE_GAMES_IN_SEARCH = 200 }; char m_search[40]; - int m_prev_selected; - static int m_isabios; + static int m_isabios; + int highlight; static std::vector m_sortedlist; std::vector m_availsortedlist; @@ -73,6 +73,7 @@ private: void inkey_select_favorite(const ui_menu_event *menu_event); void inkey_special(const ui_menu_event *menu_event); void inkey_export(); + void inkey_configure(const ui_menu_event *menu_event); }; diff --git a/src/emu/ui/selsoft.cpp b/src/emu/ui/selsoft.cpp index 4cc43bbdb39..19ea982519a 100644 --- a/src/emu/ui/selsoft.cpp +++ b/src/emu/ui/selsoft.cpp @@ -126,6 +126,7 @@ ui_menu_select_software::ui_menu_select_software(running_machine &machine, rende reselect_last::set(false); sw_filters::actual = 0; + highlight = 0; m_driver = driver; build_software_list(); @@ -155,6 +156,9 @@ ui_menu_select_software::~ui_menu_select_software() void ui_menu_select_software::handle() { + if (m_prev_selected == nullptr) + m_prev_selected = item[0].ref; + bool check_filter = false; // ignore pause keys by swallowing them before we process the menu @@ -171,7 +175,18 @@ void ui_menu_select_software::handle() // handle selections else if (m_event->iptkey == IPT_UI_SELECT) - inkey_select(m_event); + { + if (m_focus == focused_menu::main) + { + inkey_select(m_event); + } + else if (m_focus == focused_menu::left) + { + l_sw_hover = highlight; + check_filter = true; + m_prev_selected = nullptr; + } + } // handle UI_LEFT else if (m_event->iptkey == IPT_UI_LEFT) @@ -225,20 +240,18 @@ void ui_menu_select_software::handle() } } - // handle UI_UP_FILTER - else if (m_event->iptkey == IPT_UI_UP_FILTER && sw_filters::actual > UI_SW_FIRST) +/* // handle UI_UP_FILTER + else if (m_event->iptkey == IPT_UI_UP_FILTER && highlight > UI_SW_FIRST) { - l_sw_hover = sw_filters::actual - 1; - check_filter = true; + highlight--; } // handle UI_DOWN_FILTER - else if (m_event->iptkey == IPT_UI_DOWN_FILTER && sw_filters::actual < UI_SW_LAST) + else if (m_event->iptkey == IPT_UI_DOWN_FILTER && highlight < UI_SW_LAST) { - l_sw_hover = sw_filters::actual + 1; - check_filter = true; + highlight++; } - +*/ // handle UI_LEFT_PANEL else if (m_event->iptkey == IPT_UI_LEFT_PANEL) ui_globals::rpanel = RP_IMAGES; @@ -280,31 +293,40 @@ void ui_menu_select_software::handle() inkey_special(m_event); else if (m_event->iptkey == IPT_OTHER) + { + highlight = l_sw_hover; check_filter = true; + m_prev_selected = nullptr; + } + + else if (m_event->iptkey == IPT_UI_CONFIGURE) + inkey_configure(m_event); } if (m_event != nullptr && m_event->itemref == nullptr) { - // reset the error on any future m_event - if (ui_error) - ui_error = false; - else if (m_event->iptkey == IPT_OTHER) - check_filter = true; + if (m_event->iptkey == IPT_UI_CONFIGURE) + inkey_configure(m_event); // handle UI_UP_FILTER - else if (m_event->iptkey == IPT_UI_UP_FILTER && sw_filters::actual > UI_SW_FIRST) + else if (m_event->iptkey == IPT_UI_UP_FILTER && highlight > UI_SW_FIRST) { - l_sw_hover = sw_filters::actual - 1; - check_filter = true; + highlight--; } // handle UI_DOWN_FILTER - else if (m_event->iptkey == IPT_UI_DOWN_FILTER && sw_filters::actual < UI_SW_LAST) + else if (m_event->iptkey == IPT_UI_DOWN_FILTER && highlight < UI_SW_LAST) { - l_sw_hover = sw_filters::actual + 1; - check_filter = true; + highlight++; } + else if (m_event->iptkey == IPT_UI_SELECT && m_focus == focused_menu::left) + { + l_sw_hover = highlight; + check_filter = true; + m_prev_selected = nullptr; + } + } // if we're in an error state, overlay an error message @@ -602,7 +624,7 @@ void ui_menu_select_software::build_software_list() void ui_menu_select_software::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) { - ui_software_info *swinfo = (ui_software_info *)selectedref; + ui_software_info *swinfo = (selectedref != nullptr) ? (ui_software_info *)selectedref : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr); const game_driver *driver = nullptr; ui_manager &mui = machine().ui(); float width; @@ -663,10 +685,10 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float } // determine the text to render below - if (swinfo && swinfo->startempty == 1) + if (swinfo != nullptr && swinfo->startempty == 1) driver = swinfo->driver; - if ((FPTR)driver > 1) + if (driver != nullptr) { isstar = machine().favorite().isgame_favorite(driver); @@ -716,7 +738,7 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float } - else if ((FPTR)swinfo > 1) + else if (swinfo != nullptr) { isstar = machine().favorite().isgame_favorite(*swinfo); @@ -920,6 +942,32 @@ void ui_menu_select_software::inkey_special(const ui_menu_event *m_event) } } +void ui_menu_select_software::inkey_configure(const ui_menu_event *m_event) +{ + if (selected <= visible_items && m_focus == focused_menu::main) + { + m_prev_selected = item[selected].ref; + selected = visible_items + 1; + } + else if (selected > visible_items && m_focus == focused_menu::main) + m_focus = focused_menu::left; + else if (m_focus == focused_menu::left) + { + m_focus = focused_menu::main; + if (m_prev_selected == nullptr) + { + selected = 0; + return; + } + + for (int x = 0; x < item.size(); ++x) + if (item[x].ref == m_prev_selected) + selected = x; + } + else if (m_focus == focused_menu::rightbottom) + m_focus = focused_menu::main; +} + //------------------------------------------------- // load custom filters info from file //------------------------------------------------- @@ -1317,14 +1365,15 @@ float ui_menu_select_software::draw_left_panel(float x1, float y1, float x2, flo hover = phover + filter; } -/* if (afilter == filter) - { - bgcolor = UI_SELECTED_BG_COLOR; - fgcolor = UI_SELECTED_COLOR; - } -*/ + if (highlight == filter && m_focus == focused_menu::left) + { + fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00); + bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff); + } + if (bgcolor != UI_TEXT_BG_COLOR) - container->add_rect(x1, y1, x2, y1 + line_height, bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); + mui.draw_textured_box(container, x1, y1, x2, y1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), + hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); float x1t = x1 + text_sign; if (afilter == UI_SW_CUSTOM) @@ -1351,7 +1400,7 @@ float ui_menu_select_software::draw_left_panel(float x1, float y1, float x2, flo } else if (filter == sw_filters::actual) { - str.assign("@custom1 ").append(text[filter]); + str.assign("_> ").append(text[filter]); x1t -= text_sign; convert_command_glyph(str); } @@ -1425,7 +1474,8 @@ void ui_menu_select_software::infos_render(void *selectedref, float origx1, floa std::vector xstart; std::vector xend; float text_size = machine().ui().options().infos_size(); - ui_software_info *soft = (ui_software_info *)selectedref; +// ui_software_info *soft = (ui_software_info *)selectedref; + ui_software_info *soft = (selectedref != nullptr) ? (ui_software_info *)selectedref : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr); static ui_software_info *oldsoft = nullptr; static int old_sw_view = -1; @@ -1434,7 +1484,7 @@ void ui_menu_select_software::infos_render(void *selectedref, float origx1, floa float oy1 = origy1 + line_height; // apply title to right panel - if (soft && soft->usage.empty()) + if (soft != nullptr && soft->usage.empty()) { mui.draw_text_full(container, _("History"), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); @@ -1530,9 +1580,10 @@ void ui_menu_select_software::arts_render(void *selectedref, float origx1, float static ui_software_info *oldsoft = nullptr; static const game_driver *olddriver = nullptr; const game_driver *driver = nullptr; - ui_software_info *soft = (ui_software_info *)selectedref; + ui_software_info *soft = (selectedref != nullptr) ? (ui_software_info *)selectedref : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr); +// ui_software_info *soft = (ui_software_info *)selectedref; - if (soft && soft->startempty == 1) + if (soft != nullptr && soft->startempty == 1) { driver = soft->driver; oldsoft = nullptr; @@ -1540,7 +1591,7 @@ void ui_menu_select_software::arts_render(void *selectedref, float origx1, float else olddriver = nullptr; - if (driver) + if (driver != nullptr) { if (ui_globals::default_image) ((driver->flags & MACHINE_TYPE_ARCADE) == 0) ? ui_globals::curimage_view = CABINETS_VIEW : ui_globals::curimage_view = SNAPSHOT_VIEW; @@ -1618,7 +1669,7 @@ void ui_menu_select_software::arts_render(void *selectedref, float origx1, float container->add_quad( x1, y1, x2, y2, ARGB_WHITE, snapx_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } } - else if (soft) + else if (soft != nullptr) { std::string fullname, pathname; if (ui_globals::default_image) diff --git a/src/emu/ui/selsoft.h b/src/emu/ui/selsoft.h index 8f7e6d413c8..290b96d5320 100644 --- a/src/emu/ui/selsoft.h +++ b/src/emu/ui/selsoft.h @@ -45,6 +45,7 @@ private: const game_driver *m_driver; bool m_has_empty_start; s_filter m_filter; + int highlight; ui_software_info *m_searchlist[VISIBLE_GAMES_IN_SEARCH + 1]; std::vector m_displaylist, m_tmp, m_sortedlist; @@ -62,6 +63,7 @@ private: // handlers void inkey_select(const ui_menu_event *menu_event); void inkey_special(const ui_menu_event *menu_event); + void inkey_configure(const ui_menu_event *menu_event); }; class ui_software_parts : public ui_menu