summaryrefslogblamecommitdiffstatshomepage
path: root/src/frontend/mame/ui/menu.h
blob: d1e3b50089806e0f4e25f54376c5186e3151ec12 (plain) (tree)
1
2
3
4
5
6
7
8

                                                               

                                                                            
             
 
                                               
 



                                                                            

                               
 
                  
                        
 


                     
                 
 
 

              
                                                                            
                    

                                                                            
          

       

















                                                
 

                                                                   
 








                                                                                            
 
                                                   


                                                                                                                                        
 
                                                  
                                                                                                                     
 
                                                                
                                        
 
                                                                 
                                                    
 
                                                                  
                              
 
                                                                
                                                   
 
                                                                        
                                          
 
                                
                                                                     
                                                   
 
                                               
                                                          
 
                                         











                                                                                                        
 
                                    
                                                        
 
                                                                      
                                                  
 
                    

                                                                                                                  
                     

                                                                                                                                       
                         
                                                                                    
 
                          
                                             
 
                         
 
                                                   
                                    
 
                                                   
                                  
 


                                                               
        
                                                            
                                                               
 
                                                                  
                             
                                         
                                       
 

                                                                 
                                                                                                                       
 
       

                              








                                             












                                                                                                                     
                                                                        







                                                            
                                                                                                                                               


          


















                                         








                               







                                                                                                                                                  
























                                                                                                                        

          




                                                        
                            
 










                                                                                                        
                                                          

                                                               








                                                                                                                                     
                                                                                                               
 

                                                                                                                                                        

                                                                                                           
 


                                                          


                                                                                





                                                           

                                                                 
 
        






                                                     
 



                                                                  
                                                                                         
                                                            
                                                                        

                                               





                                                                        
                  
                                                                                             


                                                                        
                                            
 
                            

                                 


                              





                                                                       
                                  
 
                                                                            
                                                                                                                        







                                                                        
                                        
                                                            


                                                
  
 


                                  
// 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 MAME_FRONTEND_UI_MENU_H
#define MAME_FRONTEND_UI_MENU_H

#include "ui/ui.h"
#include "ui/menuitem.h"

#include "language.h"
#include "render.h"

#include <memory>


namespace ui {

/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

class menu
{
public:
	// flags for menu items
	enum
	{
		FLAG_LEFT_ARROW     = (1 << 0),
		FLAG_RIGHT_ARROW    = (1 << 1),
		FLAG_INVERT         = (1 << 2),
		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)
	};

	virtual ~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
	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
	std::vector<menu_item>  item;         // array of items

	// append a new item to the end of the menu
	void item_append(const char *text, const char *subtext, UINT32 flags, void *ref, menu_item_type type = menu_item_type::UNKNOWN);
	void item_append(menu_item item);
	void item_append(menu_item_type type);

	// 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;

	// 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
	template <typename T, typename... Params>
	static void stack_push(Params &&... args)
	{
		stack_push(std::unique_ptr<menu>(global_alloc_clear<T>(std::forward<Params>(args)...)));
	}
	template <typename T, typename... Params>
	static void stack_push_special_main(Params &&... args)
	{
		std::unique_ptr<menu> ptr(global_alloc_clear<T>(std::forward<Params>(args)...));
		ptr->set_special_main_menu(true);
		stack_push(std::move(ptr));
	}

	// 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(render_container *container, mame_ui_manager &mui);

	// Used by sliders
	void validate_selection(int scandir);

	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 std::unique_ptr<bitmap_rgb32> hilight_bitmap;
	static render_texture *hilight_texture, *arrow_texture;

	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:
	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) ? FLAG_RIGHT_ARROW : (actual >= max ? FLAG_LEFT_ARROW : (FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW)));
	}

protected:
	// flags to pass to process
	enum
	{
		PROCESS_NOKEYS      = 1,
		PROCESS_LR_REPEAT   = 2,
		PROCESS_CUSTOM_ONLY = 4,
		PROCESS_ONLYCHAR    = 8,
		PROCESS_NOINPUT     = 16,
		PROCESS_NOIMAGE     = 32
	};

	// options for reset
	enum class reset_options
	{
		SELECT_FIRST,
		REMEMBER_POSITION,
		REMEMBER_REF
	};

	// tab navigation
	enum class focused_menu
	{
		main,
		left,
		righttop,
		rightbottom
	};

	// menu-related events
	struct event
	{
		void                *itemref;   // reference for the selected item
		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

		bool is_char_printable() const
		{
			return
				!(0x0001f >= unichar) &&                            // C0 control
				!((0x0007f <= unichar) && (0x0009f >= unichar)) &&  // DEL and C1 control
				!((0x0fdd0 <= unichar) && (0x0fddf >= unichar)) &&  // noncharacters
				!(0x0fffe == (unichar & 0x0ffff)) &&                // byte-order detection noncharacter
				!(0x0ffff == (unichar & 0x0ffff));                  // the other noncharacter
		}

		template <std::size_t N>
		bool append_char(char (&buffer)[N], std::size_t offset) const
		{
			auto const chlen = utf8_from_uchar(&buffer[offset], N - offset - 1, unichar);
			if (0 < chlen)
			{
				buffer[offset + chlen] = '\0';
				return true;
			}
			else
			{
				return false;
			}
		}
	};

	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;

	menu(mame_ui_manager &mui, render_container *container);

	// free all items in the menu, and all memory allocated from the memory pool
	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); }

	// 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; }

	// 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);

	// 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
	virtual bool custom_mouse_down() { return false; }

	template <typename T>
	static T *topmost_menu() { return dynamic_cast<T *>(menu_stack.get()); }

	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:
	struct pool
	{
		pool   *next;    // chain to next one
		UINT8  *top;     // top of the pool
		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
	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);

	// 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                    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;
	static std::vector<const game_driver *> m_old_icons;

	static std::unique_ptr<menu> menu_stack;
	static std::unique_ptr<menu> menu_free;
};

} // namespace ui

#endif  // MAME_FRONTEND_UI_MENU_H