fix drawing software art/info when keyboard focus leaves list,

consolidate more logic, more code deduplication, fix gutters on dats
view, fix fallthrough from dats to save

there's some weirdness with shortcust for dats/export/favourite toggle
if they result in a character being typed
This commit is contained in:
Vas Crabb 2017-08-11 13:12:06 +10:00
parent c02fb9b802
commit 14d9e1f35a
8 changed files with 228 additions and 226 deletions

View File

@ -64,7 +64,7 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container
// ctor
//-------------------------------------------------
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, ui_software_info *swinfo, const game_driver *driver)
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_software_info *swinfo, const game_driver *driver)
: menu(mui, container)
, m_actual(0)
, m_driver((driver == nullptr) ? &mui.machine().system() : driver)
@ -149,20 +149,20 @@ void menu_dats_view::populate(float &customtop, float &custombottom)
void menu_dats_view::draw(uint32_t flags)
{
auto line_height = ui().get_line_height();
auto ud_arrow_width = line_height * machine().render().ui_aspect();
auto gutter_width = 0.52f * line_height * machine().render().ui_aspect();
float visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER;
float visible_left = (1.0f - visible_width) * 0.5f;
float const line_height = ui().get_line_height();
float const ud_arrow_width = line_height * machine().render().ui_aspect();
float const gutter_width = 0.52f * line_height * machine().render().ui_aspect();
float const visible_width = 1.0f - (2.0f * UI_BOX_LR_BORDER);
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;
int const visible_items = item.size() - 2;
// 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();
hover = item.size() + 1;
int visible_items = item.size() - 2;
float extra_height = 2.0f * line_height;
float visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
// locate mouse
map_mouse();
// account for extra space at the top and bottom
@ -170,11 +170,8 @@ void menu_dats_view::draw(uint32_t flags)
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
float visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;
// if the menu is at the bottom of the extra, adjust
visible_top += get_customtop();
// 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 left box size
float x1 = visible_left;
@ -190,27 +187,25 @@ void menu_dats_view::draw(uint32_t flags)
if (top_line + m_visible_lines >= visible_items)
top_line = visible_items - m_visible_lines;
// determine effective positions taking into account the hilighting arrows
float effective_width = visible_width - 2.0f * gutter_width;
float effective_left = visible_left + gutter_width;
hover = item.size() + 1;
int const n_loop = (std::min)(visible_items, m_visible_lines);
for (int linenum = 0; linenum < n_loop; linenum++)
{
float line_y = visible_top + (float)linenum * line_height;
int itemnum = top_line + linenum;
const menu_item &pitem = item[itemnum];
const char *itemtext = pitem.text.c_str();
float const line_y = visible_top + (float)linenum * line_height;
int const itemnum = top_line + linenum;
menu_item const &pitem = item[itemnum];
char const *const itemtext = pitem.text.c_str();
float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float const line_y0 = line_y;
float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
float const line_y1 = line_y + line_height;
rgb_t fgcolor = UI_TEXT_COLOR;
rgb_t bgcolor = UI_TEXT_BG_COLOR;
float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float line_y0 = line_y;
float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
float line_y1 = line_y + line_height;
// if we're on the top line, display the up arrow
if (linenum == 0 && top_line != 0)
if (!linenum && top_line)
{
// if we're on the top line, display the up arrow
if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1))
{
fgcolor = UI_MOUSEOVER_COLOR;
@ -218,14 +213,14 @@ void menu_dats_view::draw(uint32_t flags)
highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
hover = HOVER_ARROW_UP;
}
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);
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);
}
// if we're on the bottom line, display the down arrow
else if (linenum == m_visible_lines - 1 && itemnum != visible_items - 1)
else if ((linenum == m_visible_lines - 1) && (itemnum != visible_items - 1))
{
// if we're on the bottom line, display the down arrow
if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1))
{
fgcolor = UI_MOUSEOVER_COLOR;
@ -233,41 +228,52 @@ void menu_dats_view::draw(uint32_t flags)
highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
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_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 dats text
else if (pitem.subtext.empty())
{
ui().draw_text_full(container(), itemtext, effective_left, line_y, effective_width, ui::text_layout::LEFT, ui::text_layout::NEVER,
mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
// draw dats text
ui().draw_text_full(
container(), itemtext,
effective_left, line_y, effective_width,
ui::text_layout::LEFT, ui::text_layout::NEVER,
mame_ui_manager::NORMAL, fgcolor, bgcolor,
nullptr, nullptr);
}
}
for (size_t count = visible_items; count < item.size(); count++)
{
const menu_item &pitem = item[count];
const char *itemtext = pitem.text.c_str();
float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float line_y0 = line;
float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
float line_y1 = line + line_height;
rgb_t fgcolor = UI_SELECTED_COLOR;
rgb_t bgcolor = UI_SELECTED_BG_COLOR;
menu_item const &pitem = item[count];
char const *const itemtext = pitem.text.c_str();
float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float const line_y0 = line;
float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
float const line_y1 = line + line_height;
rgb_t const fgcolor = UI_SELECTED_COLOR;
rgb_t const bgcolor = UI_SELECTED_BG_COLOR;
if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
hover = count;
if (pitem.type == menu_item_type::SEPARATOR)
container().add_line(visible_left, line + 0.5f * line_height, visible_left + visible_width, line + 0.5f * line_height,
UI_LINE_WIDTH, UI_TEXT_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
{
container().add_line(
visible_left, line + 0.5f * line_height, visible_left + visible_width, line + 0.5f * line_height,
UI_LINE_WIDTH, UI_TEXT_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
else
{
highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
ui().draw_text_full(container(), itemtext, effective_left, line, effective_width, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
ui().draw_text_full(
container(), itemtext,
effective_left, line, effective_width,
ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NORMAL, fgcolor, bgcolor,
nullptr, nullptr);
}
line += line_height;
}
@ -387,14 +393,17 @@ void menu_dats_view::get_data()
std::string buffer;
mame_machine_manager::instance()->lua()->call_plugin("data", m_items_list[m_actual].option, buffer);
float const line_height = ui().get_line_height();
float const gutter_width = 0.52f * line_height * machine().render().ui_aspect();
float const visible_width = 1.0f - (2.0f * UI_BOX_LR_BORDER);
float const effective_width = visible_width - 2.0f * gutter_width;
auto lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, 1.0f - (4.0f * UI_BOX_LR_BORDER), xstart, xend);
auto lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, effective_width, xstart, xend);
for (int x = 0; x < lines; ++x)
{
std::string tempbuf(buffer.substr(xstart[x], xend[x] - xstart[x]));
if((tempbuf[0] == '#') && !x)
continue;
item_append(tempbuf, "", (FLAG_UI_DATS | FLAG_DISABLE), (void *)(uintptr_t)(x + 1));
if ((tempbuf[0] != '#') || x)
item_append(tempbuf, "", (FLAG_UI_DATS | FLAG_DISABLE), (void *)(uintptr_t)(x + 1));
}
}

View File

@ -31,7 +31,7 @@ namespace ui {
class menu_dats_view : public menu
{
public:
menu_dats_view(mame_ui_manager &mui, render_container &container, ui_software_info *swinfo, const game_driver *driver = nullptr);
menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_software_info *swinfo, const game_driver *driver = nullptr);
menu_dats_view(mame_ui_manager &mui, render_container &container, const game_driver *driver = nullptr);
virtual ~menu_dats_view() override;
@ -47,7 +47,7 @@ private:
int m_actual;
const game_driver *m_driver;
ui_software_info *m_swinfo;
const ui_software_info *m_swinfo;
std::string m_list, m_short, m_long, m_parent;
void get_data();
void get_data_sw();

View File

@ -14,7 +14,6 @@
#include "ui/ui.h"
#include "ui/miscmenu.h"
#include "ui/inifile.h"
#include "ui/datmenu.h"
#include "ui/optsmenu.h"
#include "ui/selector.h"
#include "ui/selsoft.h"
@ -48,7 +47,6 @@ int menu_select_game::m_isabios = 0;
menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &container, const char *gamename)
: menu_select_launch(mui, container, false)
{
highlight = 0;
std::string error_string, last_filter, sub_filter;
ui_options &moptions = mui.options();
@ -106,6 +104,7 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta
// do this after processing the last used filter setting so it overwrites the placeholder
load_custom_filters();
m_filter_highlight = main_filters::actual;
if (!moptions.remember_last())
reselect_last::reset();
@ -192,7 +191,6 @@ void menu_select_game::handle()
machine().ui_input().pressed(IPT_UI_PAUSE);
// process the menu
bool check_filter(false);
const event *menu_event = process(PROCESS_LR_REPEAT);
if (menu_event)
{
@ -203,37 +201,37 @@ void menu_select_game::handle()
else switch (menu_event->iptkey)
{
case IPT_UI_UP:
if ((get_focus() == focused_menu::LEFT) && (machine_filter::FIRST < highlight))
--highlight;
if ((get_focus() == focused_menu::LEFT) && (machine_filter::FIRST < m_filter_highlight))
--m_filter_highlight;
break;
case IPT_UI_DOWN:
if ((get_focus() == focused_menu::LEFT) && (machine_filter::LAST > highlight))
highlight++;
if ((get_focus() == focused_menu::LEFT) && (machine_filter::LAST > m_filter_highlight))
m_filter_highlight++;
break;
case IPT_UI_HOME:
if (get_focus() == focused_menu::LEFT)
highlight = machine_filter::FIRST;
m_filter_highlight = machine_filter::FIRST;
break;
case IPT_UI_END:
if (get_focus() == focused_menu::LEFT)
highlight = machine_filter::LAST;
break;
case IPT_OTHER:
// this is generated when something in the left box is clicked
m_prev_selected = nullptr;
check_filter = true;
highlight = hover - HOVER_FILTER_FIRST;
assert((machine_filter::FIRST <= highlight) && (machine_filter::LAST >= highlight));
m_filter_highlight = machine_filter::LAST;
break;
case IPT_UI_CONFIGURE:
inkey_navigation();
break;
case IPT_UI_EXPORT:
inkey_export();
break;
case IPT_UI_DATS:
inkey_dats();
break;
default:
if (menu_event->itemref)
{
@ -247,11 +245,6 @@ void menu_select_game::handle()
else
inkey_select(menu_event);
}
else if (get_focus() == focused_menu::LEFT)
{
check_filter = true;
m_prev_selected = nullptr;
}
break;
case IPT_CUSTOM:
@ -303,26 +296,6 @@ void menu_select_game::handle()
}
break;
case IPT_UI_DATS:
if (!isfavorite())
{
const game_driver *driver = (const game_driver *)menu_event->itemref;
if ((uintptr_t)driver > skip_main_items && mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", driver->name, true))
menu::stack_push<menu_dats_view>(ui(), container(), driver);
}
else
{
ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref;
if ((uintptr_t)ui_swinfo > skip_main_items)
{
if (ui_swinfo->startempty == 1 && mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", ui_swinfo->driver->name, true))
menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo->driver);
else if (mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", std::string(ui_swinfo->shortname).append(1, ',').append(ui_swinfo->listname).c_str()) || !ui_swinfo->usage.empty())
menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo);
}
}
case IPT_UI_FAVORITES:
if (uintptr_t(menu_event->itemref) > skip_main_items)
{
@ -351,10 +324,6 @@ void menu_select_game::handle()
}
break;
case IPT_UI_EXPORT:
inkey_export();
break;
case IPT_UI_AUDIT_FAST:
if (!m_unavailsortedlist.empty())
menu::stack_push<menu_audit>(ui(), container(), m_availsortedlist, m_unavailsortedlist, 1);
@ -370,36 +339,6 @@ void menu_select_game::handle()
// if we're in an error state, overlay an error message
draw_error_text();
// handle filters selection from key shortcuts
if (check_filter)
{
m_search.clear();
if ((machine_filter::FIRST <= highlight) && (machine_filter::LAST >= highlight))
{
auto it(main_filters::filters.find(machine_filter::type(highlight)));
if (main_filters::filters.end() == it)
it = main_filters::filters.emplace(machine_filter::type(highlight), machine_filter::create(machine_filter::type(highlight))).first;
it->second->show_ui(
ui(),
container(),
[this] (machine_filter &filter)
{
machine_filter::type const new_type(filter.get_type());
if (machine_filter::CUSTOM == new_type)
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == osd_file::error::NONE)
{
filter.save_ini(file, 0);
file.close();
}
}
main_filters::actual = new_type;
reset(reset_options::SELECT_FIRST);
});
}
}
}
//-------------------------------------------------
@ -1210,7 +1149,7 @@ void menu_select_game::load_custom_filters()
float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2)
{
return menu_select_launch::draw_left_panel<machine_filter>(main_filters::actual, main_filters::filters, highlight, x1, y1, x2, y2);
return menu_select_launch::draw_left_panel<machine_filter>(main_filters::actual, main_filters::filters, x1, y1, x2, y2);
}
@ -1273,6 +1212,36 @@ std::string menu_select_game::make_software_description(ui_software_info const &
}
void menu_select_game::filter_selected()
{
if ((machine_filter::FIRST <= m_filter_highlight) && (machine_filter::LAST >= m_filter_highlight))
{
m_search.clear();
auto it(main_filters::filters.find(machine_filter::type(m_filter_highlight)));
if (main_filters::filters.end() == it)
it = main_filters::filters.emplace(machine_filter::type(m_filter_highlight), machine_filter::create(machine_filter::type(m_filter_highlight))).first;
it->second->show_ui(
ui(),
container(),
[this] (machine_filter &filter)
{
machine_filter::type const new_type(filter.get_type());
if (machine_filter::CUSTOM == new_type)
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == osd_file::error::NONE)
{
filter.save_ini(file, 0);
file.close();
}
}
main_filters::actual = new_type;
reset(reset_options::SELECT_FIRST);
});
}
}
std::string menu_select_game::make_error_text(bool summary, media_auditor const &auditor)
{
std::ostringstream str;

View File

@ -39,7 +39,6 @@ private:
enum { VISIBLE_GAMES_IN_SEARCH = 200 };
static bool first_start;
static int m_isabios;
int highlight;
static std::vector<const game_driver *> m_sortedlist;
std::vector<const game_driver *> m_availsortedlist;
@ -63,6 +62,12 @@ private:
virtual std::string make_driver_description(game_driver const &driver) const override;
virtual std::string make_software_description(ui_software_info const &software) const override;
// filter navigation
virtual void filter_selected() override;
// toolbar
virtual void inkey_export() override;
// internal methods
void change_info_pane(int delta);
@ -76,19 +81,12 @@ private:
static std::string make_error_text(bool summary, media_auditor const &auditor);
void *get_selection_ptr() const
{
void *const selected_ref(get_selection_ref());
return (uintptr_t(selected_ref) > skip_main_items) ? selected_ref : m_prev_selected;
}
// General info
virtual void general_info(const game_driver *driver, std::string &buffer) override;
// handlers
void inkey_select(const event *menu_event);
void inkey_select_favorite(const event *menu_event);
void inkey_export();
};
} // namespace ui

View File

@ -11,6 +11,7 @@
#include "emu.h"
#include "ui/selmenu.h"
#include "ui/datmenu.h"
#include "ui/icorender.h"
#include "ui/info.h"
#include "ui/inifile.h"
@ -137,8 +138,8 @@ char const *const menu_select_launch::s_info_titles[] = {
// instantiate possible variants of these so derived classes don't get link errors
template bool menu_select_launch::select_bios(game_driver const &, bool);
template bool menu_select_launch::select_bios(ui_software_info const &, bool);
template float menu_select_launch::draw_left_panel<machine_filter>(machine_filter::type current, std::map<machine_filter::type, machine_filter::ptr> const &filters, int focus, float x1, float y1, float x2, float y2);
template float menu_select_launch::draw_left_panel<software_filter>(software_filter::type current, std::map<software_filter::type, software_filter::ptr> const &filters, int focus, float x1, float y1, float x2, float y2);
template float menu_select_launch::draw_left_panel<machine_filter>(machine_filter::type current, std::map<machine_filter::type, machine_filter::ptr> const &filters, float x1, float y1, float x2, float y2);
template float menu_select_launch::draw_left_panel<software_filter>(software_filter::type current, std::map<software_filter::type, software_filter::ptr> const &filters, float x1, float y1, float x2, float y2);
menu_select_launch::system_flags::system_flags(machine_static_info const &info)
@ -437,6 +438,7 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c
, m_prev_selected(nullptr)
, m_total_lines(0)
, m_topline_datsview(0)
, m_filter_highlight(0)
, m_ui_error(false)
, m_info_driver(nullptr)
, m_info_software(nullptr)
@ -731,6 +733,26 @@ void menu_select_launch::inkey_navigation()
}
void menu_select_launch::inkey_dats()
{
ui_software_info const *software;
game_driver const *driver;
get_selection(software, driver);
if (software)
{
if (software->startempty && mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", software->driver->name, true))
menu::stack_push<menu_dats_view>(ui(), container(), software->driver);
else if (mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", std::string(software->shortname).append(1, ',').append(software->listname).c_str()) || !software->usage.empty())
menu::stack_push<menu_dats_view>(ui(), container(), software);
}
else if (driver)
{
if (mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", driver->name, true))
menu::stack_push<menu_dats_view>(ui(), container(), driver);
}
}
//-------------------------------------------------
// draw common arrows
//-------------------------------------------------
@ -820,7 +842,6 @@ template <typename Filter>
float menu_select_launch::draw_left_panel(
typename Filter::type current,
std::map<typename Filter::type, typename Filter::ptr> const &filters,
int focus,
float x1, float y1, float x2, float y2)
{
if ((ui_globals::panels_status != SHOW_PANELS) && (ui_globals::panels_status != HIDE_RIGHT_PANEL))
@ -888,7 +909,7 @@ float menu_select_launch::draw_left_panel(
}
// draw primary highlight if keyboard focus is here
if ((focus == filter) && (get_focus() == focused_menu::LEFT))
if ((m_filter_highlight == filter) && (get_focus() == focused_menu::LEFT))
{
fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
@ -1222,7 +1243,16 @@ void menu_select_launch::handle_keys(uint32_t flags, int &iptkey)
// if we hit select, return true or pop the stack, depending on the item
if (exclusive_input_pressed(iptkey, IPT_UI_SELECT, 0))
{
if (is_last_selected() && m_focus == focused_menu::MAIN)
if (m_ui_error)
{
// dismiss error
}
else if (m_focus == focused_menu::LEFT)
{
m_prev_selected = nullptr;
filter_selected();
}
if (is_last_selected() && (m_focus == focused_menu::MAIN))
{
iptkey = IPT_UI_CANCEL;
stack_pop();
@ -1527,12 +1557,12 @@ void menu_select_launch::handle_events(uint32_t flags, event &ev)
}
else if (hover == HOVER_B_EXPORT)
{
ev.iptkey = IPT_UI_EXPORT;
inkey_export();
stop = true;
}
else if (hover == HOVER_B_DATS)
{
ev.iptkey = IPT_UI_DATS;
inkey_dats();
stop = true;
}
else if (hover >= HOVER_RP_FIRST && hover <= HOVER_RP_LAST)
@ -1542,7 +1572,9 @@ void menu_select_launch::handle_events(uint32_t flags, event &ev)
}
else if (hover >= HOVER_FILTER_FIRST && hover <= HOVER_FILTER_LAST)
{
ev.iptkey = IPT_OTHER;
m_prev_selected = nullptr;
m_filter_highlight = hover - HOVER_FILTER_FIRST;
filter_selected();
stop = true;
}
}

View File

@ -107,6 +107,8 @@ protected:
// handlers
void inkey_navigation();
virtual void inkey_export() = 0;
void inkey_dats();
// draw arrow
void draw_common_arrow(float origx1, float origy1, float origx2, float origy2, int current, int dmin, int dmax, float title);
@ -118,16 +120,22 @@ protected:
float draw_left_panel(
typename Filter::type current,
std::map<typename Filter::type, typename Filter::ptr> const &filters,
int focus,
float x1, float y1, float x2, float y2);
template <typename T> bool select_bios(T const &driver, bool inlist);
bool select_part(software_info const &info, ui_software_info const &ui_info);
void *get_selection_ptr() const
{
void *const selected_ref(get_selection_ref());
return (uintptr_t(selected_ref) > skip_main_items) ? selected_ref : m_prev_selected;
}
int visible_items;
void *m_prev_selected;
int m_total_lines;
int m_topline_datsview; // right box top line
int m_topline_datsview;
int m_filter_highlight;
std::string m_search;
static char const *const s_info_titles[];
@ -255,6 +263,9 @@ private:
virtual std::string make_driver_description(game_driver const &driver) const = 0;
virtual std::string make_software_description(ui_software_info const &software) const = 0;
// filter navigation
virtual void filter_selected() = 0;
static void launch_system(mame_ui_manager &mui, game_driver const &driver, ui_software_info const *swinfo, std::string const *part, int const *bios);
static bool select_part(mame_ui_manager &mui, render_container &container, software_info const &info, ui_software_info const &ui_info);
static bool has_multiple_bios(ui_software_info const &swinfo, s_bios &biosname);

View File

@ -12,7 +12,6 @@
#include "ui/selsoft.h"
#include "ui/ui.h"
#include "ui/datmenu.h"
#include "ui/inifile.h"
#include "ui/selector.h"
@ -87,11 +86,10 @@ menu_select_software::menu_select_software(mame_ui_manager &mui, render_containe
{
reselect_last::reselect(false);
highlight = 0;
m_driver = driver;
build_software_list();
load_sw_custom_filters();
m_filter_highlight = m_filter_type;
ui_globals::curimage_view = SNAPSHOT_VIEW;
ui_globals::switch_image = true;
@ -122,7 +120,6 @@ void menu_select_software::handle()
machine().ui_input().pressed(IPT_UI_PAUSE);
// process the menu
bool check_filter(false);
const event *menu_event = process(PROCESS_LR_REPEAT);
if (menu_event)
{
@ -133,15 +130,8 @@ void menu_select_software::handle()
else switch (menu_event->iptkey)
{
case IPT_UI_SELECT:
if (get_focus() == focused_menu::LEFT)
{
check_filter = true;
m_prev_selected = nullptr;
}
else if ((get_focus() == focused_menu::MAIN) && menu_event->itemref)
{
if ((get_focus() == focused_menu::MAIN) && menu_event->itemref)
inkey_select(menu_event);
}
break;
case IPT_UI_LEFT:
@ -177,51 +167,37 @@ void menu_select_software::handle()
break;
case IPT_UI_UP:
if ((get_focus() == focused_menu::LEFT) && (software_filter::FIRST < highlight))
--highlight;
if ((get_focus() == focused_menu::LEFT) && (software_filter::FIRST < m_filter_highlight))
--m_filter_highlight;
break;
case IPT_UI_DOWN:
if ((get_focus() == focused_menu::LEFT) && (software_filter::LAST > highlight))
++highlight;
if ((get_focus() == focused_menu::LEFT) && (software_filter::LAST > m_filter_highlight))
++m_filter_highlight;
break;
case IPT_UI_HOME:
if (get_focus() == focused_menu::LEFT)
highlight = software_filter::FIRST;
m_filter_highlight = software_filter::FIRST;
break;
case IPT_UI_END:
if (get_focus() == focused_menu::LEFT)
highlight = software_filter::LAST;
break;
case IPT_OTHER:
// this is generated when something in the left box is clicked
check_filter = true;
highlight = hover - HOVER_FILTER_FIRST;
assert((software_filter::FIRST <= highlight) && (software_filter::LAST >= highlight));
m_prev_selected = nullptr;
m_filter_highlight = software_filter::LAST;
break;
case IPT_UI_CONFIGURE:
inkey_navigation();
break;
case IPT_UI_DATS:
inkey_dats();
break;
default:
if (menu_event->itemref)
{
if (menu_event->iptkey == IPT_UI_DATS)
{
// handle UI_DATS
ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref;
if (ui_swinfo->startempty == 1 && mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", ui_swinfo->driver->name, true))
menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo->driver);
else if (mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", std::string(ui_swinfo->shortname).append(1, ',').append(ui_swinfo->listname).c_str()) || !ui_swinfo->usage.empty())
menu::stack_push<menu_dats_view>(ui(), container(), ui_swinfo);
}
else if (menu_event->iptkey == IPT_UI_FAVORITES)
if (menu_event->iptkey == IPT_UI_FAVORITES)
{
// handle UI_FAVORITES
ui_software_info *swinfo = (ui_software_info *)menu_event->itemref;
@ -248,34 +224,6 @@ void menu_select_software::handle()
// if we're in an error state, overlay an error message
draw_error_text();
// handle filters selection from key shortcuts
if (check_filter)
{
m_search.clear();
filter_map::const_iterator it(m_filters.find(software_filter::type(highlight)));
if (m_filters.end() == it)
it = m_filters.emplace(software_filter::type(highlight), software_filter::create(software_filter::type(highlight), m_filter_data)).first;
it->second->show_ui(
ui(),
container(),
[this, driver = m_driver] (software_filter &filter)
{
software_filter::type const new_type(filter.get_type());
if (software_filter::CUSTOM == new_type)
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
if (file.open("custom_", driver->name, "_filter.ini") == osd_file::error::NONE)
{
filter.save_ini(file, 0);
file.close();
}
}
m_filter_type = new_type;
reset(reset_options::SELECT_FIRST);
});
}
}
//-------------------------------------------------
@ -583,7 +531,7 @@ void menu_select_software::find_matches(const char *str, int count)
float menu_select_software::draw_left_panel(float x1, float y1, float x2, float y2)
{
return menu_select_launch::draw_left_panel<software_filter>(m_filter_type, m_filters, highlight, x1, y1, x2, y2);
return menu_select_launch::draw_left_panel<software_filter>(m_filter_type, m_filters, x1, y1, x2, y2);
}
@ -593,7 +541,7 @@ float menu_select_software::draw_left_panel(float x1, float y1, float x2, float
void menu_select_software::get_selection(ui_software_info const *&software, game_driver const *&driver) const
{
software = reinterpret_cast<ui_software_info const *>(get_selection_ref());
software = reinterpret_cast<ui_software_info const *>(get_selection_ptr());
driver = software ? software->driver : nullptr;
}
@ -627,4 +575,34 @@ std::string menu_select_software::make_software_description(ui_software_info con
return string_format(_("%1$-.100s"), software.longname);
}
void menu_select_software::filter_selected()
{
if ((software_filter::FIRST <= m_filter_highlight) && (software_filter::LAST >= m_filter_highlight))
{
m_search.clear();
filter_map::const_iterator it(m_filters.find(software_filter::type(m_filter_highlight)));
if (m_filters.end() == it)
it = m_filters.emplace(software_filter::type(m_filter_highlight), software_filter::create(software_filter::type(m_filter_highlight), m_filter_data)).first;
it->second->show_ui(
ui(),
container(),
[this, driver = m_driver] (software_filter &filter)
{
software_filter::type const new_type(filter.get_type());
if (software_filter::CUSTOM == new_type)
{
emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
if (file.open("custom_", driver->name, "_filter.ini") == osd_file::error::NONE)
{
filter.save_ini(file, 0);
file.close();
}
}
m_filter_type = new_type;
reset(reset_options::SELECT_FIRST);
});
}
}
} // namespace ui

View File

@ -36,7 +36,6 @@ private:
s_filter m_filter_data;
filter_map m_filters;
software_filter::type m_filter_type;
int highlight;
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
@ -52,6 +51,12 @@ private:
virtual std::string make_driver_description(game_driver const &driver) const override;
virtual std::string make_software_description(ui_software_info const &software) const override;
// filter navigation
virtual void filter_selected() override;
// toolbar
virtual void inkey_export() override { throw false; }
ui_software_info *m_searchlist[VISIBLE_GAMES_IN_SEARCH + 1];
std::vector<ui_software_info *> m_displaylist, m_tmp, m_sortedlist;
std::vector<ui_software_info> m_swinfo;