// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/***************************************************************************
ui/menu.h
Internal MAME menus for the user interface.
***************************************************************************/
#pragma once
#ifndef __UI_MENU_H__
#define __UI_MENU_H__
#include "render.h"
#include "language.h"
#include "ui/ui.h"
#include "ui/menuitem.h"
/***************************************************************************
CONSTANTS
***************************************************************************/
// flags for menu items
#define MENU_FLAG_LEFT_ARROW (1 << 0)
#define MENU_FLAG_RIGHT_ARROW (1 << 1)
#define MENU_FLAG_INVERT (1 << 2)
#define MENU_FLAG_MULTILINE (1 << 3)
#define MENU_FLAG_REDTEXT (1 << 4)
#define MENU_FLAG_DISABLE (1 << 5)
#define MENU_FLAG_UI (1 << 6)
#define MENU_FLAG_UI_DATS (1 << 7)
#define MENU_FLAG_UI_SWLIST (1 << 8)
#define MENU_FLAG_UI_FAVORITE (1 << 9)
#define MENU_FLAG_UI_PALETTE (1 << 10)
#define MENU_FLAG_UI_HEADING (1 << 11)
// flags to pass to ui_menu_process
#define UI_MENU_PROCESS_NOKEYS 1
#define UI_MENU_PROCESS_LR_REPEAT 2
#define UI_MENU_PROCESS_CUSTOM_ONLY 4
#define UI_MENU_PROCESS_ONLYCHAR 8
#define UI_MENU_PROCESS_NOINPUT 16
#define UI_MENU_PROCESS_NOIMAGE 32
// options for ui_menu_reset
enum ui_menu_reset_options
{
UI_MENU_RESET_SELECT_FIRST,
UI_MENU_RESET_REMEMBER_POSITION,
UI_MENU_RESET_REMEMBER_REF
};
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
// menu-related events
struct ui_menu_event
{
void *itemref; // reference for the selected item
ui_menu_item_type type; // item type (eventually will go away when itemref is proper ui_menu_item class rather than void*)
int iptkey; // one of the IPT_* values from inptport.h
unicode_char unichar; // unicode character if iptkey == IPT_SPECIAL
render_bounds mouse; // mouse position if iptkey == IPT_CUSTOM
};
struct ui_menu_pool
{
ui_menu_pool *next; // chain to next one
UINT8 *top; // top of the pool
UINT8 *end; // end of the pool
};
class ui_menu
{
public:
ui_menu(mame_ui_manager &mui, render_container *container);
virtual ~ui_menu();
mame_ui_manager &ui() const { return m_ui; }
running_machine &machine() const { return m_ui.machine(); }
render_container *container; // render_container we render to
ui_menu_event menu_event; // the UI menu_event that occurred
ui_menu *parent; // pointer to parent menu
int resetpos; // reset position
void *resetref; // reset reference
int selected; // which item is selected
int hover; // which item is being hovered over
int visitems; // number of visible items
float customtop; // amount of extra height to add at the top
float custombottom; // amount of extra height to add at the bottom
ui_menu_pool *pool; // list of memory pools
std::vector<ui_menu_item> item; // array of items
// free all items in the menu, and all memory allocated from the memory pool
void reset(ui_menu_reset_options options);
// append a new item to the end of the menu
void item_append(const char *text, const char *subtext, UINT32 flags, void *ref, ui_menu_item_type type = ui_menu_item_type::UNKNOWN);
void item_append(ui_menu_item item);
void item_append(ui_menu_item_type type);
// process a menu, drawing it and returning any interesting events
const ui_menu_event *process(UINT32 flags, float x0 = 0.0f, float y0 = 0.0f);
// configure the menu for custom rendering
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2);
// allocate temporary memory from the menu's memory pool
void *m_pool_alloc(size_t size);
// make a temporary string copy in the menu's memory pool
const char *pool_strdup(const char *string);
// retrieves the index of the currently selected menu item
void *get_selection();
// changes the index of the currently selected menu item
void set_selection(void *selected_itemref);
// request the specific handling of the game selection main menu
bool is_special_main_menu() const;
void set_special_main_menu(bool disable);
// 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);
// push a new menu onto the stack
static void stack_push(ui_menu *menu);
// pop a menu from the stack
static void stack_pop(running_machine &machine);
// test if one of the menus in the stack requires hide disable
static bool 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(mame_ui_manager &mui, render_container *container, UINT32 state);
// Used by sliders
void validate_selection(int scandir);
static ui_menu *menu_stack;
void do_handle();
// To be reimplemented in the menu subclass
virtual void populate() = 0;
// To be reimplemented in the menu subclass
virtual void handle() = 0;
// test if search is active
virtual bool menu_has_search_active() { return false; }
private:
static ui_menu *menu_free;
static std::unique_ptr<bitmap_rgb32> hilight_bitmap;
static render_texture *hilight_texture, *arrow_texture;
bool m_special_main_menu;
mame_ui_manager &m_ui; // UI we are attached to
void draw(UINT32 flags, float x0 = 0.0f, float y0 = 0.0f);
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:
// tab navigation
enum class focused_menu
{
main,
left,
righttop,
rightbottom
};
focused_menu m_focus;
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);
// get arrows status
template <typename _T1, typename _T2, typename _T3>
UINT32 get_arrow_flags(_T1 min, _T2 max, _T3 actual)
{
if (max == 0)
return 0;
else
return ((actual <= min) ? MENU_FLAG_RIGHT_ARROW : (actual >= max ? MENU_FLAG_LEFT_ARROW : (MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW)));
}
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;
// draw right box
float draw_right_box_title(float x1, float y1, float x2, float y2);
// draw arrow
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, bool software);
// 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);
int visible_lines; // main box visible lines
int right_visible_lines; // right box lines
static std::unique_ptr<bitmap_argb32> snapx_bitmap;
static render_texture *snapx_texture;
static std::unique_ptr<bitmap_rgb32> hilight_main_bitmap;
static render_texture *hilight_main_texture;
private:
// mouse button held down
bool m_pressed = false;
osd_ticks_t m_repeat = 0;
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 bitmap_argb32 *icons_bitmap[];
static render_texture *icons_texture[];
// toolbar
static bitmap_argb32 *toolbar_bitmap[], *sw_toolbar_bitmap[];
static render_texture *toolbar_texture[], *sw_toolbar_texture[];
// draw game list
void draw_select_game(UINT32 flags);
// 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(UINT32 flags);
void 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);
};
#endif // __UI_MENU_H__