mirror of
https://github.com/holub/mame
synced 2025-07-01 16:19:38 +03:00
UI code refactoring: [Vas Crabb]
* Split out main menu and dat box drawing from base class * Make a bunch of class statics proper per-machine persistent objects * Object lifecycle fixes
This commit is contained in:
parent
2364b48f0d
commit
1abf53ca6a
@ -110,6 +110,8 @@ files {
|
||||
MAME_DIR .. "src/frontend/mame/ui/info_pty.h",
|
||||
MAME_DIR .. "src/frontend/mame/ui/inputmap.cpp",
|
||||
MAME_DIR .. "src/frontend/mame/ui/inputmap.h",
|
||||
MAME_DIR .. "src/frontend/mame/ui/selmenu.cpp",
|
||||
MAME_DIR .. "src/frontend/mame/ui/selmenu.h",
|
||||
MAME_DIR .. "src/frontend/mame/ui/sliders.cpp",
|
||||
MAME_DIR .. "src/frontend/mame/ui/sliders.h",
|
||||
MAME_DIR .. "src/frontend/mame/ui/slotopt.cpp",
|
||||
|
@ -159,7 +159,7 @@ void menu_audit::handle()
|
||||
std::stable_sort(m_unavailablesorted.begin(), m_unavailablesorted.end(), sorted_game_list);
|
||||
save_available_machines();
|
||||
reset_parent(reset_options::SELECT_FIRST);
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -1045,7 +1045,7 @@ void menu_palette_sel::handle()
|
||||
{
|
||||
m_original = rgb_t((UINT32)strtoul(item[selected].subtext.c_str(), nullptr, 16));
|
||||
reset_parent(reset_options::SELECT_FIRST);
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,10 @@
|
||||
#include "mame.h"
|
||||
#include "rendfont.h"
|
||||
#include "softlist.h"
|
||||
#include "uiinput.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
namespace ui {
|
||||
//-------------------------------------------------
|
||||
@ -118,6 +122,147 @@ void menu_dats_view::populate()
|
||||
machine().resume();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// draw - draw dats menu
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_dats_view::draw(UINT32 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();
|
||||
mouse_x = -1, mouse_y = -1;
|
||||
float visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER;
|
||||
float visible_left = (1.0f - visible_width) * 0.5f;
|
||||
|
||||
draw_background();
|
||||
|
||||
hover = item.size() + 1;
|
||||
visible_items = item.size() - 2;
|
||||
float extra_height = 2.0f * line_height;
|
||||
float visible_extra_menu_height = customtop + custombottom + extra_height;
|
||||
|
||||
// locate mouse
|
||||
mouse_hit = false;
|
||||
mouse_button = false;
|
||||
mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
|
||||
if (mouse_target != nullptr)
|
||||
if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y))
|
||||
mouse_hit = true;
|
||||
|
||||
// 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
|
||||
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 += customtop;
|
||||
|
||||
// compute left box size
|
||||
float x1 = visible_left;
|
||||
float y1 = visible_top - UI_BOX_TB_BORDER;
|
||||
float x2 = x1 + visible_width;
|
||||
float y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER + extra_height;
|
||||
float line = visible_top + float(m_visible_lines) * line_height;
|
||||
|
||||
ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
|
||||
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();
|
||||
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)
|
||||
{
|
||||
draw_arrow(container, 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 (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y)
|
||||
{
|
||||
fgcolor = UI_MOUSEOVER_COLOR;
|
||||
bgcolor = UI_MOUSEOVER_BG_COLOR;
|
||||
highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
|
||||
hover = HOVER_ARROW_UP;
|
||||
}
|
||||
}
|
||||
// if we're on the bottom line, display the down arrow
|
||||
else if (linenum == m_visible_lines - 1 && itemnum != visible_items - 1)
|
||||
{
|
||||
draw_arrow(container, 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);
|
||||
|
||||
if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y)
|
||||
{
|
||||
fgcolor = UI_MOUSEOVER_COLOR;
|
||||
bgcolor = UI_MOUSEOVER_BG_COLOR;
|
||||
highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
|
||||
hover = HOVER_ARROW_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && 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));
|
||||
else
|
||||
{
|
||||
highlight(container, 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);
|
||||
}
|
||||
line += line_height;
|
||||
}
|
||||
|
||||
// if there is something special to add, do it by calling the virtual method
|
||||
custom_render(get_selection_ref(), customtop, custombottom, x1, y1, x2, y2);
|
||||
|
||||
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
m_visible_items = m_visible_lines - (top_line != 0) - (top_line + m_visible_lines != visible_items);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// perform our special rendering
|
||||
//-------------------------------------------------
|
||||
|
@ -38,6 +38,10 @@ public:
|
||||
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
|
||||
|
||||
private:
|
||||
// draw dats menu
|
||||
virtual void draw(UINT32 flags) override;
|
||||
|
||||
int visible_items;
|
||||
int m_actual;
|
||||
const game_driver *m_driver;
|
||||
ui_software_info *m_swinfo;
|
||||
|
@ -392,7 +392,7 @@ void menu_add_change_folder::handle()
|
||||
}
|
||||
|
||||
reset_parent(reset_options::SELECT_FIRST);
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
else if (menu_event->is_char_printable())
|
||||
{
|
||||
@ -614,7 +614,7 @@ void menu_remove_folder::handle()
|
||||
}
|
||||
|
||||
reset_parent(reset_options::REMEMBER_REF);
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ void menu_confirm_save_as::handle()
|
||||
*m_yes = true;
|
||||
|
||||
// no matter what, pop out
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +238,7 @@ void menu_file_create::handle()
|
||||
if (tmp_file.find(".") != -1 && tmp_file.find(".") < tmp_file.length() - 1)
|
||||
{
|
||||
m_current_file = m_filename;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
else
|
||||
ui().popup_time(1, "%s", _("Please enter a file extension too"));
|
||||
@ -316,7 +316,7 @@ void menu_select_format::handle()
|
||||
if (event != nullptr && event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
*m_result = int(FPTR(event->itemref));
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,18 +392,18 @@ void menu_file_selector::handle()
|
||||
case SELECTOR_ENTRY_TYPE_EMPTY:
|
||||
// empty slot - unload
|
||||
m_result = result::EMPTY;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case SELECTOR_ENTRY_TYPE_CREATE:
|
||||
// create
|
||||
m_result = result::CREATE;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST:
|
||||
m_result = result::SOFTLIST;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case SELECTOR_ENTRY_TYPE_DRIVE:
|
||||
@ -424,7 +424,7 @@ void menu_file_selector::handle()
|
||||
// file
|
||||
m_current_file.assign(entry->fullpath);
|
||||
m_result = result::FILE;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -551,7 +551,7 @@ void menu_select_rw::handle()
|
||||
if (event != nullptr && event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
m_result = result_from_itemref(event->itemref);
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ void menu_control_floppy_image::hook_load(std::string filename, bool softlist)
|
||||
{
|
||||
machine().popmessage("When loaded from software list, the disk is Read-only.\n");
|
||||
image->load(filename.c_str());
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ void menu_control_floppy_image::hook_load(std::string filename, bool softlist)
|
||||
if (!input_format)
|
||||
{
|
||||
machine().popmessage("Error: %s\n", image->error());
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ void menu_control_floppy_image::handle()
|
||||
output_filename = util::zippath_combine(m_current_directory.c_str(), m_current_file.c_str());
|
||||
output_format = format_array[submenu_result.i];
|
||||
do_load_create();
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -142,18 +142,18 @@ void menu_control_floppy_image::handle()
|
||||
switch(submenu_result.rw) {
|
||||
case menu_select_rw::result::READONLY:
|
||||
do_load_create();
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case menu_select_rw::result::READWRITE:
|
||||
output_format = input_format;
|
||||
do_load_create();
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case menu_select_rw::result::WRITE_DIFF:
|
||||
machine().popmessage("Sorry, diffs are not supported yet\n");
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case menu_select_rw::result::WRITE_OTHER:
|
||||
|
@ -156,7 +156,7 @@ void menu_control_device_image::hook_load(std::string name, bool softlist)
|
||||
{
|
||||
if (image->is_reset_on_load()) image->set_init_phase();
|
||||
image->load(name.c_str());
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +198,7 @@ void menu_control_device_image::handle()
|
||||
|
||||
case SELECT_SOFTLIST:
|
||||
if(!sld) {
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
}
|
||||
software_info_name = "";
|
||||
@ -251,7 +251,7 @@ void menu_control_device_image::handle()
|
||||
|
||||
case menu_software_parts::result::EMPTY:
|
||||
image->unload();
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case menu_software_parts::result::SWLIST:
|
||||
@ -260,7 +260,7 @@ void menu_control_device_image::handle()
|
||||
break;
|
||||
|
||||
case menu_software_parts::result::INVALID: // return to system
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
}
|
||||
@ -270,7 +270,7 @@ void menu_control_device_image::handle()
|
||||
switch(submenu_result.filesel) {
|
||||
case menu_file_selector::result::EMPTY:
|
||||
image->unload();
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
|
||||
case menu_file_selector::result::FILE:
|
||||
@ -288,7 +288,7 @@ void menu_control_device_image::handle()
|
||||
break;
|
||||
|
||||
default: // return to system
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -326,7 +326,7 @@ void menu_control_device_image::handle()
|
||||
int err = image->create(path.c_str(), nullptr, nullptr);
|
||||
if (err != 0)
|
||||
machine().popmessage("Error: %s", image->error());
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ void menu_main::handle()
|
||||
break;
|
||||
|
||||
case QUIT_GAME:
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
ui().request_quit();
|
||||
break;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,18 +8,21 @@
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MAME_FRONTEND_UI_MENU_H
|
||||
#define MAME_FRONTEND_UI_MENU_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui/ui.h"
|
||||
#include "ui/menuitem.h"
|
||||
|
||||
#include "language.h"
|
||||
#include "render.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
namespace ui {
|
||||
@ -39,9 +42,7 @@ public:
|
||||
FLAG_MULTILINE = (1 << 3),
|
||||
FLAG_REDTEXT = (1 << 4),
|
||||
FLAG_DISABLE = (1 << 5),
|
||||
FLAG_UI = (1 << 6),
|
||||
FLAG_UI_DATS = (1 << 7),
|
||||
FLAG_UI_SWLIST = (1 << 8),
|
||||
FLAG_UI_FAVORITE = (1 << 9),
|
||||
FLAG_UI_PALETTE = (1 << 10),
|
||||
FLAG_UI_HEADING = (1 << 11)
|
||||
@ -72,10 +73,9 @@ public:
|
||||
|
||||
// Global initialization
|
||||
static void init(running_machine &machine, ui_options &mopt);
|
||||
static void exit(running_machine &machine);
|
||||
|
||||
// reset the menus, clearing everything
|
||||
static void stack_reset(running_machine &machine);
|
||||
static void stack_reset(running_machine &machine) { get_global_state(machine)->stack_reset(); }
|
||||
|
||||
// push a new menu onto the stack
|
||||
template <typename T, typename... Params>
|
||||
@ -92,17 +92,14 @@ public:
|
||||
}
|
||||
|
||||
// pop a menu from the stack
|
||||
static void stack_pop(running_machine &machine);
|
||||
static void stack_pop(running_machine &machine) { get_global_state(machine)->stack_pop(); }
|
||||
|
||||
// test if one of the menus in the stack requires hide disable
|
||||
static bool stack_has_special_main_menu();
|
||||
static bool stack_has_special_main_menu(running_machine &machine) { return get_global_state(machine)->stack_has_special_main_menu(); }
|
||||
|
||||
// highlight
|
||||
static void highlight(render_container *container, float x0, float y0, float x1, float y1, rgb_t bgcolor);
|
||||
|
||||
// draw arrow
|
||||
static void draw_arrow(render_container *container, float x0, float y0, float x1, float y1, rgb_t fgcolor, UINT32 orientation);
|
||||
|
||||
// master handler
|
||||
static UINT32 ui_handler(render_container *container, mame_ui_manager &mui);
|
||||
|
||||
@ -122,41 +119,28 @@ public:
|
||||
|
||||
private:
|
||||
static std::unique_ptr<bitmap_rgb32> hilight_bitmap;
|
||||
static render_texture *hilight_texture, *arrow_texture;
|
||||
static render_texture *hilight_texture;
|
||||
|
||||
void draw(UINT32 flags, float x0 = 0.0f, float y0 = 0.0f);
|
||||
virtual void draw(UINT32 flags);
|
||||
void draw_text_box();
|
||||
void handle_events(UINT32 flags);
|
||||
void handle_keys(UINT32 flags);
|
||||
|
||||
inline bool exclusive_input_pressed(int key, int repeat);
|
||||
static void clear_free_list(running_machine &machine);
|
||||
static void render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param);
|
||||
|
||||
public:
|
||||
void *m_prev_selected;
|
||||
|
||||
int visible_items;
|
||||
bool ui_error;
|
||||
|
||||
// mouse handling
|
||||
bool mouse_hit, mouse_button;
|
||||
render_target *mouse_target;
|
||||
INT32 mouse_target_x, mouse_target_y;
|
||||
float mouse_x, mouse_y;
|
||||
|
||||
// draw toolbar
|
||||
void draw_toolbar(float x1, float y1, float x2, float y2, bool software = false);
|
||||
|
||||
// draw left panel
|
||||
virtual float draw_left_panel(float x1, float y1, float x2, float y2) { return 0; }
|
||||
|
||||
// draw right panel
|
||||
virtual void draw_right_panel(void *selectedref, float origx1, float origy1, float origx2, float origy2) { };
|
||||
|
||||
// draw star
|
||||
void draw_star(float x0, float y0);
|
||||
|
||||
// Global initialization
|
||||
static void init_ui(running_machine &machine, ui_options &mopt);
|
||||
|
||||
@ -171,6 +155,10 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
using cleanup_callback = std::function<void(running_machine &)>;
|
||||
using bitmap_ptr = std::unique_ptr<bitmap_argb32>;
|
||||
using texture_ptr = std::unique_ptr<render_texture, std::function<void(render_texture *)> >;
|
||||
|
||||
// flags to pass to process
|
||||
enum
|
||||
{
|
||||
@ -190,15 +178,6 @@ protected:
|
||||
REMEMBER_REF
|
||||
};
|
||||
|
||||
// tab navigation
|
||||
enum class focused_menu
|
||||
{
|
||||
main,
|
||||
left,
|
||||
righttop,
|
||||
rightbottom
|
||||
};
|
||||
|
||||
// menu-related events
|
||||
struct event
|
||||
{
|
||||
@ -234,27 +213,33 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
int topline_datsview; // right box top line
|
||||
int top_line; // main box top line
|
||||
int l_sw_hover;
|
||||
int l_hover;
|
||||
int totallines;
|
||||
int skip_main_items;
|
||||
int selected; // which item is selected
|
||||
|
||||
int m_visible_lines; // main box visible lines
|
||||
int m_visible_items; // number of visible items
|
||||
|
||||
menu(mame_ui_manager &mui, render_container *container);
|
||||
|
||||
void reset(reset_options options);
|
||||
void reset_parent(reset_options options) { m_parent->reset(options); }
|
||||
static void reset_topmost(reset_options options) { if (menu_stack) menu_stack->reset(options); }
|
||||
void reset_topmost(reset_options options) { m_global_state->reset_topmost(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(); }
|
||||
|
||||
void add_cleanup_callback(cleanup_callback &&callback) { m_global_state->add_cleanup_callback(std::move(callback)); }
|
||||
|
||||
// process a menu, drawing it and returning any interesting events
|
||||
const event *process(UINT32 flags, float x0 = 0.0f, float y0 = 0.0f);
|
||||
void process_parent() { m_parent->process(PROCESS_NOINPUT); }
|
||||
|
||||
focused_menu get_focus() const { return m_focus; }
|
||||
void set_focus(focused_menu focus) { m_focus = focus; }
|
||||
|
||||
// retrieves the ref of the currently selected menu item or nullptr
|
||||
void *get_selection_ref() const { return selection_valid() ? item[selected].ref : nullptr; }
|
||||
bool selection_valid() const { return (0 <= selected) && (item.size() > selected); }
|
||||
@ -267,37 +252,81 @@ protected:
|
||||
// scroll position control
|
||||
void centre_selection() { top_line = selected - (m_visible_lines / 2); }
|
||||
|
||||
// draw right box
|
||||
float draw_right_box_title(float x1, float y1, float x2, float y2);
|
||||
// test if the given key is pressed and we haven't already reported a key
|
||||
bool exclusive_input_pressed(int &iptkey, int key, int repeat);
|
||||
|
||||
// draw arrow
|
||||
void draw_arrow(render_container *container, float x0, float y0, float x1, float y1, rgb_t fgcolor, UINT32 orientation);
|
||||
void draw_common_arrow(float origx1, float origy1, float origx2, float origy2, int current, int dmin, int dmax, float title);
|
||||
void info_arrow(int ub, float origx1, float origx2, float oy1, float line_height, float text_size, float ud_arrow_width);
|
||||
|
||||
// images render
|
||||
std::string arts_render_common(float origx1, float origy1, float origx2, float origy2);
|
||||
void arts_render_images(bitmap_argb32 *bitmap, float origx1, float origy1, float origx2, float origy2);
|
||||
|
||||
// draw header and footer text
|
||||
void extra_text_render(float top, float bottom, float origx1, float origy1, float origx2, float origy2, const char *header, const char *footer);
|
||||
void extra_text_position(float origx1, float origx2, float origy, float yspan, text_layout &layout,
|
||||
int direction, float &x1, float &y1, float &x2, float &y2);
|
||||
|
||||
// custom events
|
||||
void draw_background();
|
||||
|
||||
// overridable event handling
|
||||
virtual void handle_events(UINT32 flags, event &ev);
|
||||
virtual void handle_keys(UINT32 flags, int &iptkey);
|
||||
virtual bool custom_mouse_down() { return false; }
|
||||
|
||||
template <typename T>
|
||||
static T *topmost_menu() { return dynamic_cast<T *>(menu_stack.get()); }
|
||||
static bool is_selectable(menu_item const &item)
|
||||
{
|
||||
return ((item.flags & (menu::FLAG_MULTILINE | menu::FLAG_DISABLE)) == 0 && item.type != menu_item_type::SEPARATOR);
|
||||
}
|
||||
|
||||
int right_visible_lines; // right box lines
|
||||
|
||||
static std::unique_ptr<bitmap_argb32> snapx_bitmap;
|
||||
static bitmap_ptr snapx_bitmap;
|
||||
static render_texture *snapx_texture;
|
||||
|
||||
static std::unique_ptr<bitmap_rgb32> hilight_main_bitmap;
|
||||
static render_texture *hilight_main_texture;
|
||||
|
||||
private:
|
||||
class global_state
|
||||
{
|
||||
public:
|
||||
global_state(running_machine &machine, ui_options const &options);
|
||||
global_state(global_state const &) = delete;
|
||||
global_state(global_state &&) = delete;
|
||||
~global_state();
|
||||
|
||||
void add_cleanup_callback(cleanup_callback &&callback);
|
||||
|
||||
render_texture * arrow_texture() { return m_arrow_texture.get(); }
|
||||
bitmap_argb32 *bgrnd_bitmap() { return m_bgrnd_bitmap.get(); }
|
||||
render_texture * bgrnd_texture() { return m_bgrnd_texture.get(); }
|
||||
|
||||
void reset_topmost(reset_options options) { if (m_stack) m_stack->reset(options); }
|
||||
|
||||
template <typename T>
|
||||
T *topmost_menu() const { return dynamic_cast<T *>(m_stack.get()); }
|
||||
|
||||
void stack_push(std::unique_ptr<menu> &&menu);
|
||||
void stack_pop();
|
||||
void stack_reset();
|
||||
void clear_free_list();
|
||||
bool stack_has_special_main_menu() const;
|
||||
|
||||
private:
|
||||
using cleanup_callback_vector = std::vector<cleanup_callback>;
|
||||
|
||||
running_machine &m_machine;
|
||||
cleanup_callback_vector m_cleanup_callbacks;
|
||||
|
||||
texture_ptr m_arrow_texture;
|
||||
bitmap_ptr m_bgrnd_bitmap;
|
||||
texture_ptr m_bgrnd_texture;
|
||||
|
||||
std::unique_ptr<menu> m_stack;
|
||||
std::unique_ptr<menu> m_free;
|
||||
};
|
||||
using global_state_ptr = std::shared_ptr<global_state>;
|
||||
using global_state_map = std::map<running_machine *, global_state_ptr>;
|
||||
|
||||
struct pool
|
||||
{
|
||||
pool *next; // chain to next one
|
||||
@ -305,69 +334,36 @@ private:
|
||||
UINT8 *end; // end of the pool
|
||||
};
|
||||
|
||||
|
||||
void reset_pressed() { m_pressed = false; m_repeat = 0; }
|
||||
bool mouse_pressed() { return (osd_ticks() >= m_repeat); }
|
||||
void set_pressed();
|
||||
|
||||
static std::unique_ptr<bitmap_argb32> no_avail_bitmap, bgrnd_bitmap, star_bitmap;
|
||||
static render_texture *bgrnd_texture, *star_texture;
|
||||
static std::vector<std::unique_ptr<bitmap_argb32>> icons_bitmap;
|
||||
static render_texture *icons_texture[];
|
||||
|
||||
// request the specific handling of the game selection main menu
|
||||
bool is_special_main_menu() const;
|
||||
void set_special_main_menu(bool disable);
|
||||
|
||||
// push a new menu onto the stack
|
||||
static void stack_push(std::unique_ptr<menu> &&menu);
|
||||
|
||||
// toolbar
|
||||
static std::vector<std::shared_ptr<bitmap_argb32>> toolbar_bitmap, sw_toolbar_bitmap;
|
||||
static render_texture *toolbar_texture[], *sw_toolbar_texture[];
|
||||
|
||||
// draw game list
|
||||
void draw_select_game(UINT32 flags);
|
||||
static void stack_push(std::unique_ptr<menu> &&menu) { get_global_state(menu->machine())->stack_push(std::move(menu)); }
|
||||
|
||||
// draw palette menu
|
||||
void draw_palette_menu();
|
||||
|
||||
// draw dats menu
|
||||
void draw_dats_menu();
|
||||
|
||||
void get_title_search(std::string &title, std::string &search);
|
||||
|
||||
// handle keys
|
||||
void handle_main_keys(UINT32 flags);
|
||||
|
||||
// handle mouse
|
||||
void handle_main_events();
|
||||
|
||||
float draw_icon(int linenum, void *selectedref, float x1, float y1);
|
||||
void extra_text_draw_box(float origx1, float origx2, float origy, float yspan, const char *text, int direction);
|
||||
|
||||
bool first_item_visible() const { return top_line <= 0; }
|
||||
bool last_item_visible() const { return (top_line + m_visible_lines) >= item.size(); }
|
||||
|
||||
static void exit(running_machine &machine);
|
||||
static global_state_ptr get_global_state(running_machine &machine);
|
||||
|
||||
global_state_ptr const m_global_state;
|
||||
bool m_special_main_menu;
|
||||
mame_ui_manager &m_ui; // UI we are attached to
|
||||
std::unique_ptr<menu> m_parent; // pointer to parent menu
|
||||
bool m_pressed; // mouse button held down
|
||||
osd_ticks_t m_repeat;
|
||||
event m_event; // the UI event that occurred
|
||||
pool *m_pool; // list of memory pools
|
||||
focused_menu m_focus;
|
||||
|
||||
int m_visible_lines; // main box visible lines
|
||||
int m_visible_items; // number of visible items
|
||||
|
||||
int m_resetpos; // reset position
|
||||
void *m_resetref; // reset reference
|
||||
|
||||
static std::vector<const game_driver *> m_old_icons;
|
||||
|
||||
static std::unique_ptr<menu> menu_stack;
|
||||
static std::unique_ptr<menu> menu_free;
|
||||
static std::mutex s_global_state_guard;
|
||||
static global_state_map s_global_states;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
@ -548,7 +548,7 @@ void menu_quit_game::handle()
|
||||
machine().schedule_exit();
|
||||
|
||||
/* reset the menu stack */
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -95,7 +95,7 @@ void menu_selector::handle()
|
||||
}
|
||||
|
||||
ui_globals::switch_image = true;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_SPECIAL)
|
||||
{
|
||||
|
@ -55,7 +55,8 @@ int menu_select_game::m_isabios = 0;
|
||||
// ctor
|
||||
//-------------------------------------------------
|
||||
|
||||
menu_select_game::menu_select_game(mame_ui_manager &mui, render_container *container, const char *gamename) : menu(mui, container)
|
||||
menu_select_game::menu_select_game(mame_ui_manager &mui, render_container *container, const char *gamename)
|
||||
: menu_select_launch(mui, container, false)
|
||||
{
|
||||
set_focus(focused_menu::main);
|
||||
highlight = 0;
|
||||
@ -184,7 +185,7 @@ void menu_select_game::handle()
|
||||
{
|
||||
ui_globals::reset = false;
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -203,10 +204,10 @@ void menu_select_game::handle()
|
||||
const event *menu_event = process(PROCESS_LR_REPEAT);
|
||||
if (menu_event && menu_event->itemref)
|
||||
{
|
||||
if (ui_error)
|
||||
if (m_ui_error)
|
||||
{
|
||||
// reset the error on any future menu_event
|
||||
ui_error = false;
|
||||
m_ui_error = false;
|
||||
machine().ui_input().reset();
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
@ -257,7 +258,7 @@ void menu_select_game::handle()
|
||||
if ((FPTR)drv > skip_main_items && ui_globals::curdats_view > UI_FIRST_LOAD)
|
||||
{
|
||||
ui_globals::curdats_view--;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -266,12 +267,12 @@ void menu_select_game::handle()
|
||||
if (drv->startempty == 1 && ui_globals::curdats_view > UI_FIRST_LOAD)
|
||||
{
|
||||
ui_globals::curdats_view--;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
else if ((FPTR)drv > skip_main_items && ui_globals::cur_sw_dats_view > 0)
|
||||
{
|
||||
ui_globals::cur_sw_dats_view--;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -295,7 +296,7 @@ void menu_select_game::handle()
|
||||
if ((FPTR)drv > skip_main_items && ui_globals::curdats_view < UI_LAST_LOAD)
|
||||
{
|
||||
ui_globals::curdats_view++;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -304,12 +305,12 @@ void menu_select_game::handle()
|
||||
if (drv->startempty == 1 && ui_globals::curdats_view < UI_LAST_LOAD)
|
||||
{
|
||||
ui_globals::curdats_view++;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
else if ((FPTR)drv > skip_main_items && ui_globals::cur_sw_dats_view < 1)
|
||||
{
|
||||
ui_globals::cur_sw_dats_view++;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -457,7 +458,7 @@ void menu_select_game::handle()
|
||||
}
|
||||
|
||||
// if we're in an error state, overlay an error message
|
||||
if (ui_error)
|
||||
if (m_ui_error)
|
||||
ui().draw_text_box(container, _("The selected machine is missing one or more required ROM or CHD images. "
|
||||
"Please select a different machine.\n\nPress any key to continue."), ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
|
||||
|
||||
@ -497,7 +498,7 @@ void menu_select_game::populate()
|
||||
ui_globals::redraw_icon = true;
|
||||
ui_globals::switch_image = true;
|
||||
int old_item_selected = -1;
|
||||
UINT32 flags_ui = FLAG_UI | FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
|
||||
UINT32 flags_ui = FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
|
||||
|
||||
if (!isfavorite())
|
||||
{
|
||||
@ -588,7 +589,7 @@ void menu_select_game::populate()
|
||||
item_append(menu_item_type::SEPARATOR, flags_ui);
|
||||
|
||||
// add special items
|
||||
if (menu::stack_has_special_main_menu())
|
||||
if (stack_has_special_main_menu())
|
||||
{
|
||||
item_append(_("Configure Options"), "", flags_ui, (void *)(FPTR)CONF_OPTS);
|
||||
item_append(_("Configure Machine"), "", flags_ui, (void *)(FPTR)CONF_MACHINE);
|
||||
@ -1064,14 +1065,14 @@ void menu_select_game::inkey_select(const event *menu_event)
|
||||
reselect_last::swlist.clear();
|
||||
mame_machine_manager::instance()->schedule_new_driver(*driver);
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
}
|
||||
// otherwise, display an error
|
||||
else
|
||||
{
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
ui_error = true;
|
||||
m_ui_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1125,7 +1126,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
|
||||
reselect_last::set(true);
|
||||
mame_machine_manager::instance()->schedule_new_driver(*ui_swinfo->driver);
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1133,7 +1134,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
|
||||
else
|
||||
{
|
||||
reset(reset_options::REMEMBER_REF);
|
||||
ui_error = true;
|
||||
m_ui_error = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1182,14 +1183,14 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
|
||||
reselect_last::swlist = ui_swinfo->listname;
|
||||
mame_machine_manager::instance()->schedule_new_driver(drv.driver());
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
|
||||
// otherwise, display an error
|
||||
else
|
||||
{
|
||||
reset(reset_options::REMEMBER_POSITION);
|
||||
ui_error = true;
|
||||
m_ui_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1531,7 +1532,7 @@ void menu_select_game::populate_search()
|
||||
}
|
||||
|
||||
(index < VISIBLE_GAMES_IN_SEARCH) ? m_searchlist[index] = nullptr : m_searchlist[VISIBLE_GAMES_IN_SEARCH] = nullptr;
|
||||
UINT32 flags_ui = FLAG_UI | FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
|
||||
UINT32 flags_ui = FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
|
||||
for (int curitem = 0; m_searchlist[curitem]; ++curitem)
|
||||
{
|
||||
bool cloneof = strcmp(m_searchlist[curitem]->parent, "0");
|
||||
@ -2040,8 +2041,8 @@ void menu_select_game::infos_render(void *selectedref, float origx1, float origy
|
||||
buffer.clear();
|
||||
olddriver = driver;
|
||||
oldview = ui_globals::curdats_view;
|
||||
topline_datsview = 0;
|
||||
totallines = 0;
|
||||
m_topline_datsview = 0;
|
||||
m_total_lines = 0;
|
||||
std::vector<std::string> m_item;
|
||||
|
||||
if (ui_globals::curdats_view == UI_GENERAL_LOAD)
|
||||
@ -2072,29 +2073,29 @@ void menu_select_game::infos_render(void *selectedref, float origx1, float origy
|
||||
return;
|
||||
}
|
||||
else if (ui_globals::curdats_view != UI_STORY_LOAD && ui_globals::curdats_view != UI_COMMAND_LOAD)
|
||||
totallines = ui().wrap_text(container, buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
m_total_lines = ui().wrap_text(container, buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
else
|
||||
totallines = ui().wrap_text(container, buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
m_total_lines = ui().wrap_text(container, buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
|
||||
int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
|
||||
if (totallines < r_visible_lines)
|
||||
r_visible_lines = totallines;
|
||||
if (topline_datsview < 0)
|
||||
topline_datsview = 0;
|
||||
if (topline_datsview + r_visible_lines >= totallines)
|
||||
topline_datsview = totallines - r_visible_lines;
|
||||
if (m_total_lines < r_visible_lines)
|
||||
r_visible_lines = m_total_lines;
|
||||
if (m_topline_datsview < 0)
|
||||
m_topline_datsview = 0;
|
||||
if (m_topline_datsview + r_visible_lines >= m_total_lines)
|
||||
m_topline_datsview = m_total_lines - r_visible_lines;
|
||||
|
||||
sc = origx2 - origx1 - (2.0f * UI_BOX_LR_BORDER);
|
||||
for (int r = 0; r < r_visible_lines; ++r)
|
||||
{
|
||||
int itemline = r + topline_datsview;
|
||||
int itemline = r + m_topline_datsview;
|
||||
std::string tempbuf(buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
|
||||
|
||||
// up arrow
|
||||
if (r == 0 && topline_datsview != 0)
|
||||
if (r == 0 && m_topline_datsview != 0)
|
||||
info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
// bottom arrow
|
||||
else if (r == r_visible_lines - 1 && itemline != totallines - 1)
|
||||
else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1)
|
||||
info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
// special case for mamescore
|
||||
else if (ui_globals::curdats_view == UI_STORY_LOAD)
|
||||
@ -2159,7 +2160,7 @@ void menu_select_game::infos_render(void *selectedref, float origx1, float origy
|
||||
}
|
||||
|
||||
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
right_visible_lines = r_visible_lines - (topline_datsview != 0) - (topline_datsview + r_visible_lines != totallines);
|
||||
right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines);
|
||||
}
|
||||
else if (soft)
|
||||
{
|
||||
@ -2233,26 +2234,26 @@ void menu_select_game::infos_render(void *selectedref, float origx1, float origy
|
||||
return;
|
||||
}
|
||||
else
|
||||
totallines = ui().wrap_text(container, buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
m_total_lines = ui().wrap_text(container, buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
|
||||
int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
|
||||
if (totallines < r_visible_lines)
|
||||
r_visible_lines = totallines;
|
||||
if (topline_datsview < 0)
|
||||
topline_datsview = 0;
|
||||
if (topline_datsview + r_visible_lines >= totallines)
|
||||
topline_datsview = totallines - r_visible_lines;
|
||||
if (m_total_lines < r_visible_lines)
|
||||
r_visible_lines = m_total_lines;
|
||||
if (m_topline_datsview < 0)
|
||||
m_topline_datsview = 0;
|
||||
if (m_topline_datsview + r_visible_lines >= m_total_lines)
|
||||
m_topline_datsview = m_total_lines - r_visible_lines;
|
||||
|
||||
for (int r = 0; r < r_visible_lines; ++r)
|
||||
{
|
||||
int itemline = r + topline_datsview;
|
||||
int itemline = r + m_topline_datsview;
|
||||
std::string tempbuf(buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
|
||||
|
||||
// up arrow
|
||||
if (r == 0 && topline_datsview != 0)
|
||||
if (r == 0 && m_topline_datsview != 0)
|
||||
info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
// bottom arrow
|
||||
else if (r == r_visible_lines - 1 && itemline != totallines - 1)
|
||||
else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1)
|
||||
info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
else
|
||||
ui().draw_text_full(container, tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT,
|
||||
@ -2261,7 +2262,7 @@ void menu_select_game::infos_render(void *selectedref, float origx1, float origy
|
||||
}
|
||||
|
||||
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
right_visible_lines = r_visible_lines - (topline_datsview != 0) - (topline_datsview + r_visible_lines != totallines);
|
||||
right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,11 @@
|
||||
#ifndef MAME_FRONTEND_UI_SELGAME_H
|
||||
#define MAME_FRONTEND_UI_SELGAME_H
|
||||
|
||||
#include "ui/menu.h"
|
||||
#include "ui/selmenu.h"
|
||||
|
||||
|
||||
namespace ui {
|
||||
class menu_select_game : public menu
|
||||
class menu_select_game : public menu_select_launch
|
||||
{
|
||||
public:
|
||||
menu_select_game(mame_ui_manager &mui, render_container *container, const char *gamename);
|
||||
|
1287
src/frontend/mame/ui/selmenu.cpp
Normal file
1287
src/frontend/mame/ui/selmenu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
134
src/frontend/mame/ui/selmenu.h
Normal file
134
src/frontend/mame/ui/selmenu.h
Normal file
@ -0,0 +1,134 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
|
||||
/***************************************************************************
|
||||
|
||||
ui/selmenu.h
|
||||
|
||||
MAME system/software selection menu.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_FRONTEND_UI_SELMENU_H
|
||||
#define MAME_FRONTEND_UI_SELMENU_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui/menu.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace ui {
|
||||
class menu_select_launch : public menu
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~menu_select_launch() override;
|
||||
|
||||
protected:
|
||||
|
||||
// tab navigation
|
||||
enum class focused_menu
|
||||
{
|
||||
main,
|
||||
left,
|
||||
righttop,
|
||||
rightbottom
|
||||
};
|
||||
|
||||
menu_select_launch(mame_ui_manager &mui, render_container *container, bool is_swlist);
|
||||
|
||||
focused_menu get_focus() const { return m_focus; }
|
||||
void set_focus(focused_menu focus) { m_focus = focus; }
|
||||
|
||||
// draw right box
|
||||
float draw_right_box_title(float x1, float y1, float x2, float y2);
|
||||
|
||||
// images render
|
||||
std::string arts_render_common(float origx1, float origy1, float origx2, float origy2);
|
||||
void arts_render_images(bitmap_argb32 *bitmap, float origx1, float origy1, float origx2, float origy2);
|
||||
|
||||
// draw toolbar
|
||||
void draw_toolbar(float x1, float y1, float x2, float y2, bool software = false);
|
||||
|
||||
// draw star
|
||||
void draw_star(float x0, float y0);
|
||||
|
||||
int visible_items;
|
||||
int m_total_lines;
|
||||
int m_topline_datsview; // right box top line
|
||||
bool m_ui_error;
|
||||
|
||||
private:
|
||||
using bitmap_ptr_vector = std::vector<bitmap_ptr>;
|
||||
using texture_ptr_vector = std::vector<texture_ptr>;
|
||||
|
||||
class cache
|
||||
{
|
||||
public:
|
||||
cache(running_machine &machine);
|
||||
~cache();
|
||||
|
||||
bitmap_argb32 &no_avail_bitmap() { return *m_no_avail_bitmap; }
|
||||
render_texture *star_texture() { return m_star_texture.get(); }
|
||||
|
||||
bitmap_ptr_vector const &toolbar_bitmap() { return m_toolbar_bitmap; }
|
||||
bitmap_ptr_vector const &sw_toolbar_bitmap() { return m_sw_toolbar_bitmap; }
|
||||
texture_ptr_vector const &toolbar_texture() { return m_toolbar_texture; }
|
||||
texture_ptr_vector const &sw_toolbar_texture() { return m_sw_toolbar_texture; }
|
||||
|
||||
private:
|
||||
bitmap_ptr m_no_avail_bitmap;
|
||||
bitmap_ptr m_star_bitmap;
|
||||
texture_ptr m_star_texture;
|
||||
|
||||
bitmap_ptr_vector m_toolbar_bitmap;
|
||||
bitmap_ptr_vector m_sw_toolbar_bitmap;
|
||||
texture_ptr_vector m_toolbar_texture;
|
||||
texture_ptr_vector m_sw_toolbar_texture;
|
||||
};
|
||||
using cache_ptr = std::shared_ptr<cache>;
|
||||
using cache_ptr_map = std::map<running_machine *, cache_ptr>;
|
||||
|
||||
static constexpr std::size_t MAX_ICONS_RENDER = 40;
|
||||
|
||||
void reset_pressed() { m_pressed = false; m_repeat = 0; }
|
||||
bool mouse_pressed() const { return (osd_ticks() >= m_repeat); }
|
||||
void set_pressed();
|
||||
|
||||
float draw_icon(int linenum, void *selectedref, float x1, float y1);
|
||||
|
||||
void get_title_search(std::string &title, std::string &search);
|
||||
|
||||
// handle keys
|
||||
virtual void handle_keys(UINT32 flags, int &iptkey) override;
|
||||
|
||||
// handle mouse
|
||||
virtual void handle_events(UINT32 flags, event &ev) override;
|
||||
|
||||
// draw game list
|
||||
virtual void draw(UINT32 flags) override;
|
||||
|
||||
// cleanup function
|
||||
static void exit(running_machine &machine);
|
||||
|
||||
cache_ptr m_cache;
|
||||
bool m_is_swlist;
|
||||
focused_menu m_focus;
|
||||
bool m_pressed; // mouse button held down
|
||||
osd_ticks_t m_repeat;
|
||||
|
||||
render_texture *m_icons_texture[MAX_ICONS_RENDER];
|
||||
bitmap_ptr m_icons_bitmap[MAX_ICONS_RENDER];
|
||||
game_driver const *m_old_icons[MAX_ICONS_RENDER];
|
||||
|
||||
static std::mutex s_cache_guard;
|
||||
static cache_ptr_map s_caches;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // MAME_FRONTEND_UI_SELMENU_H
|
@ -125,7 +125,8 @@ bool has_multiple_bios(const game_driver *driver, s_bios &biosname)
|
||||
// ctor
|
||||
//-------------------------------------------------
|
||||
|
||||
menu_select_software::menu_select_software(mame_ui_manager &mui, render_container *container, const game_driver *driver) : menu(mui, container)
|
||||
menu_select_software::menu_select_software(mame_ui_manager &mui, render_container *container, const game_driver *driver)
|
||||
: menu_select_launch(mui, container, true)
|
||||
{
|
||||
if (reselect_last::get())
|
||||
reselect_last::set(false);
|
||||
@ -174,10 +175,10 @@ void menu_select_software::handle()
|
||||
|
||||
if (menu_event && menu_event->itemref)
|
||||
{
|
||||
if (ui_error)
|
||||
if (m_ui_error)
|
||||
{
|
||||
// reset the error on any future event
|
||||
ui_error = false;
|
||||
m_ui_error = false;
|
||||
machine().ui_input().reset();
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
@ -208,7 +209,7 @@ void menu_select_software::handle()
|
||||
{
|
||||
// Infos
|
||||
ui_globals::cur_sw_dats_view--;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT)
|
||||
@ -225,7 +226,7 @@ void menu_select_software::handle()
|
||||
{
|
||||
// Infos
|
||||
ui_globals::cur_sw_dats_view++;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_UP_FILTER && highlight > UI_SW_FIRST)
|
||||
@ -322,7 +323,7 @@ void menu_select_software::handle()
|
||||
{
|
||||
// Infos
|
||||
ui_globals::cur_sw_dats_view--;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_RIGHT)
|
||||
@ -339,7 +340,7 @@ void menu_select_software::handle()
|
||||
{
|
||||
// Infos
|
||||
ui_globals::cur_sw_dats_view++;
|
||||
topline_datsview = 0;
|
||||
m_topline_datsview = 0;
|
||||
}
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_LEFT_PANEL)
|
||||
@ -371,7 +372,7 @@ void menu_select_software::handle()
|
||||
}
|
||||
|
||||
// if we're in an error state, overlay an error message
|
||||
if (ui_error)
|
||||
if (m_ui_error)
|
||||
ui().draw_text_box(container, _("The selected software is missing one or more required files. "
|
||||
"Please select a different software.\n\nPress any key to continue."),
|
||||
ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
|
||||
@ -415,7 +416,7 @@ void menu_select_software::handle()
|
||||
|
||||
void menu_select_software::populate()
|
||||
{
|
||||
UINT32 flags_ui = FLAG_UI_SWLIST | FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
|
||||
UINT32 flags_ui = FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
|
||||
m_has_empty_start = true;
|
||||
int old_software = -1;
|
||||
|
||||
@ -897,7 +898,7 @@ void menu_select_software::inkey_select(const event *menu_event)
|
||||
reselect_last::set(true);
|
||||
mame_machine_manager::instance()->schedule_new_driver(*ui_swinfo->driver);
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -948,14 +949,14 @@ void menu_select_software::inkey_select(const event *menu_event)
|
||||
reselect_last::set(true);
|
||||
mame_machine_manager::instance()->schedule_new_driver(drivlist.driver());
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
|
||||
// otherwise, display an error
|
||||
else
|
||||
{
|
||||
reset(reset_options::REMEMBER_POSITION);
|
||||
ui_error = true;
|
||||
m_ui_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1652,27 +1653,27 @@ void menu_select_software::infos_render(void *selectedref, float origx1, float o
|
||||
return;
|
||||
}
|
||||
else
|
||||
totallines = ui().wrap_text(container, buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
m_total_lines = ui().wrap_text(container, buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
|
||||
int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
|
||||
if (totallines < r_visible_lines)
|
||||
r_visible_lines = totallines;
|
||||
if (topline_datsview < 0)
|
||||
topline_datsview = 0;
|
||||
if (topline_datsview + r_visible_lines >= totallines)
|
||||
topline_datsview = totallines - r_visible_lines;
|
||||
if (m_total_lines < r_visible_lines)
|
||||
r_visible_lines = m_total_lines;
|
||||
if (m_topline_datsview < 0)
|
||||
m_topline_datsview = 0;
|
||||
if (m_topline_datsview + r_visible_lines >= m_total_lines)
|
||||
m_topline_datsview = m_total_lines - r_visible_lines;
|
||||
|
||||
for (int r = 0; r < r_visible_lines; ++r)
|
||||
{
|
||||
int itemline = r + topline_datsview;
|
||||
int itemline = r + m_topline_datsview;
|
||||
std::string tempbuf;
|
||||
tempbuf.assign(buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
|
||||
|
||||
// up arrow
|
||||
if (r == 0 && topline_datsview != 0)
|
||||
if (r == 0 && m_topline_datsview != 0)
|
||||
info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
// bottom arrow
|
||||
else if (r == r_visible_lines - 1 && itemline != totallines - 1)
|
||||
else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1)
|
||||
info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
else
|
||||
ui().draw_text_full(container, tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1,
|
||||
@ -1682,7 +1683,7 @@ void menu_select_software::infos_render(void *selectedref, float origx1, float o
|
||||
}
|
||||
|
||||
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
right_visible_lines = r_visible_lines - (topline_datsview != 0) - (topline_datsview + r_visible_lines != totallines);
|
||||
right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -1972,7 +1973,7 @@ void software_parts::handle()
|
||||
|
||||
mame_machine_manager::instance()->schedule_new_driver(*m_uiinfo->driver);
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2074,7 +2075,7 @@ void bios_selection::handle()
|
||||
moptions.set_value(OPTION_BIOS, elem.second, OPTION_PRIORITY_CMDLINE, error);
|
||||
mame_machine_manager::instance()->schedule_new_driver(*s_driver);
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2112,7 +2113,7 @@ void bios_selection::handle()
|
||||
reselect_last::set(true);
|
||||
mame_machine_manager::instance()->schedule_new_driver(drivlist.driver());
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,14 @@
|
||||
#define MAME_FRONTEND_UI_SELSOFT_H
|
||||
|
||||
#include "ui/custmenu.h"
|
||||
#include "ui/selmenu.h"
|
||||
|
||||
namespace ui {
|
||||
using s_bios = std::vector<std::pair<std::string, int>>;
|
||||
using s_parts = std::unordered_map<std::string, std::string>;
|
||||
|
||||
// Menu Class
|
||||
class menu_select_software : public menu
|
||||
class menu_select_software : public menu_select_launch
|
||||
{
|
||||
public:
|
||||
menu_select_software(mame_ui_manager &mui, render_container *container, const game_driver *driver);
|
||||
|
@ -164,7 +164,7 @@ void simple_menu_select_game::inkey_select(const event *menu_event)
|
||||
{
|
||||
mame_machine_manager::instance()->schedule_new_driver(*driver);
|
||||
machine().schedule_hard_reset();
|
||||
menu::stack_reset(machine());
|
||||
stack_reset();
|
||||
}
|
||||
|
||||
// otherwise, display an error
|
||||
@ -264,7 +264,7 @@ void simple_menu_select_game::populate()
|
||||
}
|
||||
|
||||
// if we're forced into this, allow general input configuration as well
|
||||
if (menu::stack_has_special_main_menu())
|
||||
if (stack_has_special_main_menu())
|
||||
{
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
item_append(_("Configure Options"), "", 0, (void *)1);
|
||||
|
@ -53,7 +53,7 @@ void menu_sliders::handle()
|
||||
// toggle visibility
|
||||
case IPT_UI_ON_SCREEN_DISPLAY:
|
||||
if (m_menuless_mode)
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
else
|
||||
m_hidden = !m_hidden;
|
||||
break;
|
||||
@ -268,7 +268,7 @@ UINT32 menu_sliders::ui_handler(render_container *container, mame_ui_manager &mu
|
||||
UINT32 result;
|
||||
|
||||
// if this is the first call, push the sliders menu
|
||||
if (topmost_menu<menu_sliders>() == nullptr)
|
||||
if (topmost_menu<menu_sliders>(mui.machine()) == nullptr)
|
||||
menu::stack_push<menu_sliders>(mui, container, true);
|
||||
|
||||
// handle standard menus
|
||||
@ -278,7 +278,7 @@ UINT32 menu_sliders::ui_handler(render_container *container, mame_ui_manager &mu
|
||||
if (result == UI_HANDLER_CANCEL)
|
||||
menu::stack_pop(mui.machine());
|
||||
|
||||
menu_sliders *uim = topmost_menu<menu_sliders>();
|
||||
menu_sliders *uim = topmost_menu<menu_sliders>(mui.machine());
|
||||
return uim && uim->m_menuless_mode ? 0 : UI_HANDLER_CANCEL;
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ void menu_software_parts::handle()
|
||||
software_part_menu_entry *entry = (software_part_menu_entry *) event->itemref;
|
||||
m_result = entry->type;
|
||||
*m_selected_part = entry->part;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ void menu_software_list::handle()
|
||||
{
|
||||
entry_info *info = (entry_info *) event->itemref;
|
||||
m_result = info->short_name;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
else if (event->iptkey == IPT_SPECIAL)
|
||||
{
|
||||
@ -316,7 +316,7 @@ void menu_software_list::handle()
|
||||
if (m_filename_buffer[0] != '\0')
|
||||
memset(m_filename_buffer, '\0', ARRAY_LENGTH(m_filename_buffer));
|
||||
m_result = m_filename_buffer;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -402,7 +402,7 @@ void menu_software::handle()
|
||||
if (event != nullptr && event->iptkey == IPT_UI_SELECT) {
|
||||
//menu::stack_push<menu_software_list>(ui(), container, (software_list_config *)event->itemref, image);
|
||||
*m_result = (software_list_device *)event->itemref;
|
||||
menu::stack_pop(machine());
|
||||
stack_pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
|
||||
|
||||
// loop over states
|
||||
set_handler(UI_CALLBACK_TYPE_GENERAL, &mame_ui_manager::handler_ingame);
|
||||
for (state = 0; state < maxstate && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(); state++)
|
||||
for (state = 0; state < maxstate && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(machine()); state++)
|
||||
{
|
||||
// default to standard colors
|
||||
messagebox_backcolor = UI_BACKGROUND_COLOR;
|
||||
@ -328,7 +328,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
|
||||
while (machine().input().poll_switches() != INPUT_CODE_INVALID) { }
|
||||
|
||||
// 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())
|
||||
while (m_handler_callback_type == UI_CALLBACK_TYPE_MODAL && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(machine()))
|
||||
{
|
||||
machine().video().frame_update();
|
||||
}
|
||||
@ -339,7 +339,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
|
||||
}
|
||||
|
||||
// if we're the empty driver, force the menus on
|
||||
if (ui::menu::stack_has_special_main_menu())
|
||||
if (ui::menu::stack_has_special_main_menu(machine()))
|
||||
show_menu();
|
||||
}
|
||||
|
||||
@ -381,7 +381,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())
|
||||
if (ui::menu::stack_has_special_main_menu(machine()))
|
||||
alpha = 255;
|
||||
if (alpha > 255)
|
||||
alpha = 255;
|
||||
|
Loading…
Reference in New Issue
Block a user