branches/old_menus/src/emu/inpttype.h
| r29605 | r29606 | |
| 709 | 709 | INPUT_PORT_DIGITAL_TYPE( 0, OTHER, KEYBOARD, "Keyboard", input_seq() ) |
| 710 | 710 | } |
| 711 | 711 | |
| 712 | | void construct_core_types_ui_general(simple_list<input_type_entry> &typelist) |
| 712 | void construct_core_types_UI(simple_list<input_type_entry> &typelist) |
| 713 | 713 | { |
| 714 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_CONFIGURE, "Config Menu", input_seq(KEYCODE_TAB, input_seq::or_code, KEYCODE_SCRLOCK) ) |
| 715 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_UP, "UI Up", input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) |
| 716 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_DOWN, "UI Down", input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) |
| 717 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_LEFT, "UI Left", input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) |
| 718 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_RIGHT, "UI Right", input_seq(KEYCODE_RIGHT, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) |
| 719 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_HOME, "UI Home", input_seq(KEYCODE_HOME) ) |
| 720 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_END, "UI End", input_seq(KEYCODE_END) ) |
| 721 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_PAGE_UP, "UI Page Up", input_seq(KEYCODE_PGUP) ) |
| 722 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_PAGE_DOWN, "UI Page Down", input_seq(KEYCODE_PGDN) ) |
| 723 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_SELECT, "UI Select", input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) |
| 724 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_CANCEL, "UI Cancel", input_seq(KEYCODE_ESC) ) |
| 725 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_DISPLAY_COMMENT, "UI Display Comment", input_seq(KEYCODE_SPACE) ) |
| 726 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_CLEAR, "UI Clear", input_seq(KEYCODE_DEL) ) |
| 727 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_ZOOM_IN, "UI Zoom In", input_seq(KEYCODE_EQUALS) ) |
| 728 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_ZOOM_OUT, "UI Zoom Out", input_seq(KEYCODE_MINUS) ) |
| 729 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_PREV_GROUP, "UI Previous Group", input_seq(KEYCODE_OPENBRACE) ) |
| 730 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, UI_NEXT_GROUP, "UI Next Group", input_seq(KEYCODE_CLOSEBRACE) ) |
| 714 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ON_SCREEN_DISPLAY,"On Screen Display", input_seq(KEYCODE_TILDE) ) |
| 715 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DEBUG_BREAK, "Break in Debugger", input_seq(KEYCODE_TILDE) ) |
| 716 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CONFIGURE, "Config Menu", input_seq(KEYCODE_TAB) ) |
| 717 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAUSE, "Pause", input_seq(KEYCODE_P) ) |
| 718 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RESET_MACHINE, "Reset Game", input_seq(KEYCODE_F3, KEYCODE_LSHIFT) ) |
| 719 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SOFT_RESET, "Soft Reset", input_seq(KEYCODE_F3, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 720 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SHOW_GFX, "Show Gfx", input_seq(KEYCODE_F4) ) |
| 721 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FRAMESKIP_DEC, "Frameskip Dec", input_seq(KEYCODE_F8) ) |
| 722 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FRAMESKIP_INC, "Frameskip Inc", input_seq(KEYCODE_F9) ) |
| 723 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_THROTTLE, "Throttle", input_seq(KEYCODE_F10) ) |
| 724 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FAST_FORWARD, "Fast Forward", input_seq(KEYCODE_INSERT) ) |
| 725 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SHOW_FPS, "Show FPS", input_seq(KEYCODE_F11, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 726 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SNAPSHOT, "Save Snapshot", input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 727 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RECORD_MOVIE, "Record Movie", input_seq(KEYCODE_F12, KEYCODE_LSHIFT) ) |
| 728 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_CHEAT, "Toggle Cheat", input_seq(KEYCODE_F6) ) |
| 729 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_UP, "UI Up", input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) |
| 730 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DOWN, "UI Down", input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) |
| 731 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LEFT, "UI Left", input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) |
| 732 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RIGHT, "UI Right", input_seq(KEYCODE_RIGHT, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) |
| 733 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_HOME, "UI Home", input_seq(KEYCODE_HOME) ) |
| 734 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_END, "UI End", input_seq(KEYCODE_END) ) |
| 735 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_UP, "UI Page Up", input_seq(KEYCODE_PGUP) ) |
| 736 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_DOWN, "UI Page Down", input_seq(KEYCODE_PGDN) ) |
| 737 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SELECT, "UI Select", input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) |
| 738 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CANCEL, "UI Cancel", input_seq(KEYCODE_ESC) ) |
| 739 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DISPLAY_COMMENT, "UI Display Comment", input_seq(KEYCODE_SPACE) ) |
| 740 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CLEAR, "UI Clear", input_seq(KEYCODE_DEL) ) |
| 741 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ZOOM_IN, "UI Zoom In", input_seq(KEYCODE_EQUALS) ) |
| 742 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ZOOM_OUT, "UI Zoom Out", input_seq(KEYCODE_MINUS) ) |
| 743 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PREV_GROUP, "UI Previous Group", input_seq(KEYCODE_OPENBRACE) ) |
| 744 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_NEXT_GROUP, "UI Next Group", input_seq(KEYCODE_CLOSEBRACE) ) |
| 745 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ROTATE, "UI Rotate", input_seq(KEYCODE_R) ) |
| 746 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SHOW_PROFILER, "Show Profiler", input_seq(KEYCODE_F11, KEYCODE_LSHIFT) ) |
| 747 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_UI, "UI Toggle", input_seq(KEYCODE_SCRLOCK, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 748 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PASTE, "UI Paste Text", input_seq(KEYCODE_SCRLOCK, KEYCODE_LSHIFT) ) |
| 749 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_DEBUG, "Toggle Debugger", input_seq(KEYCODE_F5) ) |
| 750 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SAVE_STATE, "Save State", input_seq(KEYCODE_F7, KEYCODE_LSHIFT) ) |
| 751 | INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LOAD_STATE, "Load State", input_seq(KEYCODE_F7, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 731 | 752 | } |
| 732 | 753 | |
| 733 | | void construct_core_types_ui_shortcuts(simple_list<input_type_entry> &typelist) |
| 734 | | { |
| 735 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_ON_SCREEN_DISPLAY,"On Screen Display", input_seq(KEYCODE_TILDE) ) |
| 736 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_DEBUG_BREAK, "Break in Debugger", input_seq(KEYCODE_TILDE) ) |
| 737 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_PAUSE, "Pause", input_seq(KEYCODE_P) ) |
| 738 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_RESET_MACHINE, "Reset Game", input_seq(KEYCODE_F3, KEYCODE_LSHIFT) ) |
| 739 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_SOFT_RESET, "Soft Reset", input_seq(KEYCODE_F3, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 740 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_EXIT, "Exit", input_seq(KEYCODE_ESC) ) |
| 741 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_SHOW_GFX, "Show Gfx", input_seq(KEYCODE_F4) ) |
| 742 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_FRAMESKIP_DEC, "Frameskip Dec", input_seq(KEYCODE_F8) ) |
| 743 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_FRAMESKIP_INC, "Frameskip Inc", input_seq(KEYCODE_F9) ) |
| 744 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_THROTTLE, "Throttle", input_seq(KEYCODE_F10) ) |
| 745 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_FAST_FORWARD, "Fast Forward", input_seq(KEYCODE_INSERT) ) |
| 746 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_SHOW_FPS, "Show FPS", input_seq(KEYCODE_F11, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 747 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_SNAPSHOT, "Save Snapshot", input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 748 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_RECORD_MOVIE, "Record Movie", input_seq(KEYCODE_F12, KEYCODE_LSHIFT) ) |
| 749 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_TOGGLE_CHEAT, "Toggle Cheat", input_seq(KEYCODE_F6) ) |
| 750 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_ROTATE, "UI Rotate", input_seq(KEYCODE_R) ) |
| 751 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_SHOW_PROFILER, "Show Profiler", input_seq(KEYCODE_F11, KEYCODE_LSHIFT) ) |
| 752 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_PASTE, "UI Paste Text", input_seq(KEYCODE_SCRLOCK, KEYCODE_LSHIFT) ) |
| 753 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_TOGGLE_DEBUG, "Toggle Debugger", input_seq(KEYCODE_F5) ) |
| 754 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_SAVE_STATE, "Save State", input_seq(KEYCODE_F7, KEYCODE_LSHIFT) ) |
| 755 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_SHORTCUT, UI_LOAD_STATE, "Load State", input_seq(KEYCODE_F7, input_seq::not_code, KEYCODE_LSHIFT) ) |
| 756 | | } |
| 757 | | |
| 758 | 754 | void construct_core_types_OSD(simple_list<input_type_entry> &typelist) |
| 759 | 755 | { |
| 760 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_1, NULL, input_seq() ) |
| 761 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_2, NULL, input_seq() ) |
| 762 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_3, NULL, input_seq() ) |
| 763 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_4, NULL, input_seq() ) |
| 764 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_5, NULL, input_seq() ) |
| 765 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_6, NULL, input_seq() ) |
| 766 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_7, NULL, input_seq() ) |
| 767 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_8, NULL, input_seq() ) |
| 768 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_9, NULL, input_seq() ) |
| 769 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_10, NULL, input_seq() ) |
| 770 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_11, NULL, input_seq() ) |
| 771 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_12, NULL, input_seq() ) |
| 772 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_13, NULL, input_seq() ) |
| 773 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_14, NULL, input_seq() ) |
| 774 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_15, NULL, input_seq() ) |
| 775 | | INPUT_PORT_DIGITAL_TYPE( 0, UI_GENERAL, OSD_16, NULL, input_seq() ) |
| 756 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_1, NULL, input_seq() ) |
| 757 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_2, NULL, input_seq() ) |
| 758 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_3, NULL, input_seq() ) |
| 759 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_4, NULL, input_seq() ) |
| 760 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_5, NULL, input_seq() ) |
| 761 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_6, NULL, input_seq() ) |
| 762 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_7, NULL, input_seq() ) |
| 763 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_8, NULL, input_seq() ) |
| 764 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_9, NULL, input_seq() ) |
| 765 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_10, NULL, input_seq() ) |
| 766 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_11, NULL, input_seq() ) |
| 767 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_12, NULL, input_seq() ) |
| 768 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_13, NULL, input_seq() ) |
| 769 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_14, NULL, input_seq() ) |
| 770 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_15, NULL, input_seq() ) |
| 771 | INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_16, NULL, input_seq() ) |
| 776 | 772 | } |
| 777 | 773 | |
| 778 | 774 | void construct_core_types_invalid(simple_list<input_type_entry> &typelist) |
| r29605 | r29606 | |
| 827 | 823 | construct_core_types_mouse_X(typelist); |
| 828 | 824 | construct_core_types_mouse_Y(typelist); |
| 829 | 825 | construct_core_types_keypad(typelist); |
| 830 | | construct_core_types_ui_general(typelist); |
| 831 | | construct_core_types_ui_shortcuts(typelist); |
| 826 | construct_core_types_UI(typelist); |
| 832 | 827 | construct_core_types_OSD(typelist); |
| 833 | 828 | construct_core_types_invalid(typelist); |
| 834 | 829 | } |
branches/old_menus/src/emu/ui/menubar.h
| r29605 | r29606 | |
| 1 | | /*************************************************************************** |
| 2 | | |
| 3 | | menubar.h |
| 4 | | |
| 5 | | Internal MAME menu bar for the user interface. |
| 6 | | |
| 7 | | Copyright Nicola Salmoria and the MAME Team. |
| 8 | | Visit http://mamedev.org for licensing and usage restrictions. |
| 9 | | |
| 10 | | ***************************************************************************/ |
| 11 | | |
| 12 | | #pragma once |
| 13 | | |
| 14 | | #ifndef __UI_MENUBAR_H__ |
| 15 | | #define __UI_MENUBAR_H__ |
| 16 | | |
| 17 | | #include "render.h" |
| 18 | | |
| 19 | | |
| 20 | | //************************************************************************** |
| 21 | | // MENU BAR |
| 22 | | //************************************************************************** |
| 23 | | |
| 24 | | class ui_menubar |
| 25 | | { |
| 26 | | public: |
| 27 | | ui_menubar(running_machine &machine); |
| 28 | | virtual ~ui_menubar(); |
| 29 | | |
| 30 | | // menu item |
| 31 | | class menu_item |
| 32 | | { |
| 33 | | public: |
| 34 | | menu_item(ui_menubar &menubar, const char *text = NULL, menu_item *parent = NULL, bool is_invokable = false, int shortcut = 0); |
| 35 | | virtual ~menu_item(); |
| 36 | | |
| 37 | | // methods |
| 38 | | menu_item &append(const char *text); |
| 39 | | void append_separator(); |
| 40 | | bool is_child_of(menu_item *that) const; |
| 41 | | virtual void invoke(); |
| 42 | | void clear_area_recursive(); |
| 43 | | menu_item *find_point(float x, float y); |
| 44 | | menu_item &find_child(const char *target); |
| 45 | | const char *shortcut_text(); |
| 46 | | float shortcut_text_width(); |
| 47 | | void sensible_seq_name(astring &text, const input_seq &seq); |
| 48 | | |
| 49 | | // template methods; look I tried to use delegate.h but I got humbled... |
| 50 | | template<class _Target> menu_item &append(const char *text, void (_Target::*callback)(), _Target &obj, int shortcut = 0) |
| 51 | | { |
| 52 | | menu_item *child = new invokable_menu_item<_Target>(m_menubar, text, this, callback, obj, shortcut); |
| 53 | | initialize(*child); |
| 54 | | return *child; |
| 55 | | } |
| 56 | | template<class _Target, typename _Arg> menu_item &append(const char *text, void (_Target::*callback)(_Arg), _Target &obj, _Arg arg, int shortcut = 0) |
| 57 | | { |
| 58 | | menu_item *child = new arg_invokable_menu_item<_Target, _Arg>(m_menubar, text, this, callback, obj, arg, shortcut); |
| 59 | | initialize(*child); |
| 60 | | return *child; |
| 61 | | } |
| 62 | | template<class _Target, typename _Arg1, typename _Arg2> menu_item &append(const char *text, void (_Target::*callback)(_Arg1, _Arg2), _Target &obj, _Arg1 arg1, _Arg2 arg2, int shortcut = 0) |
| 63 | | { |
| 64 | | menu_item *child = new arg2_invokable_menu_item<_Target, _Arg1, _Arg2>(m_menubar, text, this, callback, obj, arg1, arg2, shortcut); |
| 65 | | initialize(*child); |
| 66 | | return *child; |
| 67 | | } |
| 68 | | template<class _Target> menu_item &append(const char *text, void (_Target::*set_callback)(bool), bool (_Target::*get_callback)() const, _Target &obj, int shortcut = 0) |
| 69 | | { |
| 70 | | // tailored for a toggle |
| 71 | | bool current_value = ((obj).*(get_callback))(); |
| 72 | | menu_item &menu = append(text, set_callback, obj, !current_value, shortcut); |
| 73 | | menu.set_checked(current_value); |
| 74 | | return menu; |
| 75 | | } |
| 76 | | template<class _Target, typename _Arg> menu_item &append(const char *text, void (_Target::*set_callback)(_Arg), _Arg (_Target::*get_callback)() const, _Target &obj, _Arg arg, int shortcut = 0) |
| 77 | | { |
| 78 | | // tailored for a set operation |
| 79 | | _Arg current_value = ((obj).*(get_callback))(); |
| 80 | | menu_item &menu = append(text, set_callback, obj, arg, shortcut); |
| 81 | | menu.set_checked(current_value == arg); |
| 82 | | return menu; |
| 83 | | } |
| 84 | | |
| 85 | | // getters |
| 86 | | bool is_empty() const { return !m_first_child; } |
| 87 | | bool is_invokable() const { return m_is_invokable; } |
| 88 | | bool is_checked() const { return m_is_checked; } |
| 89 | | bool is_enabled() const { return m_is_enabled; } |
| 90 | | bool is_separator() const { return m_is_separator; } |
| 91 | | bool has_children() const { return m_first_child ? true : false; } |
| 92 | | int shortcut() const { return m_shortcut; } |
| 93 | | const astring &text() const { return m_text; } |
| 94 | | menu_item *parent() { return m_parent; } |
| 95 | | menu_item *child() { return m_first_child; } |
| 96 | | menu_item *last_child() { return m_last_child; } |
| 97 | | menu_item *previous() { return m_previous; } |
| 98 | | menu_item *next() { return m_next; } |
| 99 | | menu_item *next_with_shortcut() { return m_next_with_shortcut; } |
| 100 | | bool is_sub_menu() const { return m_parent && m_parent->m_parent; } |
| 101 | | |
| 102 | | // setters |
| 103 | | void set_area(float x0, float y0, float x1, float y1); |
| 104 | | void clear_area() { set_area(-1, -1, -1, -1); } |
| 105 | | void set_checked(bool checked) { m_is_checked = checked; } |
| 106 | | void set_enabled(bool enabled) { m_is_enabled = enabled; } |
| 107 | | void set_text(const char *text) { m_text.cpy(text); } |
| 108 | | void set_next_with_shortcut(menu_item *item) { m_next_with_shortcut = item; } |
| 109 | | |
| 110 | | private: |
| 111 | | // private variables |
| 112 | | ui_menubar & m_menubar; |
| 113 | | astring m_text; |
| 114 | | int m_shortcut; |
| 115 | | astring m_shortcut_text; |
| 116 | | float m_shortcut_text_width; |
| 117 | | bool m_is_invokable; |
| 118 | | bool m_is_checked; |
| 119 | | bool m_is_enabled; |
| 120 | | bool m_is_separator; |
| 121 | | menu_item * m_parent; |
| 122 | | menu_item * m_first_child; |
| 123 | | menu_item * m_last_child; |
| 124 | | menu_item * m_previous; |
| 125 | | menu_item * m_next; |
| 126 | | menu_item * m_next_with_shortcut; |
| 127 | | float m_x0; |
| 128 | | float m_y0; |
| 129 | | float m_x1; |
| 130 | | float m_y1; |
| 131 | | |
| 132 | | // private methods |
| 133 | | void initialize(menu_item &child); |
| 134 | | menu_item *find_child_internal(const char *target); |
| 135 | | }; |
| 136 | | |
| 137 | | // methods |
| 138 | | virtual void reset(); |
| 139 | | virtual void handle(render_container *container); |
| 140 | | |
| 141 | | // getters |
| 142 | | bool is_visible() const { return m_menubar_visibility != MENUBAR_VISIBILITY_INVISIBLE; } |
| 143 | | bool has_selection() const { return m_selected_item != NULL; } |
| 144 | | menu_item &root_menu() { return m_menus; } |
| 145 | | |
| 146 | | protected: |
| 147 | | // implemented by child classes |
| 148 | | virtual void menubar_build_menus() = 0; |
| 149 | | virtual void menubar_draw_ui_elements() = 0; |
| 150 | | |
| 151 | | // accessors |
| 152 | | running_machine &machine() { return m_machine; } |
| 153 | | render_container *container() { return m_container; } |
| 154 | | |
| 155 | | private: |
| 156 | | // classes |
| 157 | | template<class _Target> |
| 158 | | class invokable_menu_item : public menu_item |
| 159 | | { |
| 160 | | public: |
| 161 | | invokable_menu_item(ui_menubar &menubar, const char *name, menu_item *parent, void (_Target::*callback)(), _Target &obj, int shortcut) |
| 162 | | : menu_item(menubar, name, parent, true, shortcut), m_callback(callback), m_obj(obj) |
| 163 | | { |
| 164 | | } |
| 165 | | |
| 166 | | virtual void invoke() { ((m_obj).*(m_callback))(); } |
| 167 | | |
| 168 | | private: |
| 169 | | void (_Target::*m_callback)(); |
| 170 | | _Target &m_obj; |
| 171 | | }; |
| 172 | | |
| 173 | | template<class _Target, typename _Arg> |
| 174 | | class arg_invokable_menu_item : public menu_item |
| 175 | | { |
| 176 | | public: |
| 177 | | arg_invokable_menu_item(ui_menubar &menubar, const char *name, menu_item *parent, void (_Target::*callback)(_Arg), _Target &obj, _Arg arg, int shortcut) |
| 178 | | : menu_item(menubar, name, parent, true, shortcut), m_callback(callback), m_obj(obj), m_arg(arg) |
| 179 | | { |
| 180 | | } |
| 181 | | |
| 182 | | virtual void invoke() { ((m_obj).*(m_callback))(m_arg); } |
| 183 | | |
| 184 | | private: |
| 185 | | void (_Target::*m_callback)(_Arg); |
| 186 | | _Target &m_obj; |
| 187 | | _Arg m_arg; |
| 188 | | }; |
| 189 | | |
| 190 | | template<class _Target, typename _Arg1, typename _Arg2> |
| 191 | | class arg2_invokable_menu_item : public menu_item |
| 192 | | { |
| 193 | | public: |
| 194 | | arg2_invokable_menu_item(ui_menubar &menubar, const char *name, menu_item *parent, void (_Target::*callback)(_Arg1, _Arg2), _Target &obj, _Arg1 arg1, _Arg2 arg2, int shortcut) |
| 195 | | : menu_item(menubar, name, parent, true, shortcut), m_callback(callback), m_obj(obj), m_arg1(arg1), m_arg2(arg2) |
| 196 | | { |
| 197 | | } |
| 198 | | |
| 199 | | virtual void invoke() { ((m_obj).*(m_callback))(m_arg1, m_arg2); } |
| 200 | | |
| 201 | | private: |
| 202 | | void (_Target::*m_callback)(_Arg1, _Arg2); |
| 203 | | _Target &m_obj; |
| 204 | | _Arg1 m_arg1; |
| 205 | | _Arg2 m_arg2; |
| 206 | | }; |
| 207 | | |
| 208 | | // menubar visibility |
| 209 | | enum menubar_visibility_t |
| 210 | | { |
| 211 | | MENUBAR_VISIBILITY_INVISIBLE, |
| 212 | | MENUBAR_VISIBILITY_TRANSLUCENT, |
| 213 | | MENUBAR_VISIBILITY_VISIBLE |
| 214 | | }; |
| 215 | | |
| 216 | | // instance variables |
| 217 | | running_machine & m_machine; |
| 218 | | render_container * m_container; |
| 219 | | menu_item m_menus; // the root menu item |
| 220 | | menu_item * m_shortcuted_menu_items; // list of menu items with shortcuts |
| 221 | | menu_item * m_selected_item; // current selection |
| 222 | | menu_item * m_active_item; // active menu item |
| 223 | | bool m_dragged; // have we dragged over at least one item? |
| 224 | | float m_mouse_x, m_mouse_y; |
| 225 | | bool m_mouse_button; |
| 226 | | float m_checkmark_width; |
| 227 | | osd_ticks_t m_last_mouse_move; |
| 228 | | menubar_visibility_t m_menubar_visibility; |
| 229 | | bool m_first_time; |
| 230 | | |
| 231 | | // selection walking |
| 232 | | bool walk_selection_previous(); |
| 233 | | bool walk_selection_next(); |
| 234 | | bool walk_selection_child(); |
| 235 | | bool walk_selection_parent(); |
| 236 | | bool walk_selection_escape(); |
| 237 | | bool walk_selection_previous_sub_menu(); |
| 238 | | bool walk_selection_next_sub_menu(); |
| 239 | | |
| 240 | | // miscellaneous |
| 241 | | void draw_child_menu(menu_item *menu, float x, float y); |
| 242 | | bool is_child_menu_visible(menu_item *menu) const; |
| 243 | | void draw_menu_item_text(menu_item *mi, float x0, float y0, float x1, float y1, bool decorations, const float *column_widths = NULL); |
| 244 | | bool is_highlighted_selection(menu_item *mi); |
| 245 | | bool event_loop(); |
| 246 | | bool poll_navigation_keys(); |
| 247 | | bool poll_shortcut_keys(bool swallow); |
| 248 | | bool input_pressed_safe(int key); |
| 249 | | void toggle_selection(); |
| 250 | | void invoke(menu_item *menu); |
| 251 | | bool find_mouse(float &mouse_x, float &mouse_y, bool &mouse_button); |
| 252 | | menubar_visibility_t get_menubar_visibility(); |
| 253 | | rgb_t adjust_color(rgb_t color); |
| 254 | | }; |
| 255 | | |
| 256 | | |
| 257 | | #endif /* __UI_MENUBAR_H__ */ |
branches/old_menus/src/emu/ui/emenubar.c
| r29605 | r29606 | |
| 1 | | /*************************************************************************** |
| 2 | | |
| 3 | | emenubar.c |
| 4 | | |
| 5 | | Internal MAME menu bar for the user interface. |
| 6 | | |
| 7 | | Copyright Nicola Salmoria and the MAME Team. |
| 8 | | Visit http://mamedev.org for licensing and usage restrictions. |
| 9 | | |
| 10 | | ***************************************************************************/ |
| 11 | | |
| 12 | | #include "emu.h" |
| 13 | | #include "ui/emenubar.h" |
| 14 | | #include "ui/selgame.h" |
| 15 | | #include "ui/miscmenu.h" |
| 16 | | #include "ui/filesel.h" |
| 17 | | #include "ui/imginfo.h" |
| 18 | | #include "ui/tapectrl.h" |
| 19 | | #include "ui/bbcontrl.h" |
| 20 | | #include "ui/swlist.h" |
| 21 | | #include "ui/viewgfx.h" |
| 22 | | #include "ui/barcode.h" |
| 23 | | #include "softlist.h" |
| 24 | | #include "cheat.h" |
| 25 | | |
| 26 | | |
| 27 | | //************************************************************************** |
| 28 | | // CONSTANTS |
| 29 | | //************************************************************************** |
| 30 | | |
| 31 | | #ifdef MAME_PROFILER |
| 32 | | #define HAS_PROFILER 1 |
| 33 | | #else // !MAME_PROFILER |
| 34 | | #define HAS_PROFILER 0 |
| 35 | | #endif // MAME_PROFILER |
| 36 | | |
| 37 | | |
| 38 | | //************************************************************************** |
| 39 | | // MENUBAR IMPLEMENTATION |
| 40 | | //************************************************************************** |
| 41 | | |
| 42 | | astring ui_emu_menubar::s_softlist_result; |
| 43 | | device_image_interface *ui_emu_menubar::s_softlist_image; |
| 44 | | |
| 45 | | |
| 46 | | //------------------------------------------------- |
| 47 | | // ctor |
| 48 | | //------------------------------------------------- |
| 49 | | |
| 50 | | ui_emu_menubar::ui_emu_menubar(running_machine &machine) |
| 51 | | : ui_menubar(machine) |
| 52 | | { |
| 53 | | } |
| 54 | | |
| 55 | | |
| 56 | | //------------------------------------------------- |
| 57 | | // handle |
| 58 | | //------------------------------------------------- |
| 59 | | |
| 60 | | void ui_emu_menubar::handle(render_container *container) |
| 61 | | { |
| 62 | | // check to see if we have a softlist selection |
| 63 | | if (s_softlist_result.len() > 0) |
| 64 | | { |
| 65 | | // do the load |
| 66 | | s_softlist_image->load(s_softlist_result); |
| 67 | | |
| 68 | | // clear out state |
| 69 | | s_softlist_image = NULL; |
| 70 | | s_softlist_result.reset(); |
| 71 | | } |
| 72 | | |
| 73 | | // call inherited method |
| 74 | | ui_menubar::handle(container); |
| 75 | | } |
| 76 | | |
| 77 | | |
| 78 | | //------------------------------------------------- |
| 79 | | // start_menu |
| 80 | | //------------------------------------------------- |
| 81 | | |
| 82 | | void ui_emu_menubar::start_menu(ui_menu *menu) |
| 83 | | { |
| 84 | | machine().ui().set_handler(ui_menu::ui_handler, 0); |
| 85 | | ui_menu::stack_push(menu); |
| 86 | | } |
| 87 | | |
| 88 | | |
| 89 | | //------------------------------------------------- |
| 90 | | // start_menu |
| 91 | | //------------------------------------------------- |
| 92 | | |
| 93 | | template<class _Menu> |
| 94 | | void ui_emu_menubar::start_menu() |
| 95 | | { |
| 96 | | start_menu(auto_alloc_clear(machine(), _Menu(machine(), container()))); |
| 97 | | } |
| 98 | | |
| 99 | | |
| 100 | | //------------------------------------------------- |
| 101 | | // menubar_draw_ui_elements |
| 102 | | //------------------------------------------------- |
| 103 | | |
| 104 | | void ui_emu_menubar::menubar_draw_ui_elements() |
| 105 | | { |
| 106 | | // first draw the FPS counter |
| 107 | | if (machine().ui().show_fps_counter()) |
| 108 | | { |
| 109 | | astring tempstring; |
| 110 | | machine().ui().draw_text_full(container(), machine().video().speed_text(tempstring), 0.0f, 0.0f, 1.0f, |
| 111 | | JUSTIFY_RIGHT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, NULL, NULL); |
| 112 | | } |
| 113 | | |
| 114 | | // draw the profiler if visible |
| 115 | | if (machine().ui().show_profiler()) |
| 116 | | { |
| 117 | | const char *text = g_profiler.text(machine()); |
| 118 | | machine().ui().draw_text_full(container(), text, 0.0f, 0.0f, 1.0f, JUSTIFY_LEFT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, NULL, NULL); |
| 119 | | } |
| 120 | | |
| 121 | | // check for fast forward |
| 122 | | if (machine().ioport().type_pressed(IPT_UI_FAST_FORWARD)) |
| 123 | | { |
| 124 | | machine().video().set_fastforward(true); |
| 125 | | machine().ui().show_fps_temp(0.5); |
| 126 | | } |
| 127 | | else |
| 128 | | machine().video().set_fastforward(false); |
| 129 | | |
| 130 | | } |
| 131 | | |
| 132 | | |
| 133 | | //------------------------------------------------- |
| 134 | | // menubar_build_menus |
| 135 | | //------------------------------------------------- |
| 136 | | |
| 137 | | void ui_emu_menubar::menubar_build_menus() |
| 138 | | { |
| 139 | | // build normal menus |
| 140 | | build_file_menu(); |
| 141 | | if (has_images()) |
| 142 | | build_images_menu(); |
| 143 | | build_options_menu(); |
| 144 | | build_settings_menu(); |
| 145 | | build_help_menu(); |
| 146 | | |
| 147 | | // and customize them |
| 148 | | machine().osd().customize_menubar(*this); |
| 149 | | } |
| 150 | | |
| 151 | | |
| 152 | | //------------------------------------------------- |
| 153 | | // build_file_menu |
| 154 | | //------------------------------------------------- |
| 155 | | |
| 156 | | void ui_emu_menubar::build_file_menu() |
| 157 | | { |
| 158 | | astring menu_text; |
| 159 | | menu_item &file_menu = root_menu().append("File"); |
| 160 | | |
| 161 | | // show gfx |
| 162 | | if (ui_gfx_is_relevant(machine())) |
| 163 | | file_menu.append("Show Graphics/Palette...", &ui_emu_menubar::set_ui_handler, *this, ui_gfx_ui_handler, (UINT32) machine().paused(), IPT_UI_SHOW_GFX); |
| 164 | | |
| 165 | | // save screen snapshot |
| 166 | | file_menu.append("Save Screen Snapshot(s)", &video_manager::save_active_screen_snapshots, machine().video(), IPT_UI_SNAPSHOT); |
| 167 | | |
| 168 | | // record movie |
| 169 | | menu_item &record_movie_menu = file_menu.append("Record Movie", &video_manager::toggle_record_movie, machine().video(), IPT_UI_RECORD_MOVIE); |
| 170 | | record_movie_menu.set_checked(machine().video().is_recording()); |
| 171 | | |
| 172 | | // save state |
| 173 | | file_menu.append("Save State...", &ui_emu_menubar::set_ui_handler, *this, ui_manager::ui_handler_load_save, (UINT32) LOADSAVE_SAVE, IPT_UI_SAVE_STATE); |
| 174 | | |
| 175 | | // load state |
| 176 | | file_menu.append("Load State...", &ui_emu_menubar::set_ui_handler, *this, ui_manager::ui_handler_load_save, (UINT32) LOADSAVE_LOAD, IPT_UI_LOAD_STATE); |
| 177 | | |
| 178 | | // separator |
| 179 | | file_menu.append_separator(); |
| 180 | | |
| 181 | | // paste |
| 182 | | if (machine().ioport().has_keyboard() && machine().ioport().natkeyboard().can_post()) |
| 183 | | { |
| 184 | | menu_item &paste_menu = file_menu.append("Paste", &ui_manager::paste, machine().ui(), IPT_UI_PASTE); |
| 185 | | paste_menu.set_enabled(machine().ui().can_paste()); |
| 186 | | } |
| 187 | | |
| 188 | | // pause |
| 189 | | menu_item &pause_menu = file_menu.append("Pause", &running_machine::toggle_pause, machine(), IPT_UI_PAUSE); |
| 190 | | pause_menu.set_checked(machine().paused()); |
| 191 | | |
| 192 | | // reset |
| 193 | | menu_item &reset_menu = file_menu.append("Reset"); |
| 194 | | reset_menu.append("Hard", &running_machine::schedule_hard_reset, machine(), IPT_UI_RESET_MACHINE); |
| 195 | | reset_menu.append("Soft", &running_machine::schedule_soft_reset, machine(), IPT_UI_SOFT_RESET); |
| 196 | | |
| 197 | | // separator |
| 198 | | file_menu.append_separator(); |
| 199 | | |
| 200 | | // select new game |
| 201 | | menu_text.printf("Select New %s...", emulator_info::get_capstartgamenoun()); |
| 202 | | file_menu.append(menu_text, &ui_emu_menubar::select_new_game, *this); |
| 203 | | |
| 204 | | // exit |
| 205 | | file_menu.append("Exit", &ui_manager::request_quit, machine().ui(), IPT_UI_EXIT); |
| 206 | | } |
| 207 | | |
| 208 | | |
| 209 | | //------------------------------------------------- |
| 210 | | // build_images_menu |
| 211 | | //------------------------------------------------- |
| 212 | | |
| 213 | | void ui_emu_menubar::build_images_menu() |
| 214 | | { |
| 215 | | // add the root "Images" menu |
| 216 | | menu_item &images_menu = root_menu().append("Images"); |
| 217 | | |
| 218 | | // loop through all devices |
| 219 | | image_interface_iterator iter(machine().root_device()); |
| 220 | | for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) |
| 221 | | { |
| 222 | | bool is_loaded = image->basename() != NULL; |
| 223 | | |
| 224 | | astring buffer; |
| 225 | | buffer.printf("%s (%s): \t%s", |
| 226 | | image->device().name(), |
| 227 | | image->brief_instance_name(), |
| 228 | | is_loaded ? image->basename() : "[empty]"); |
| 229 | | |
| 230 | | // append the menu item for this device |
| 231 | | menu_item &menu = images_menu.append(buffer); |
| 232 | | |
| 233 | | // software list |
| 234 | | if (image->image_interface() != NULL) |
| 235 | | { |
| 236 | | if (build_software_list_menus(menu, image)) |
| 237 | | menu.append_separator(); |
| 238 | | } |
| 239 | | |
| 240 | | // load |
| 241 | | menu.append("Load...", &ui_emu_menubar::load, *this, image); |
| 242 | | |
| 243 | | // unload |
| 244 | | menu_item &unload_menu = menu.append("Unload", &device_image_interface::unload, *image); |
| 245 | | unload_menu.set_enabled(is_loaded); |
| 246 | | |
| 247 | | // tape control |
| 248 | | cassette_image_device *cassette = dynamic_cast<cassette_image_device *>(image); |
| 249 | | if (cassette != NULL) |
| 250 | | { |
| 251 | | menu_item &control_menu = menu.append("Tape Control...", &ui_emu_menubar::tape_control, *this, cassette); |
| 252 | | control_menu.set_enabled(is_loaded); |
| 253 | | } |
| 254 | | |
| 255 | | // bitbanger control |
| 256 | | bitbanger_device *bitbanger = dynamic_cast<bitbanger_device *>(image); |
| 257 | | if (bitbanger != NULL) |
| 258 | | { |
| 259 | | menu_item &control_menu = menu.append("Bitbanger Control...", &ui_emu_menubar::bitbanger_control, *this, bitbanger); |
| 260 | | control_menu.set_enabled(is_loaded); |
| 261 | | } |
| 262 | | } |
| 263 | | } |
| 264 | | |
| 265 | | |
| 266 | | //------------------------------------------------- |
| 267 | | // build_software_list_menus |
| 268 | | //------------------------------------------------- |
| 269 | | |
| 270 | | bool ui_emu_menubar::build_software_list_menus(menu_item &menu, device_image_interface *image) |
| 271 | | { |
| 272 | | int item_count = 0; |
| 273 | | menu_item *last_menu_item = NULL; |
| 274 | | astring description; |
| 275 | | softlist_type types[] = { SOFTWARE_LIST_ORIGINAL_SYSTEM, SOFTWARE_LIST_COMPATIBLE_SYSTEM }; |
| 276 | | software_list_device_iterator softlist_iter(machine().config().root_device()); |
| 277 | | |
| 278 | | // first do "original system" softlists, then do compatible ones |
| 279 | | for (int typenum = 0; typenum < ARRAY_LENGTH(types); typenum++) |
| 280 | | { |
| 281 | | for (software_list_device *swlist = softlist_iter.first(); swlist != NULL; swlist = softlist_iter.next()) |
| 282 | | { |
| 283 | | if ((swlist->list_type() == types[typenum]) && is_softlist_relevant(swlist, image->image_interface(), description)) |
| 284 | | { |
| 285 | | // we've found a softlist; append the menu item |
| 286 | | last_menu_item = &menu.append(description, &ui_emu_menubar::select_from_software_list, *this, image, swlist); |
| 287 | | item_count++; |
| 288 | | } |
| 289 | | } |
| 290 | | } |
| 291 | | |
| 292 | | // if we only had one list, lets use a generic name |
| 293 | | if (last_menu_item != NULL && (item_count == 1)) |
| 294 | | last_menu_item->set_text("Software list..."); |
| 295 | | |
| 296 | | return item_count > 0; |
| 297 | | } |
| 298 | | |
| 299 | | |
| 300 | | //------------------------------------------------- |
| 301 | | // build_options_menu |
| 302 | | //------------------------------------------------- |
| 303 | | |
| 304 | | void ui_emu_menubar::build_options_menu() |
| 305 | | { |
| 306 | | astring menu_text; |
| 307 | | menu_item &options_menu = root_menu().append("Options"); |
| 308 | | |
| 309 | | // throttle |
| 310 | | float throttle_rates[] = { 10.0f, 5.0f, 2.0f, 1.0f, 0.5f, 0.2f, 0.1f, 0.0f }; |
| 311 | | float current_throttle_rate = machine().video().throttled() |
| 312 | | ? machine().video().throttle_rate() |
| 313 | | : 0.0f; |
| 314 | | menu_item &throttle_menu = options_menu.append("Throttle"); |
| 315 | | for (int i = 0; i < ARRAY_LENGTH(throttle_rates); i++) |
| 316 | | { |
| 317 | | const char *item = "Unthrottled"; |
| 318 | | if (throttle_rates[i] != 0) |
| 319 | | { |
| 320 | | menu_text.printf("%d%%", (int) (throttle_rates[i] * 100)); |
| 321 | | item = menu_text; |
| 322 | | } |
| 323 | | |
| 324 | | menu_item &menu = throttle_menu.append(item, &ui_emu_menubar::set_throttle_rate, *this, throttle_rates[i]); |
| 325 | | menu.set_checked(current_throttle_rate == throttle_rates[i]); |
| 326 | | } |
| 327 | | |
| 328 | | // frame skip |
| 329 | | menu_item &frameskip_menu = options_menu.append("Frame Skip"); |
| 330 | | for (int i = -1; i <= MAX_FRAMESKIP; i++) |
| 331 | | { |
| 332 | | const char *item = "Auto"; |
| 333 | | if (i >= 0) |
| 334 | | { |
| 335 | | menu_text.printf("%d", i); |
| 336 | | item = menu_text; |
| 337 | | } |
| 338 | | |
| 339 | | menu_item &menu = frameskip_menu.append(item, &video_manager::set_frameskip, machine().video(), i); |
| 340 | | menu.set_checked(machine().video().frameskip() == i); |
| 341 | | } |
| 342 | | |
| 343 | | // separator |
| 344 | | frameskip_menu.append_separator(); |
| 345 | | |
| 346 | | // increase |
| 347 | | frameskip_menu.append("Increase", &ui_manager::increase_frameskip, machine().ui(), IPT_UI_FRAMESKIP_INC); |
| 348 | | |
| 349 | | // decrease |
| 350 | | frameskip_menu.append("Decrease", &ui_manager::decrease_frameskip, machine().ui(), IPT_UI_FRAMESKIP_DEC); |
| 351 | | |
| 352 | | // show fps |
| 353 | | options_menu.append("Show Frames Per Second", &ui_manager::set_show_fps, &ui_manager::show_fps, machine().ui(), IPT_UI_SHOW_FPS); |
| 354 | | |
| 355 | | // show profiler |
| 356 | | if (HAS_PROFILER) |
| 357 | | options_menu.append("Show Profiler", &ui_manager::set_show_profiler, &ui_manager::show_profiler, machine().ui(), IPT_UI_SHOW_PROFILER); |
| 358 | | |
| 359 | | // video |
| 360 | | // do different things if we actually have multiple render targets |
| 361 | | menu_item &video_menu = options_menu.append("Video"); |
| 362 | | if (machine().render().target_by_index(1) != NULL) |
| 363 | | { |
| 364 | | // multiple targets |
| 365 | | int targetnum = 0; |
| 366 | | render_target *target; |
| 367 | | while((target = machine().render().target_by_index(targetnum)) != NULL) |
| 368 | | { |
| 369 | | astring buffer; |
| 370 | | buffer.printf("Screen #%d", targetnum++); |
| 371 | | menu_item &target_menu = options_menu.append(buffer); |
| 372 | | build_video_target_menu(target_menu, *target); |
| 373 | | } |
| 374 | | } |
| 375 | | else |
| 376 | | { |
| 377 | | // single target |
| 378 | | build_video_target_menu(video_menu, *machine().render().first_target()); |
| 379 | | } |
| 380 | | |
| 381 | | // separator |
| 382 | | options_menu.append_separator(); |
| 383 | | |
| 384 | | // slot devices |
| 385 | | slot_interface_iterator slotiter(machine().root_device()); |
| 386 | | if (slotiter.first() != NULL) |
| 387 | | options_menu.append<ui_emu_menubar>("Slot Devices...", &ui_emu_menubar::start_menu<ui_menu_slot_devices>, *this); |
| 388 | | |
| 389 | | // barcode reader |
| 390 | | barcode_reader_device_iterator bcriter(machine().root_device()); |
| 391 | | if (bcriter.first() != NULL) |
| 392 | | options_menu.append<ui_emu_menubar>("Barcode Reader...", &ui_emu_menubar::start_menu<ui_menu_barcode_reader>, *this); |
| 393 | | |
| 394 | | // network devices |
| 395 | | network_interface_iterator netiter(machine().root_device()); |
| 396 | | if (netiter.first() != NULL) |
| 397 | | options_menu.append<ui_emu_menubar>("Network Devices...", &ui_emu_menubar::start_menu<ui_menu_network_devices>, *this); |
| 398 | | |
| 399 | | // keyboard |
| 400 | | if (machine().ioport().has_keyboard() && machine().ioport().natkeyboard().can_post()) |
| 401 | | { |
| 402 | | menu_item &keyboard_menu = options_menu.append("Keyboard"); |
| 403 | | keyboard_menu.append("Emulated", &ui_manager::set_use_natural_keyboard, &ui_manager::use_natural_keyboard, machine().ui(), false); |
| 404 | | keyboard_menu.append("Natural", &ui_manager::set_use_natural_keyboard, &ui_manager::use_natural_keyboard, machine().ui(), true); |
| 405 | | } |
| 406 | | |
| 407 | | // crosshair options |
| 408 | | if (crosshair_get_usage(machine())) |
| 409 | | options_menu.append<ui_emu_menubar>("Crosshair Options...", &ui_emu_menubar::start_menu<ui_menu_crosshair>, *this); |
| 410 | | |
| 411 | | // memory card |
| 412 | | if (machine().config().m_memcard_handler != NULL) |
| 413 | | options_menu.append<ui_emu_menubar>("Memory Card...", &ui_emu_menubar::start_menu<ui_menu_memory_card>, *this); |
| 414 | | |
| 415 | | // cheat |
| 416 | | if (machine().options().cheat() && machine().cheat().first() != NULL) |
| 417 | | { |
| 418 | | options_menu.append_separator(); |
| 419 | | options_menu.append("Cheats enabled", &cheat_manager::set_enable, &cheat_manager::enabled, machine().cheat(), IPT_UI_TOGGLE_CHEAT); |
| 420 | | options_menu.append<ui_emu_menubar>("Cheat...", &ui_emu_menubar::start_menu<ui_menu_cheat>, *this); |
| 421 | | } |
| 422 | | } |
| 423 | | |
| 424 | | |
| 425 | | //------------------------------------------------- |
| 426 | | // build_video_target_menu |
| 427 | | //------------------------------------------------- |
| 428 | | |
| 429 | | void ui_emu_menubar::build_video_target_menu(menu_item &target_menu, render_target &target) |
| 430 | | { |
| 431 | | astring tempstring; |
| 432 | | const char *view_name; |
| 433 | | |
| 434 | | // add the menu items for each view |
| 435 | | for(int viewnum = 0; (view_name = target.view_name(viewnum)) != NULL; viewnum++) |
| 436 | | { |
| 437 | | // replace spaces with underscores |
| 438 | | tempstring.cpy(view_name).replace(0, "_", " "); |
| 439 | | |
| 440 | | // append the menu |
| 441 | | target_menu.append(tempstring, &render_target::set_view, &render_target::view, target, viewnum); |
| 442 | | } |
| 443 | | |
| 444 | | // separator |
| 445 | | target_menu.append_separator(); |
| 446 | | |
| 447 | | // rotation |
| 448 | | menu_item &rotation_menu = target_menu.append("Rotation"); |
| 449 | | rotation_menu.append("None", &render_target::set_orientation, &render_target::orientation, target, ROT0); |
| 450 | | rotation_menu.append("Clockwise 90", &render_target::set_orientation, &render_target::orientation, target, ROT90); |
| 451 | | rotation_menu.append("180", &render_target::set_orientation, &render_target::orientation, target, ROT180); |
| 452 | | rotation_menu.append("Counterclockwise 90", &render_target::set_orientation, &render_target::orientation, target, ROT270); |
| 453 | | |
| 454 | | // show backdrops |
| 455 | | target_menu.append("Show Backdrops", &render_target::set_backdrops_enabled, &render_target::backdrops_enabled, target); |
| 456 | | |
| 457 | | // show overlay |
| 458 | | target_menu.append("Show Overlays", &render_target::set_overlays_enabled, &render_target::overlays_enabled, target); |
| 459 | | |
| 460 | | // show bezel |
| 461 | | target_menu.append("Show Bezels", &render_target::set_bezels_enabled, &render_target::bezels_enabled, target); |
| 462 | | |
| 463 | | // show cpanel |
| 464 | | target_menu.append("Show CPanels", &render_target::set_cpanels_enabled, &render_target::cpanels_enabled, target); |
| 465 | | |
| 466 | | // show marquee |
| 467 | | target_menu.append("Show Marquees", &render_target::set_marquees_enabled, &render_target::marquees_enabled, target); |
| 468 | | |
| 469 | | // view |
| 470 | | menu_item &view_menu = target_menu.append("View"); |
| 471 | | view_menu.append("Cropped", &render_target::set_zoom_to_screen, &render_target::zoom_to_screen, target, true); |
| 472 | | view_menu.append("Full", &render_target::set_zoom_to_screen, &render_target::zoom_to_screen, target, false); |
| 473 | | } |
| 474 | | |
| 475 | | |
| 476 | | //------------------------------------------------- |
| 477 | | // build_settings_menu |
| 478 | | //------------------------------------------------- |
| 479 | | |
| 480 | | void ui_emu_menubar::build_settings_menu() |
| 481 | | { |
| 482 | | astring menu_text; |
| 483 | | menu_item &settings_menu = root_menu().append("Settings"); |
| 484 | | |
| 485 | | // general input |
| 486 | | // TODO - BREAK THIS APART? |
| 487 | | settings_menu.append<ui_emu_menubar>("General Input...", &ui_emu_menubar::start_menu<ui_menu_input_groups>, *this); |
| 488 | | |
| 489 | | // game input |
| 490 | | menu_text.printf("%s Input...", emulator_info::get_capstartgamenoun()); |
| 491 | | settings_menu.append<ui_emu_menubar>(menu_text, &ui_emu_menubar::start_menu<ui_menu_input_specific>, *this); |
| 492 | | |
| 493 | | // analog controls |
| 494 | | if (machine().ioport().has_analog()) |
| 495 | | settings_menu.append<ui_emu_menubar>("Analog Controls...", &ui_emu_menubar::start_menu<ui_menu_analog>, *this); |
| 496 | | |
| 497 | | // dip switches |
| 498 | | if (machine().ioport().has_dips()) |
| 499 | | settings_menu.append<ui_emu_menubar>("Dip Switches...", &ui_emu_menubar::start_menu<ui_menu_settings_dip_switches>, *this); |
| 500 | | |
| 501 | | // driver configuration |
| 502 | | if (machine().ioport().has_configs()) |
| 503 | | { |
| 504 | | menu_text.printf("%s Configuration...", emulator_info::get_capstartgamenoun()); |
| 505 | | settings_menu.append<ui_emu_menubar>(menu_text, &ui_emu_menubar::start_menu<ui_menu_settings_driver_config>, *this); |
| 506 | | } |
| 507 | | |
| 508 | | // bios selection |
| 509 | | if (machine().ioport().has_bioses()) |
| 510 | | settings_menu.append<ui_emu_menubar>("Bios Selection...", &ui_emu_menubar::start_menu<ui_menu_bios_selection>, *this); |
| 511 | | |
| 512 | | // sliders |
| 513 | | settings_menu.append<ui_emu_menubar>("Sliders...", &ui_emu_menubar::start_menu<ui_menu_sliders>, *this, IPT_UI_ON_SCREEN_DISPLAY); |
| 514 | | } |
| 515 | | |
| 516 | | |
| 517 | | //------------------------------------------------- |
| 518 | | // build_help_menu |
| 519 | | //------------------------------------------------- |
| 520 | | |
| 521 | | void ui_emu_menubar::build_help_menu() |
| 522 | | { |
| 523 | | astring menu_text; |
| 524 | | menu_item &help_menu = root_menu().append("Help"); |
| 525 | | |
| 526 | | // bookkeeping info |
| 527 | | help_menu.append<ui_emu_menubar>("Bookkeeping info...", &ui_emu_menubar::start_menu<ui_menu_bookkeeping>, *this); |
| 528 | | |
| 529 | | // game info |
| 530 | | menu_text.printf("%s Information...", emulator_info::get_capstartgamenoun()); |
| 531 | | help_menu.append<ui_emu_menubar>(menu_text, &ui_emu_menubar::start_menu<ui_menu_game_info>, *this); |
| 532 | | |
| 533 | | // image information |
| 534 | | image_interface_iterator imgiter(machine().root_device()); |
| 535 | | if (imgiter.first() != NULL) |
| 536 | | help_menu.append<ui_emu_menubar>("Image Information...", &ui_emu_menubar::start_menu<ui_menu_image_info>, *this); |
| 537 | | } |
| 538 | | |
| 539 | | |
| 540 | | //------------------------------------------------- |
| 541 | | // is_softlist_relevant |
| 542 | | //------------------------------------------------- |
| 543 | | |
| 544 | | bool ui_emu_menubar::is_softlist_relevant(software_list_device *swlist, const char *interface, astring &list_description) |
| 545 | | { |
| 546 | | bool result = false; |
| 547 | | |
| 548 | | for (software_info *swinfo = swlist->first_software_info(); swinfo != NULL; swinfo = swinfo->next()) |
| 549 | | { |
| 550 | | software_part *part = swinfo->find_part(NULL, NULL); |
| 551 | | if (part->matches_interface(interface)) |
| 552 | | { |
| 553 | | list_description.printf("%s...", swlist->description()); |
| 554 | | result = true; |
| 555 | | break; |
| 556 | | } |
| 557 | | } |
| 558 | | |
| 559 | | return result; |
| 560 | | } |
| 561 | | |
| 562 | | |
| 563 | | //------------------------------------------------- |
| 564 | | // set_ui_handler |
| 565 | | //------------------------------------------------- |
| 566 | | |
| 567 | | void ui_emu_menubar::set_ui_handler(ui_callback callback, UINT32 param) |
| 568 | | { |
| 569 | | // first pause |
| 570 | | machine().pause(); |
| 571 | | |
| 572 | | // and transfer control |
| 573 | | machine().ui().set_handler(callback, param); |
| 574 | | } |
| 575 | | |
| 576 | | |
| 577 | | //------------------------------------------------- |
| 578 | | // select_new_game |
| 579 | | //------------------------------------------------- |
| 580 | | |
| 581 | | void ui_emu_menubar::select_new_game() |
| 582 | | { |
| 583 | | start_menu(auto_alloc_clear(machine(), ui_menu_select_game(machine(), container(), machine().system().name))); |
| 584 | | } |
| 585 | | |
| 586 | | |
| 587 | | //------------------------------------------------- |
| 588 | | // select_from_software_list |
| 589 | | //------------------------------------------------- |
| 590 | | |
| 591 | | void ui_emu_menubar::select_from_software_list(device_image_interface *image, software_list_device *swlist) |
| 592 | | { |
| 593 | | s_softlist_image = image; |
| 594 | | start_menu(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container(), swlist, image->image_interface(), s_softlist_result))); |
| 595 | | } |
| 596 | | |
| 597 | | |
| 598 | | //------------------------------------------------- |
| 599 | | // tape_control |
| 600 | | //------------------------------------------------- |
| 601 | | |
| 602 | | void ui_emu_menubar::tape_control(cassette_image_device *image) |
| 603 | | { |
| 604 | | start_menu(auto_alloc_clear(machine(), ui_menu_mess_tape_control(machine(), container(), image))); |
| 605 | | } |
| 606 | | |
| 607 | | |
| 608 | | //------------------------------------------------- |
| 609 | | // bitbanger_control |
| 610 | | //------------------------------------------------- |
| 611 | | |
| 612 | | void ui_emu_menubar::bitbanger_control(bitbanger_device *image) |
| 613 | | { |
| 614 | | start_menu(auto_alloc_clear(machine(), ui_menu_mess_bitbanger_control(machine(), container(), image))); |
| 615 | | } |
| 616 | | |
| 617 | | |
| 618 | | //------------------------------------------------- |
| 619 | | // load |
| 620 | | //------------------------------------------------- |
| 621 | | |
| 622 | | void ui_emu_menubar::load(device_image_interface *image) |
| 623 | | { |
| 624 | | start_menu(image->get_selection_menu(machine(), container())); |
| 625 | | } |
| 626 | | |
| 627 | | |
| 628 | | //------------------------------------------------- |
| 629 | | // has_images |
| 630 | | //------------------------------------------------- |
| 631 | | |
| 632 | | bool ui_emu_menubar::has_images() |
| 633 | | { |
| 634 | | image_interface_iterator iter(machine().root_device()); |
| 635 | | return iter.first() != NULL; |
| 636 | | } |
| 637 | | |
| 638 | | |
| 639 | | //------------------------------------------------- |
| 640 | | // set_throttle_rate |
| 641 | | //------------------------------------------------- |
| 642 | | |
| 643 | | void ui_emu_menubar::set_throttle_rate(float throttle_rate) |
| 644 | | { |
| 645 | | machine().video().set_throttled(throttle_rate != 0.0); |
| 646 | | if (throttle_rate != 0.0) |
| 647 | | machine().video().set_throttle_rate(throttle_rate); |
| 648 | | } |
branches/old_menus/src/emu/ui/menubar.c
| r29605 | r29606 | |
| 1 | | /*************************************************************************** |
| 2 | | |
| 3 | | menubar.c |
| 4 | | |
| 5 | | Internal MAME menu bar for the user interface. |
| 6 | | |
| 7 | | Copyright Nicola Salmoria and the MAME Team. |
| 8 | | Visit http://mamedev.org for licensing and usage restrictions. |
| 9 | | |
| 10 | | ***************************************************************************/ |
| 11 | | |
| 12 | | #include "emu.h" |
| 13 | | #include "ui/menubar.h" |
| 14 | | #include "ui/ui.h" |
| 15 | | #include "uiinput.h" |
| 16 | | |
| 17 | | |
| 18 | | //************************************************************************** |
| 19 | | // CONSTANTS |
| 20 | | //************************************************************************** |
| 21 | | |
| 22 | | #define CHECKMARK "x " |
| 23 | | #define SEPARATOR_HEIGHT 0.25 |
| 24 | | |
| 25 | | |
| 26 | | //************************************************************************** |
| 27 | | // CLASSES |
| 28 | | //************************************************************************** |
| 29 | | |
| 30 | | class tabbed_text_iterator |
| 31 | | { |
| 32 | | public: |
| 33 | | tabbed_text_iterator(const char *text); |
| 34 | | bool next(); |
| 35 | | int index() const { return m_index; } |
| 36 | | const char *current() { return m_current; } |
| 37 | | |
| 38 | | private: |
| 39 | | astring m_buffer; |
| 40 | | const char * m_text; |
| 41 | | const char * m_current; |
| 42 | | int m_position; |
| 43 | | int m_index; |
| 44 | | }; |
| 45 | | |
| 46 | | |
| 47 | | //************************************************************************** |
| 48 | | // MENUBAR IMPLEMENTATION |
| 49 | | //************************************************************************** |
| 50 | | |
| 51 | | //------------------------------------------------- |
| 52 | | // ctor |
| 53 | | //------------------------------------------------- |
| 54 | | |
| 55 | | ui_menubar::ui_menubar(running_machine &machine) |
| 56 | | : m_machine(machine), m_menus(*this) |
| 57 | | { |
| 58 | | m_container = NULL; |
| 59 | | m_shortcuted_menu_items = NULL; |
| 60 | | m_selected_item = NULL; |
| 61 | | m_active_item = NULL; |
| 62 | | m_dragged = false; |
| 63 | | m_checkmark_width = -1; |
| 64 | | m_mouse_x = -1; |
| 65 | | m_mouse_y = -1; |
| 66 | | m_mouse_button = false; |
| 67 | | m_last_mouse_move = 0; |
| 68 | | m_first_time = true; |
| 69 | | } |
| 70 | | |
| 71 | | |
| 72 | | //------------------------------------------------- |
| 73 | | // dtor |
| 74 | | //------------------------------------------------- |
| 75 | | |
| 76 | | ui_menubar::~ui_menubar() |
| 77 | | { |
| 78 | | } |
| 79 | | |
| 80 | | |
| 81 | | //------------------------------------------------- |
| 82 | | // reset |
| 83 | | //------------------------------------------------- |
| 84 | | |
| 85 | | void ui_menubar::reset() |
| 86 | | { |
| 87 | | } |
| 88 | | |
| 89 | | |
| 90 | | //------------------------------------------------- |
| 91 | | // input_pressed_safe |
| 92 | | //------------------------------------------------- |
| 93 | | |
| 94 | | bool ui_menubar::input_pressed_safe(int key) |
| 95 | | { |
| 96 | | return (key != IPT_INVALID) && ui_input_pressed(machine(), key); |
| 97 | | } |
| 98 | | |
| 99 | | |
| 100 | | //------------------------------------------------- |
| 101 | | // handle |
| 102 | | //------------------------------------------------- |
| 103 | | |
| 104 | | void ui_menubar::handle(render_container *current_container) |
| 105 | | { |
| 106 | | m_container = current_container; |
| 107 | | |
| 108 | | // do we need to initialize the menus? |
| 109 | | if (m_menus.is_empty()) |
| 110 | | menubar_build_menus(); |
| 111 | | |
| 112 | | // measure standard string widths (if necessary) |
| 113 | | if (m_checkmark_width <= 0) |
| 114 | | m_checkmark_width = machine().ui().get_string_width(CHECKMARK); |
| 115 | | |
| 116 | | // reset screen locations of all menu items |
| 117 | | m_menus.clear_area_recursive(); |
| 118 | | |
| 119 | | // calculate visibility of the menubar |
| 120 | | m_menubar_visibility = get_menubar_visibility(); |
| 121 | | |
| 122 | | // draw conventional UI elements (e.g. - frameskip) |
| 123 | | menubar_draw_ui_elements(); |
| 124 | | |
| 125 | | float text_height = machine().ui().get_line_height(); |
| 126 | | float spacing = text_height / 10; |
| 127 | | float x = spacing; |
| 128 | | float y = spacing; |
| 129 | | |
| 130 | | for(menu_item *mi = m_menus.child(); mi != NULL; mi = mi->next()) |
| 131 | | { |
| 132 | | float width = machine().ui().get_string_width(mi->text()); |
| 133 | | |
| 134 | | machine().ui().draw_outlined_box( |
| 135 | | container(), |
| 136 | | x, |
| 137 | | y, |
| 138 | | x + width + (spacing * 2), |
| 139 | | y + text_height + (spacing * 2), |
| 140 | | adjust_color(UI_BORDER_COLOR), |
| 141 | | adjust_color(UI_BACKGROUND_COLOR)); |
| 142 | | |
| 143 | | draw_menu_item_text( |
| 144 | | mi, |
| 145 | | x + spacing, |
| 146 | | y + spacing, |
| 147 | | x + spacing + width, |
| 148 | | y + spacing + text_height, |
| 149 | | false); |
| 150 | | |
| 151 | | // child menu open? |
| 152 | | if (is_child_menu_visible(mi)) |
| 153 | | draw_child_menu(mi, x, y + text_height + (spacing * 3)); |
| 154 | | |
| 155 | | x += width + spacing * 4; |
| 156 | | } |
| 157 | | |
| 158 | | // loop while we have interesting events |
| 159 | | while(!event_loop()) |
| 160 | | { |
| 161 | | } |
| 162 | | } |
| 163 | | |
| 164 | | |
| 165 | | //------------------------------------------------- |
| 166 | | // event_loop |
| 167 | | //------------------------------------------------- |
| 168 | | |
| 169 | | bool ui_menubar::event_loop() |
| 170 | | { |
| 171 | | bool done = false; |
| 172 | | |
| 173 | | ui_event local_menu_event; |
| 174 | | if (ui_input_pop_event(machine(), &local_menu_event)) |
| 175 | | { |
| 176 | | // find the menu item we're pointing at |
| 177 | | find_mouse(m_mouse_x, m_mouse_y, m_mouse_button); |
| 178 | | menu_item *mi = m_menus.find_point(m_mouse_x, m_mouse_y); |
| 179 | | |
| 180 | | switch (local_menu_event.event_type) |
| 181 | | { |
| 182 | | case UI_EVENT_MOUSE_DOWN: |
| 183 | | if (mi != NULL) |
| 184 | | { |
| 185 | | m_selected_item = mi; |
| 186 | | m_active_item = mi; |
| 187 | | m_dragged = false; |
| 188 | | } |
| 189 | | break; |
| 190 | | |
| 191 | | case UI_EVENT_MOUSE_MOVE: |
| 192 | | // record the move |
| 193 | | m_last_mouse_move = osd_ticks(); |
| 194 | | |
| 195 | | // moving is only interesting if we have an active menu selection |
| 196 | | if (m_mouse_button && m_active_item != NULL) |
| 197 | | { |
| 198 | | // are we changing the active menu item? |
| 199 | | if (m_active_item != mi) |
| 200 | | { |
| 201 | | if (mi != NULL) |
| 202 | | m_active_item = mi->has_children() ? mi->child() : mi; |
| 203 | | m_dragged = true; |
| 204 | | done = true; |
| 205 | | } |
| 206 | | |
| 207 | | // are we changing the selection? |
| 208 | | if (m_selected_item != mi) |
| 209 | | { |
| 210 | | m_selected_item = mi; |
| 211 | | done = true; |
| 212 | | } |
| 213 | | } |
| 214 | | break; |
| 215 | | |
| 216 | | case UI_EVENT_MOUSE_UP: |
| 217 | | m_active_item = NULL; |
| 218 | | if (m_selected_item && m_selected_item == mi) |
| 219 | | { |
| 220 | | // looks like we did a mouse up on the current selection; we |
| 221 | | // should invoke or expand the current selection (whichever |
| 222 | | // may be appropriate) |
| 223 | | if (m_selected_item->is_invokable()) |
| 224 | | invoke(m_selected_item); |
| 225 | | else if (m_selected_item->has_children()) |
| 226 | | m_active_item = m_selected_item->child(); |
| 227 | | } |
| 228 | | else if (m_dragged) |
| 229 | | { |
| 230 | | m_selected_item = NULL; |
| 231 | | } |
| 232 | | done = true; |
| 233 | | break; |
| 234 | | |
| 235 | | default: |
| 236 | | break; |
| 237 | | } |
| 238 | | } |
| 239 | | |
| 240 | | if (!done) |
| 241 | | { |
| 242 | | bool navigation_input_pressed = poll_navigation_keys(); |
| 243 | | poll_shortcut_keys(navigation_input_pressed || m_first_time); |
| 244 | | m_first_time = false; |
| 245 | | done = true; |
| 246 | | } |
| 247 | | return done; |
| 248 | | } |
| 249 | | |
| 250 | | |
| 251 | | //------------------------------------------------- |
| 252 | | // poll_navigation_keys |
| 253 | | //------------------------------------------------- |
| 254 | | |
| 255 | | bool ui_menubar::poll_navigation_keys() |
| 256 | | { |
| 257 | | int code_previous_menu = IPT_INVALID; |
| 258 | | int code_next_menu = IPT_INVALID; |
| 259 | | int code_child_menu1 = IPT_INVALID; |
| 260 | | int code_child_menu2 = IPT_INVALID; |
| 261 | | int code_parent_menu = IPT_INVALID; |
| 262 | | int code_previous_sub_menu = IPT_INVALID; |
| 263 | | int code_next_sub_menu = IPT_INVALID; |
| 264 | | int code_selected = (m_selected_item && m_selected_item->is_invokable()) |
| 265 | | ? IPT_UI_SELECT |
| 266 | | : IPT_INVALID; |
| 267 | | |
| 268 | | // are we navigating the menu? |
| 269 | | if (m_selected_item != NULL) |
| 270 | | { |
| 271 | | // if so, are we in a pull down menu? |
| 272 | | if (!m_selected_item->is_sub_menu()) |
| 273 | | { |
| 274 | | // no pull down menu selected |
| 275 | | code_previous_menu = IPT_UI_LEFT; |
| 276 | | code_next_menu = IPT_UI_RIGHT; |
| 277 | | code_child_menu1 = IPT_UI_SELECT; |
| 278 | | code_child_menu2 = IPT_UI_DOWN; |
| 279 | | } |
| 280 | | else |
| 281 | | { |
| 282 | | // pull down menu selected |
| 283 | | code_previous_menu = IPT_UI_UP; |
| 284 | | code_next_menu = IPT_UI_DOWN; |
| 285 | | if (m_selected_item->child()) |
| 286 | | { |
| 287 | | code_child_menu1 = IPT_UI_SELECT; |
| 288 | | code_child_menu2 = IPT_UI_RIGHT; |
| 289 | | } |
| 290 | | code_previous_sub_menu = IPT_UI_LEFT; |
| 291 | | code_next_sub_menu = IPT_UI_RIGHT; |
| 292 | | if (m_selected_item->parent()->is_sub_menu()) |
| 293 | | code_parent_menu = IPT_UI_LEFT; |
| 294 | | } |
| 295 | | } |
| 296 | | |
| 297 | | bool result = true; |
| 298 | | if (input_pressed_safe(code_previous_menu)) |
| 299 | | result = walk_selection_previous(); |
| 300 | | else if (input_pressed_safe(code_next_menu)) |
| 301 | | result = walk_selection_next(); |
| 302 | | else if (input_pressed_safe(code_child_menu1) || input_pressed_safe(code_child_menu2)) |
| 303 | | result = walk_selection_child(); |
| 304 | | else if (input_pressed_safe(IPT_UI_CANCEL)) |
| 305 | | result = walk_selection_escape(); |
| 306 | | else if (input_pressed_safe(code_parent_menu)) |
| 307 | | result = walk_selection_parent(); |
| 308 | | else if (input_pressed_safe(code_previous_sub_menu)) |
| 309 | | result = walk_selection_previous_sub_menu(); |
| 310 | | else if (input_pressed_safe(code_next_sub_menu)) |
| 311 | | result = walk_selection_next_sub_menu(); |
| 312 | | else if (input_pressed_safe(IPT_UI_CONFIGURE)) |
| 313 | | toggle_selection(); |
| 314 | | else if (input_pressed_safe(code_selected)) |
| 315 | | invoke(m_selected_item); |
| 316 | | else |
| 317 | | result = false; // didn't do anything |
| 318 | | |
| 319 | | // if we changed something, set the active item accordingly |
| 320 | | if (result) |
| 321 | | m_active_item = m_selected_item; |
| 322 | | |
| 323 | | return result; |
| 324 | | } |
| 325 | | |
| 326 | | |
| 327 | | //------------------------------------------------- |
| 328 | | // poll_shortcut_keys |
| 329 | | //------------------------------------------------- |
| 330 | | |
| 331 | | bool ui_menubar::poll_shortcut_keys(bool swallow) |
| 332 | | { |
| 333 | | // loop through all shortcut items |
| 334 | | for (menu_item *item = m_shortcuted_menu_items; item != NULL; item = item->next_with_shortcut()) |
| 335 | | { |
| 336 | | assert(item->is_invokable()); |
| 337 | | |
| 338 | | // did we press this shortcut? |
| 339 | | if (input_pressed_safe(item->shortcut()) && !swallow) |
| 340 | | { |
| 341 | | // this shortcut was pressed and we're not swallowing them; invoke it |
| 342 | | invoke(item); |
| 343 | | return true; |
| 344 | | } |
| 345 | | } |
| 346 | | return false; |
| 347 | | } |
| 348 | | |
| 349 | | |
| 350 | | //------------------------------------------------- |
| 351 | | // toggle_selection |
| 352 | | //------------------------------------------------- |
| 353 | | |
| 354 | | void ui_menubar::toggle_selection() |
| 355 | | { |
| 356 | | m_selected_item = m_selected_item != NULL |
| 357 | | ? NULL |
| 358 | | : m_menus.child(); |
| 359 | | } |
| 360 | | |
| 361 | | |
| 362 | | //------------------------------------------------- |
| 363 | | // invoke |
| 364 | | //------------------------------------------------- |
| 365 | | |
| 366 | | void ui_menubar::invoke(menu_item *menu) |
| 367 | | { |
| 368 | | // first, we're ending the menu; pop us off first |
| 369 | | machine().ui().set_handler(NULL, 0); |
| 370 | | |
| 371 | | // and invoke the selection |
| 372 | | menu->invoke(); |
| 373 | | } |
| 374 | | |
| 375 | | |
| 376 | | //------------------------------------------------- |
| 377 | | // walk_selection_previous |
| 378 | | //------------------------------------------------- |
| 379 | | |
| 380 | | bool ui_menubar::walk_selection_previous() |
| 381 | | { |
| 382 | | if (m_selected_item) |
| 383 | | { |
| 384 | | do |
| 385 | | { |
| 386 | | m_selected_item = m_selected_item->previous() |
| 387 | | ? m_selected_item->previous() |
| 388 | | : m_selected_item->parent()->last_child(); |
| 389 | | } |
| 390 | | while(!m_selected_item->is_enabled()); |
| 391 | | } |
| 392 | | else |
| 393 | | { |
| 394 | | m_selected_item = m_menus.last_child(); |
| 395 | | } |
| 396 | | return true; |
| 397 | | } |
| 398 | | |
| 399 | | |
| 400 | | //------------------------------------------------- |
| 401 | | // walk_selection_next |
| 402 | | //------------------------------------------------- |
| 403 | | |
| 404 | | bool ui_menubar::walk_selection_next() |
| 405 | | { |
| 406 | | if (m_selected_item) |
| 407 | | { |
| 408 | | do |
| 409 | | { |
| 410 | | m_selected_item = m_selected_item->next() |
| 411 | | ? m_selected_item->next() |
| 412 | | : m_selected_item->parent()->child(); |
| 413 | | } |
| 414 | | while(!m_selected_item->is_enabled()); |
| 415 | | } |
| 416 | | else |
| 417 | | { |
| 418 | | m_selected_item = m_menus.child(); |
| 419 | | } |
| 420 | | return true; |
| 421 | | } |
| 422 | | |
| 423 | | |
| 424 | | //------------------------------------------------- |
| 425 | | // walk_selection_child |
| 426 | | //------------------------------------------------- |
| 427 | | |
| 428 | | bool ui_menubar::walk_selection_child() |
| 429 | | { |
| 430 | | bool result = false; |
| 431 | | if (m_selected_item && m_selected_item->child()) |
| 432 | | { |
| 433 | | m_selected_item = m_selected_item->child(); |
| 434 | | result = true; |
| 435 | | } |
| 436 | | return result; |
| 437 | | } |
| 438 | | |
| 439 | | |
| 440 | | //------------------------------------------------- |
| 441 | | // walk_selection_parent |
| 442 | | //------------------------------------------------- |
| 443 | | |
| 444 | | bool ui_menubar::walk_selection_parent() |
| 445 | | { |
| 446 | | bool result = false; |
| 447 | | if (m_selected_item && m_selected_item->parent() && m_selected_item->parent() != &m_menus) |
| 448 | | { |
| 449 | | m_selected_item = m_selected_item->parent(); |
| 450 | | result = true; |
| 451 | | } |
| 452 | | return result; |
| 453 | | } |
| 454 | | |
| 455 | | |
| 456 | | //------------------------------------------------- |
| 457 | | // walk_selection_escape |
| 458 | | //------------------------------------------------- |
| 459 | | |
| 460 | | bool ui_menubar::walk_selection_escape() |
| 461 | | { |
| 462 | | bool result = walk_selection_parent(); |
| 463 | | |
| 464 | | if (!result && m_selected_item != NULL) |
| 465 | | { |
| 466 | | m_selected_item = NULL; |
| 467 | | result = true; |
| 468 | | } |
| 469 | | |
| 470 | | return result; |
| 471 | | } |
| 472 | | |
| 473 | | |
| 474 | | //------------------------------------------------- |
| 475 | | // walk_selection_previous_sub_menu |
| 476 | | //------------------------------------------------- |
| 477 | | |
| 478 | | bool ui_menubar::walk_selection_previous_sub_menu() |
| 479 | | { |
| 480 | | while(walk_selection_parent()) |
| 481 | | ; |
| 482 | | bool result = walk_selection_previous(); |
| 483 | | if (result) |
| 484 | | walk_selection_child(); |
| 485 | | return result; |
| 486 | | } |
| 487 | | |
| 488 | | |
| 489 | | //------------------------------------------------- |
| 490 | | // walk_selection_next_sub_menu |
| 491 | | //------------------------------------------------- |
| 492 | | |
| 493 | | bool ui_menubar::walk_selection_next_sub_menu() |
| 494 | | { |
| 495 | | while(walk_selection_parent()) |
| 496 | | ; |
| 497 | | bool result = walk_selection_next(); |
| 498 | | if (result) |
| 499 | | walk_selection_child(); |
| 500 | | return result; |
| 501 | | } |
| 502 | | |
| 503 | | |
| 504 | | //------------------------------------------------- |
| 505 | | // draw_child_menu |
| 506 | | //------------------------------------------------- |
| 507 | | |
| 508 | | void ui_menubar::draw_child_menu(menu_item *menu, float x, float y) |
| 509 | | { |
| 510 | | float text_height = machine().ui().get_line_height(); |
| 511 | | float separator_height = text_height * SEPARATOR_HEIGHT; |
| 512 | | float spacing = text_height / 10; |
| 513 | | |
| 514 | | // calculate the maximum width and menu item count |
| 515 | | float max_widths[4] = {0, }; |
| 516 | | float total_height = (spacing * 2); |
| 517 | | float max_shortcuts_width = 0; |
| 518 | | for(menu_item *mi = menu->child(); mi != NULL; mi = mi->next()) |
| 519 | | { |
| 520 | | // aggregate the maximum width for each column |
| 521 | | tabbed_text_iterator iter(mi->text()); |
| 522 | | while(iter.next()) |
| 523 | | { |
| 524 | | float width = machine().ui().get_string_width(iter.current()); |
| 525 | | assert(iter.index() < ARRAY_LENGTH(max_widths)); |
| 526 | | max_widths[iter.index()] = MAX(max_widths[iter.index()], width); |
| 527 | | } |
| 528 | | |
| 529 | | // measure the shortcut |
| 530 | | float shortcut_width = mi->shortcut_text_width(); |
| 531 | | if (shortcut_width > 0) |
| 532 | | max_shortcuts_width = MAX(max_shortcuts_width, shortcut_width + spacing); |
| 533 | | |
| 534 | | // increase the height |
| 535 | | total_height += (mi->is_separator() ? separator_height : text_height); |
| 536 | | } |
| 537 | | |
| 538 | | // get the aggregate maximum widths across all columns |
| 539 | | float max_width = m_checkmark_width * 2 + max_shortcuts_width; |
| 540 | | for (int i = 0; i < ARRAY_LENGTH(max_widths); i++) |
| 541 | | max_width += max_widths[i]; |
| 542 | | |
| 543 | | // are we going to go over the right of the screen? |
| 544 | | float right = x + max_width + (spacing * 3); |
| 545 | | if (right > 1.0f) |
| 546 | | x = MAX(0.0f, x - (right - 1.0f)); |
| 547 | | |
| 548 | | // draw the menu outline |
| 549 | | machine().ui().draw_outlined_box( |
| 550 | | container(), |
| 551 | | x, |
| 552 | | y, |
| 553 | | x + max_width + (spacing * 2), |
| 554 | | y + total_height, |
| 555 | | adjust_color(UI_BACKGROUND_COLOR)); |
| 556 | | |
| 557 | | // draw the individual items |
| 558 | | float my = y; |
| 559 | | for(menu_item *mi = menu->child(); mi != NULL; mi = mi->next()) |
| 560 | | { |
| 561 | | if (mi->is_separator()) |
| 562 | | { |
| 563 | | // draw separator |
| 564 | | container()->add_line( |
| 565 | | x, |
| 566 | | my + spacing + separator_height / 2, |
| 567 | | x + max_width + (spacing * 2), |
| 568 | | my + spacing + separator_height / 2, |
| 569 | | separator_height / 8, |
| 570 | | adjust_color(UI_BORDER_COLOR), |
| 571 | | 0); |
| 572 | | } |
| 573 | | else |
| 574 | | { |
| 575 | | // draw normal text |
| 576 | | draw_menu_item_text( |
| 577 | | mi, |
| 578 | | x + spacing, |
| 579 | | my + spacing, |
| 580 | | x + spacing + max_width, |
| 581 | | my + spacing + text_height, |
| 582 | | true, |
| 583 | | max_widths); |
| 584 | | } |
| 585 | | |
| 586 | | // move down... |
| 587 | | my += (mi->is_separator() ? separator_height : text_height); |
| 588 | | } |
| 589 | | |
| 590 | | // draw child menus |
| 591 | | my = y; |
| 592 | | for(menu_item *mi = menu->child(); mi != NULL; mi = mi->next()) |
| 593 | | { |
| 594 | | // child menu open? |
| 595 | | if (!mi->is_separator() && is_child_menu_visible(mi)) |
| 596 | | { |
| 597 | | draw_child_menu( |
| 598 | | mi, |
| 599 | | x + max_width + (spacing * 2), |
| 600 | | my); |
| 601 | | } |
| 602 | | |
| 603 | | // move down... |
| 604 | | my += (mi->is_separator() ? separator_height : text_height); |
| 605 | | } |
| 606 | | } |
| 607 | | |
| 608 | | |
| 609 | | //------------------------------------------------- |
| 610 | | // is_child_menu_visible |
| 611 | | //------------------------------------------------- |
| 612 | | |
| 613 | | bool ui_menubar::is_child_menu_visible(menu_item *menu) const |
| 614 | | { |
| 615 | | menu_item *current_menu = m_active_item ? m_active_item : m_selected_item; |
| 616 | | return current_menu && current_menu->is_child_of(menu); |
| 617 | | } |
| 618 | | |
| 619 | | |
| 620 | | //------------------------------------------------- |
| 621 | | // draw_menu_item_text |
| 622 | | //------------------------------------------------- |
| 623 | | |
| 624 | | void ui_menubar::draw_menu_item_text(menu_item *mi, float x0, float y0, float x1, float y1, bool decorations, const float *column_widths) |
| 625 | | { |
| 626 | | // set our area |
| 627 | | mi->set_area(x0, y0, x1, y1); |
| 628 | | |
| 629 | | // choose the color |
| 630 | | rgb_t fgcolor, bgcolor; |
| 631 | | if (!mi->is_enabled()) |
| 632 | | { |
| 633 | | // disabled |
| 634 | | fgcolor = UI_UNAVAILABLE_COLOR; |
| 635 | | bgcolor = UI_TEXT_BG_COLOR; |
| 636 | | } |
| 637 | | else if (is_highlighted_selection(mi)) |
| 638 | | { |
| 639 | | // selected |
| 640 | | fgcolor = UI_SELECTED_COLOR; |
| 641 | | bgcolor = UI_SELECTED_BG_COLOR; |
| 642 | | } |
| 643 | | else if ((m_mouse_x >= x0) && (m_mouse_x < x1) && (m_mouse_y >= y0) && (m_mouse_y < y1)) |
| 644 | | { |
| 645 | | // hover |
| 646 | | fgcolor = UI_MOUSEOVER_COLOR; |
| 647 | | bgcolor = UI_MOUSEOVER_BG_COLOR; |
| 648 | | } |
| 649 | | else |
| 650 | | { |
| 651 | | // normal |
| 652 | | fgcolor = UI_TEXT_COLOR; |
| 653 | | bgcolor = UI_TEXT_BG_COLOR; |
| 654 | | } |
| 655 | | |
| 656 | | // highlight? |
| 657 | | if (bgcolor != UI_TEXT_BG_COLOR) |
| 658 | | ui_menu::highlight(container(), x0, y0, x1, y1, adjust_color(bgcolor)); |
| 659 | | |
| 660 | | // do we have to draw additional decorations? |
| 661 | | if (decorations) |
| 662 | | { |
| 663 | | // account for the checkbox |
| 664 | | if (mi->is_checked()) |
| 665 | | machine().ui().draw_text_full(container(), CHECKMARK, x0, y0, 1.0f - x0, JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, adjust_color(fgcolor), adjust_color(bgcolor)); |
| 666 | | x0 += m_checkmark_width; |
| 667 | | |
| 668 | | // expanders? |
| 669 | | if (mi->child()) |
| 670 | | { |
| 671 | | float lr_arrow_width = 0.4f * (y1 - y0) * machine().render().ui_aspect(); |
| 672 | | ui_menu::draw_arrow( |
| 673 | | container(), |
| 674 | | x1 - lr_arrow_width, |
| 675 | | y0 + (0.1f * (y1 - y0)), |
| 676 | | x1, |
| 677 | | y0 + (0.9f * (y1 - y0)), |
| 678 | | adjust_color(fgcolor), |
| 679 | | ROT90); |
| 680 | | } |
| 681 | | |
| 682 | | // shortcut? |
| 683 | | machine().ui().draw_text_full( |
| 684 | | container(), |
| 685 | | mi->shortcut_text(), |
| 686 | | x0, |
| 687 | | y0, |
| 688 | | x1 - x0, |
| 689 | | JUSTIFY_RIGHT, |
| 690 | | WRAP_WORD, |
| 691 | | DRAW_NORMAL, |
| 692 | | adjust_color(fgcolor), |
| 693 | | adjust_color(bgcolor)); |
| 694 | | } |
| 695 | | |
| 696 | | tabbed_text_iterator iter(mi->text()); |
| 697 | | while(iter.next()) |
| 698 | | { |
| 699 | | machine().ui().draw_text_full(container(), iter.current(), x0, y0, 1.0f - x0, JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, adjust_color(fgcolor), adjust_color(bgcolor)); |
| 700 | | if (column_widths != NULL) |
| 701 | | x0 += column_widths[iter.index()]; |
| 702 | | } |
| 703 | | } |
| 704 | | |
| 705 | | |
| 706 | | //------------------------------------------------- |
| 707 | | // is_highlighted_selection |
| 708 | | //------------------------------------------------- |
| 709 | | |
| 710 | | bool ui_menubar::is_highlighted_selection(menu_item *mi) |
| 711 | | { |
| 712 | | bool result = false; |
| 713 | | |
| 714 | | if (mi == m_selected_item) |
| 715 | | { |
| 716 | | // this item _is_ the selection |
| 717 | | result = true; |
| 718 | | } |
| 719 | | else if (m_selected_item != NULL) |
| 720 | | { |
| 721 | | // walk up the menu hierarchy; we want to also highlight ancestor sub menus |
| 722 | | menu_item *selected_item_ancestor = m_selected_item; |
| 723 | | do |
| 724 | | { |
| 725 | | selected_item_ancestor = selected_item_ancestor->parent(); |
| 726 | | result = (mi == selected_item_ancestor) && selected_item_ancestor->is_sub_menu(); |
| 727 | | } |
| 728 | | while(!result && selected_item_ancestor->is_sub_menu()); |
| 729 | | } |
| 730 | | return result; |
| 731 | | } |
| 732 | | |
| 733 | | |
| 734 | | //------------------------------------------------- |
| 735 | | // find_mouse |
| 736 | | //------------------------------------------------- |
| 737 | | |
| 738 | | bool ui_menubar::find_mouse(float &mouse_x, float &mouse_y, bool &mouse_button) |
| 739 | | { |
| 740 | | bool result = false; |
| 741 | | mouse_x = -1; |
| 742 | | mouse_y = -1; |
| 743 | | |
| 744 | | INT32 mouse_target_x, mouse_target_y; |
| 745 | | render_target *mouse_target = ui_input_find_mouse(machine(), &mouse_target_x, &mouse_target_y, &mouse_button); |
| 746 | | if (mouse_target != NULL) |
| 747 | | { |
| 748 | | if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container(), mouse_x, mouse_y)) |
| 749 | | result = true; |
| 750 | | } |
| 751 | | |
| 752 | | return result; |
| 753 | | } |
| 754 | | |
| 755 | | |
| 756 | | //------------------------------------------------- |
| 757 | | // get_menubar_visibility |
| 758 | | //------------------------------------------------- |
| 759 | | |
| 760 | | ui_menubar::menubar_visibility_t ui_menubar::get_menubar_visibility() |
| 761 | | { |
| 762 | | menubar_visibility_t result; |
| 763 | | |
| 764 | | // is the mouse in the menu bar? |
| 765 | | bool in_menu_bar = (m_mouse_y >= 0) && (m_mouse_y <= machine().ui().get_line_height()); |
| 766 | | |
| 767 | | // did we recently move the mouse? |
| 768 | | bool recently_moved = (m_last_mouse_move != 0) |
| 769 | | && ((osd_ticks() - m_last_mouse_move) * 5 / osd_ticks_per_second() < 1); |
| 770 | | |
| 771 | | // make the choice |
| 772 | | if ((m_selected_item != NULL) || (m_active_item != NULL)) |
| 773 | | result = MENUBAR_VISIBILITY_VISIBLE; |
| 774 | | else if (in_menu_bar || recently_moved) |
| 775 | | result = MENUBAR_VISIBILITY_TRANSLUCENT; |
| 776 | | else |
| 777 | | result = MENUBAR_VISIBILITY_INVISIBLE; |
| 778 | | |
| 779 | | return result; |
| 780 | | } |
| 781 | | |
| 782 | | |
| 783 | | //------------------------------------------------- |
| 784 | | // adjust_color |
| 785 | | //------------------------------------------------- |
| 786 | | |
| 787 | | rgb_t ui_menubar::adjust_color(rgb_t color) |
| 788 | | { |
| 789 | | switch(m_menubar_visibility) |
| 790 | | { |
| 791 | | case MENUBAR_VISIBILITY_INVISIBLE: |
| 792 | | color = rgb_t(0, 0, 0, 0); |
| 793 | | break; |
| 794 | | |
| 795 | | case MENUBAR_VISIBILITY_TRANSLUCENT: |
| 796 | | color = rgb_t( |
| 797 | | color.a() / 4, |
| 798 | | color.r(), |
| 799 | | color.g(), |
| 800 | | color.b()); |
| 801 | | break; |
| 802 | | |
| 803 | | case MENUBAR_VISIBILITY_VISIBLE: |
| 804 | | default: |
| 805 | | // do nothing |
| 806 | | break; |
| 807 | | } |
| 808 | | return color; |
| 809 | | } |
| 810 | | |
| 811 | | |
| 812 | | //************************************************************************** |
| 813 | | // MENU ITEMS |
| 814 | | //************************************************************************** |
| 815 | | |
| 816 | | //------------------------------------------------- |
| 817 | | // menu_item::ctor |
| 818 | | //------------------------------------------------- |
| 819 | | |
| 820 | | ui_menubar::menu_item::menu_item(ui_menubar &menubar, const char *text, ui_menubar::menu_item *parent, bool is_invokable, int shortcut) |
| 821 | | : m_menubar(menubar) |
| 822 | | { |
| 823 | | if (text != NULL) |
| 824 | | m_text.cpy(text); |
| 825 | | m_is_invokable = is_invokable; |
| 826 | | m_parent = parent; |
| 827 | | m_first_child = NULL; |
| 828 | | m_last_child = NULL; |
| 829 | | m_previous = NULL; |
| 830 | | m_next = NULL; |
| 831 | | m_is_checked = false; |
| 832 | | m_is_enabled = true; |
| 833 | | m_is_separator = false; |
| 834 | | m_shortcut = shortcut; |
| 835 | | m_shortcut_text_width = -1; |
| 836 | | clear_area(); |
| 837 | | } |
| 838 | | |
| 839 | | |
| 840 | | //------------------------------------------------- |
| 841 | | // menu_item::dtor |
| 842 | | //------------------------------------------------- |
| 843 | | |
| 844 | | ui_menubar::menu_item::~menu_item() |
| 845 | | { |
| 846 | | menu_item *mi = m_first_child; |
| 847 | | while (mi) |
| 848 | | { |
| 849 | | menu_item *next = mi->m_next; |
| 850 | | delete mi; |
| 851 | | mi = next; |
| 852 | | } |
| 853 | | } |
| 854 | | |
| 855 | | |
| 856 | | //------------------------------------------------- |
| 857 | | // menu_item::set_area |
| 858 | | //------------------------------------------------- |
| 859 | | |
| 860 | | void ui_menubar::menu_item::set_area(float x0, float y0, float x1, float y1) |
| 861 | | { |
| 862 | | m_x0 = x0; |
| 863 | | m_y0 = y0; |
| 864 | | m_x1 = x1; |
| 865 | | m_y1 = y1; |
| 866 | | } |
| 867 | | |
| 868 | | |
| 869 | | //------------------------------------------------- |
| 870 | | // menu_item::clear_area_recursive |
| 871 | | //------------------------------------------------- |
| 872 | | |
| 873 | | void ui_menubar::menu_item::clear_area_recursive() |
| 874 | | { |
| 875 | | clear_area(); |
| 876 | | if (m_first_child) |
| 877 | | m_first_child->clear_area_recursive(); |
| 878 | | if (m_next) |
| 879 | | m_next->clear_area_recursive(); |
| 880 | | } |
| 881 | | |
| 882 | | |
| 883 | | //------------------------------------------------- |
| 884 | | // menu_item::initialize |
| 885 | | //------------------------------------------------- |
| 886 | | |
| 887 | | void ui_menubar::menu_item::initialize(ui_menubar::menu_item &child) |
| 888 | | { |
| 889 | | // link this back to the previous item |
| 890 | | child.m_previous = m_last_child; |
| 891 | | |
| 892 | | // link the end of the chain to this new item |
| 893 | | if (m_last_child) |
| 894 | | m_last_child->m_next = &child; |
| 895 | | else |
| 896 | | m_first_child = &child; |
| 897 | | |
| 898 | | // this new child is now last in the chain |
| 899 | | m_last_child = &child; |
| 900 | | |
| 901 | | // link this up into the shortcut list, if appropriate |
| 902 | | if (child.shortcut() != 0) |
| 903 | | { |
| 904 | | child.set_next_with_shortcut(m_menubar.m_shortcuted_menu_items); |
| 905 | | m_menubar.m_shortcuted_menu_items = &child; |
| 906 | | } |
| 907 | | } |
| 908 | | |
| 909 | | |
| 910 | | //------------------------------------------------- |
| 911 | | // menu_item::append |
| 912 | | //------------------------------------------------- |
| 913 | | |
| 914 | | ui_menubar::menu_item &ui_menubar::menu_item::append(const char *text) |
| 915 | | { |
| 916 | | menu_item *child = new menu_item(m_menubar, text, this); |
| 917 | | initialize(*child); |
| 918 | | return *child; |
| 919 | | } |
| 920 | | |
| 921 | | |
| 922 | | //------------------------------------------------- |
| 923 | | // menu_item::append_separator |
| 924 | | //------------------------------------------------- |
| 925 | | |
| 926 | | void ui_menubar::menu_item::append_separator() |
| 927 | | { |
| 928 | | menu_item &separator = append("-"); |
| 929 | | separator.set_enabled(false); |
| 930 | | separator.m_is_separator = true; |
| 931 | | } |
| 932 | | |
| 933 | | |
| 934 | | //------------------------------------------------- |
| 935 | | // menu_item::find_point |
| 936 | | //------------------------------------------------- |
| 937 | | |
| 938 | | ui_menubar::menu_item *ui_menubar::menu_item::find_point(float x, float y) |
| 939 | | { |
| 940 | | menu_item *result = NULL; |
| 941 | | |
| 942 | | if (m_is_enabled && (x >= m_x0) && (y >= m_y0) && (x <= m_x1) && (y <= m_y1)) |
| 943 | | result = this; |
| 944 | | |
| 945 | | if (!result && m_first_child) |
| 946 | | result = m_first_child->find_point(x, y); |
| 947 | | if (!result && m_next) |
| 948 | | result = m_next->find_point(x, y); |
| 949 | | return result; |
| 950 | | } |
| 951 | | |
| 952 | | |
| 953 | | //------------------------------------------------- |
| 954 | | // menu_item::find_child |
| 955 | | //------------------------------------------------- |
| 956 | | |
| 957 | | ui_menubar::menu_item &ui_menubar::menu_item::find_child(const char *target) |
| 958 | | { |
| 959 | | menu_item *item = find_child_internal(target); |
| 960 | | assert(item != NULL); |
| 961 | | return *item; |
| 962 | | } |
| 963 | | |
| 964 | | |
| 965 | | //------------------------------------------------- |
| 966 | | // menu_item::find_child_internal |
| 967 | | //------------------------------------------------- |
| 968 | | |
| 969 | | ui_menubar::menu_item *ui_menubar::menu_item::find_child_internal(const char *target) |
| 970 | | { |
| 971 | | if (!strcmp(target, text())) |
| 972 | | return this; |
| 973 | | |
| 974 | | for(menu_item *item = child(); item != NULL; item = item->next()) |
| 975 | | { |
| 976 | | menu_item *result = item->find_child_internal(target); |
| 977 | | if (result != NULL) |
| 978 | | return result; |
| 979 | | } |
| 980 | | return NULL; |
| 981 | | } |
| 982 | | |
| 983 | | |
| 984 | | //------------------------------------------------- |
| 985 | | // menu_item::shortcut_text |
| 986 | | //------------------------------------------------- |
| 987 | | |
| 988 | | const char *ui_menubar::menu_item::shortcut_text() |
| 989 | | { |
| 990 | | // do we have to calculate this stuff? |
| 991 | | if (m_shortcut_text_width < 0) |
| 992 | | { |
| 993 | | // clear the text |
| 994 | | m_shortcut_text.cpy(""); |
| 995 | | |
| 996 | | // first, do we even have a shortcut? |
| 997 | | if (shortcut() != 0) |
| 998 | | { |
| 999 | | // iterate over the input ports and add menu items |
| 1000 | | for (input_type_entry *entry = m_menubar.machine().ioport().first_type(); entry != NULL; entry = entry->next()) |
| 1001 | | { |
| 1002 | | // add if we match the group and we have a valid name */ |
| 1003 | | if (entry->group() == IPG_UI_SHORTCUT && entry->name() != NULL && entry->name()[0] != 0 && entry->type() == shortcut()) |
| 1004 | | { |
| 1005 | | const input_seq &seq = m_menubar.machine().ioport().type_seq(entry->type(), entry->player(), SEQ_TYPE_STANDARD); |
| 1006 | | sensible_seq_name(m_shortcut_text, seq); |
| 1007 | | break; |
| 1008 | | } |
| 1009 | | } |
| 1010 | | } |
| 1011 | | |
| 1012 | | // finally calculate the text width |
| 1013 | | m_shortcut_text_width = m_menubar.machine().ui().get_string_width(m_shortcut_text); |
| 1014 | | } |
| 1015 | | |
| 1016 | | // return the text |
| 1017 | | return m_shortcut_text; |
| 1018 | | } |
| 1019 | | |
| 1020 | | |
| 1021 | | //------------------------------------------------- |
| 1022 | | // menu_item::shortcut_text_width |
| 1023 | | //------------------------------------------------- |
| 1024 | | |
| 1025 | | float ui_menubar::menu_item::shortcut_text_width() |
| 1026 | | { |
| 1027 | | // force a calculation, if we didn't have one |
| 1028 | | shortcut_text(); |
| 1029 | | |
| 1030 | | // and return the text width |
| 1031 | | return m_shortcut_text_width; |
| 1032 | | } |
| 1033 | | |
| 1034 | | |
| 1035 | | //------------------------------------------------- |
| 1036 | | // menu_item::sensible_seq_name |
| 1037 | | //------------------------------------------------- |
| 1038 | | |
| 1039 | | void ui_menubar::menu_item::sensible_seq_name(astring &text, const input_seq &seq) |
| 1040 | | { |
| 1041 | | // special case; we don't want 'None' |
| 1042 | | if (seq[0] == input_seq::end_code) |
| 1043 | | text.cpy(""); |
| 1044 | | else |
| 1045 | | m_menubar.machine().input().seq_name(text, seq); |
| 1046 | | } |
| 1047 | | |
| 1048 | | |
| 1049 | | //------------------------------------------------- |
| 1050 | | // menu_item::is_child_of |
| 1051 | | //------------------------------------------------- |
| 1052 | | |
| 1053 | | bool ui_menubar::menu_item::is_child_of(ui_menubar::menu_item *that) const |
| 1054 | | { |
| 1055 | | for(menu_item *mi = m_parent; mi != NULL; mi = mi->m_parent) |
| 1056 | | { |
| 1057 | | if (mi == that) |
| 1058 | | return true; |
| 1059 | | } |
| 1060 | | return false; |
| 1061 | | } |
| 1062 | | |
| 1063 | | |
| 1064 | | //------------------------------------------------- |
| 1065 | | // menu_item::invoke |
| 1066 | | //------------------------------------------------- |
| 1067 | | |
| 1068 | | void ui_menubar::menu_item::invoke() |
| 1069 | | { |
| 1070 | | // do nothing |
| 1071 | | } |
| 1072 | | |
| 1073 | | |
| 1074 | | //************************************************************************** |
| 1075 | | // TABBED TEXT ITERATOR |
| 1076 | | //************************************************************************** |
| 1077 | | |
| 1078 | | //------------------------------------------------- |
| 1079 | | // tabbed_text_iterator::ctor |
| 1080 | | //------------------------------------------------- |
| 1081 | | |
| 1082 | | tabbed_text_iterator::tabbed_text_iterator(const char *text) |
| 1083 | | { |
| 1084 | | m_text = text; |
| 1085 | | m_current = NULL; |
| 1086 | | m_position = 0; |
| 1087 | | m_index = -1; |
| 1088 | | } |
| 1089 | | |
| 1090 | | |
| 1091 | | //------------------------------------------------- |
| 1092 | | // tabbed_text_iterator::next |
| 1093 | | //------------------------------------------------- |
| 1094 | | |
| 1095 | | bool tabbed_text_iterator::next() |
| 1096 | | { |
| 1097 | | const char *current_text = &m_text[m_position]; |
| 1098 | | const char *tabpos = strchr(current_text, '\t'); |
| 1099 | | |
| 1100 | | if (tabpos != NULL) |
| 1101 | | { |
| 1102 | | int count = tabpos - current_text; |
| 1103 | | m_buffer.cpy(current_text, count); |
| 1104 | | m_position += count + 1; |
| 1105 | | m_current = m_buffer; |
| 1106 | | m_index++; |
| 1107 | | } |
| 1108 | | else if (*current_text != '\0') |
| 1109 | | { |
| 1110 | | m_current = current_text; |
| 1111 | | m_position += strlen(m_current); |
| 1112 | | m_index++; |
| 1113 | | } |
| 1114 | | else |
| 1115 | | { |
| 1116 | | m_current = NULL; |
| 1117 | | } |
| 1118 | | return m_current != NULL; |
| 1119 | | } |
branches/old_menus/src/emu/ui/mainmenu.c
| r0 | r29606 | |
| 1 | /********************************************************************* |
| 2 | |
| 3 | ui/mainmenu.c |
| 4 | |
| 5 | Internal MAME menus for the user interface. |
| 6 | |
| 7 | Copyright Nicola Salmoria and the MAME Team. |
| 8 | Visit http://mamedev.org for licensing and usage restrictions. |
| 9 | |
| 10 | *********************************************************************/ |
| 11 | |
| 12 | #include "emu.h" |
| 13 | #include "osdnet.h" |
| 14 | #include "emuopts.h" |
| 15 | #include "ui/ui.h" |
| 16 | #include "rendutil.h" |
| 17 | #include "cheat.h" |
| 18 | #include "uiinput.h" |
| 19 | #include "ui/filemngr.h" |
| 20 | #include "ui/filesel.h" |
| 21 | #include "ui/barcode.h" |
| 22 | #include "ui/bbcontrl.h" |
| 23 | #include "ui/tapectrl.h" |
| 24 | #include "ui/mainmenu.h" |
| 25 | #include "ui/miscmenu.h" |
| 26 | #include "ui/imginfo.h" |
| 27 | #include "ui/selgame.h" |
| 28 | #include "audit.h" |
| 29 | #include "crsshair.h" |
| 30 | #include <ctype.h> |
| 31 | #include "imagedev/cassette.h" |
| 32 | #include "imagedev/bitbngr.h" |
| 33 | #include "machine/bcreader.h" |
| 34 | |
| 35 | |
| 36 | |
| 37 | /*************************************************************************** |
| 38 | MENU HANDLERS |
| 39 | ***************************************************************************/ |
| 40 | |
| 41 | /*------------------------------------------------- |
| 42 | ui_menu_main constructor - populate the main menu |
| 43 | -------------------------------------------------*/ |
| 44 | |
| 45 | ui_menu_main::ui_menu_main(running_machine &machine, render_container *container) : ui_menu(machine, container) |
| 46 | { |
| 47 | } |
| 48 | |
| 49 | void ui_menu_main::populate() |
| 50 | { |
| 51 | astring menu_text; |
| 52 | |
| 53 | /* add input menu items */ |
| 54 | item_append("Input (general)", NULL, 0, (void *)INPUT_GROUPS); |
| 55 | |
| 56 | menu_text.printf("Input (this %s)",emulator_info::get_capstartgamenoun()); |
| 57 | item_append(menu_text.cstr(), NULL, 0, (void *)INPUT_SPECIFIC); |
| 58 | |
| 59 | /* add optional input-related menus */ |
| 60 | if (machine().ioport().has_analog()) |
| 61 | item_append("Analog Controls", NULL, 0, (void *)ANALOG); |
| 62 | if (machine().ioport().has_dips()) |
| 63 | item_append("Dip Switches", NULL, 0, (void *)SETTINGS_DIP_SWITCHES); |
| 64 | if (machine().ioport().has_configs()) |
| 65 | { |
| 66 | menu_text.printf("%s Configuration",emulator_info::get_capstartgamenoun()); |
| 67 | item_append(menu_text.cstr(), NULL, 0, (void *)SETTINGS_DRIVER_CONFIG); |
| 68 | } |
| 69 | |
| 70 | /* add bookkeeping menu */ |
| 71 | item_append("Bookkeeping Info", NULL, 0, (void *)BOOKKEEPING); |
| 72 | |
| 73 | /* add game info menu */ |
| 74 | menu_text.printf("%s Information",emulator_info::get_capstartgamenoun()); |
| 75 | item_append(menu_text.cstr(), NULL, 0, (void *)GAME_INFO); |
| 76 | |
| 77 | image_interface_iterator imgiter(machine().root_device()); |
| 78 | if (imgiter.first() != NULL) |
| 79 | { |
| 80 | /* add image info menu */ |
| 81 | item_append("Image Information", NULL, 0, (void *)IMAGE_MENU_IMAGE_INFO); |
| 82 | |
| 83 | /* add file manager menu */ |
| 84 | item_append("File Manager", NULL, 0, (void *)IMAGE_MENU_FILE_MANAGER); |
| 85 | |
| 86 | /* add tape control menu */ |
| 87 | cassette_device_iterator cassiter(machine().root_device()); |
| 88 | if (cassiter.first() != NULL) |
| 89 | item_append("Tape Control", NULL, 0, (void *)MESS_MENU_TAPE_CONTROL); |
| 90 | |
| 91 | /* add bitbanger control menu */ |
| 92 | bitbanger_device_iterator bititer(machine().root_device()); |
| 93 | if (bititer.first() != NULL) |
| 94 | item_append("Bitbanger Control", NULL, 0, (void *)MESS_MENU_BITBANGER_CONTROL); |
| 95 | } |
| 96 | |
| 97 | if (machine().ioport().has_bioses()) |
| 98 | item_append("Bios Selection", NULL, 0, (void *)BIOS_SELECTION); |
| 99 | |
| 100 | slot_interface_iterator slotiter(machine().root_device()); |
| 101 | if (slotiter.first() != NULL) |
| 102 | { |
| 103 | /* add slot info menu */ |
| 104 | item_append("Slot Devices", NULL, 0, (void *)SLOT_DEVICES); |
| 105 | } |
| 106 | |
| 107 | barcode_reader_device_iterator bcriter(machine().root_device()); |
| 108 | if (bcriter.first() != NULL) |
| 109 | { |
| 110 | /* add slot info menu */ |
| 111 | item_append("Barcode Reader", NULL, 0, (void *)BARCODE_READ); |
| 112 | } |
| 113 | |
| 114 | network_interface_iterator netiter(machine().root_device()); |
| 115 | if (netiter.first() != NULL) |
| 116 | { |
| 117 | /* add image info menu */ |
| 118 | item_append("Network Devices", NULL, 0, (void*)NETWORK_DEVICES); |
| 119 | } |
| 120 | |
| 121 | /* add keyboard mode menu */ |
| 122 | if (machine().ioport().has_keyboard() && machine().ioport().natkeyboard().can_post()) |
| 123 | item_append("Keyboard Mode", NULL, 0, (void *)KEYBOARD_MODE); |
| 124 | |
| 125 | /* add sliders menu */ |
| 126 | item_append("Slider Controls", NULL, 0, (void *)SLIDERS); |
| 127 | |
| 128 | /* add video options menu */ |
| 129 | item_append("Video Options", NULL, 0, (machine().render().target_by_index(1) != NULL) ? (void *)VIDEO_TARGETS : (void *)VIDEO_OPTIONS); |
| 130 | |
| 131 | /* add crosshair options menu */ |
| 132 | if (crosshair_get_usage(machine())) |
| 133 | item_append("Crosshair Options", NULL, 0, (void *)CROSSHAIR); |
| 134 | |
| 135 | /* add cheat menu */ |
| 136 | if (machine().options().cheat() && machine().cheat().first() != NULL) |
| 137 | item_append("Cheat", NULL, 0, (void *)CHEAT); |
| 138 | |
| 139 | /* add memory card menu */ |
| 140 | if (machine().config().m_memcard_handler != NULL) |
| 141 | item_append("Memory Card", NULL, 0, (void *)MEMORY_CARD); |
| 142 | |
| 143 | /* add reset and exit menus */ |
| 144 | menu_text.printf("Select New %s",emulator_info::get_capstartgamenoun()); |
| 145 | item_append(menu_text.cstr(), NULL, 0, (void *)SELECT_GAME); |
| 146 | } |
| 147 | |
| 148 | ui_menu_main::~ui_menu_main() |
| 149 | { |
| 150 | } |
| 151 | |
| 152 | /*------------------------------------------------- |
| 153 | menu_main - handle the main menu |
| 154 | -------------------------------------------------*/ |
| 155 | |
| 156 | void ui_menu_main::handle() |
| 157 | { |
| 158 | /* process the menu */ |
| 159 | const ui_menu_event *menu_event = process(0); |
| 160 | if (menu_event != NULL && menu_event->iptkey == IPT_UI_SELECT) { |
| 161 | switch((long long)(menu_event->itemref)) { |
| 162 | case INPUT_GROUPS: |
| 163 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_input_groups(machine(), container))); |
| 164 | break; |
| 165 | |
| 166 | case INPUT_SPECIFIC: |
| 167 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_input_specific(machine(), container))); |
| 168 | break; |
| 169 | |
| 170 | case SETTINGS_DIP_SWITCHES: |
| 171 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_settings_dip_switches(machine(), container))); |
| 172 | break; |
| 173 | |
| 174 | case SETTINGS_DRIVER_CONFIG: |
| 175 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_settings_driver_config(machine(), container))); |
| 176 | break; |
| 177 | |
| 178 | case ANALOG: |
| 179 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_analog(machine(), container))); |
| 180 | break; |
| 181 | |
| 182 | case BOOKKEEPING: |
| 183 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_bookkeeping(machine(), container))); |
| 184 | break; |
| 185 | |
| 186 | case GAME_INFO: |
| 187 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_game_info(machine(), container))); |
| 188 | break; |
| 189 | |
| 190 | case IMAGE_MENU_IMAGE_INFO: |
| 191 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_image_info(machine(), container))); |
| 192 | break; |
| 193 | |
| 194 | case IMAGE_MENU_FILE_MANAGER: |
| 195 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_manager(machine(), container))); |
| 196 | break; |
| 197 | |
| 198 | case MESS_MENU_TAPE_CONTROL: |
| 199 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_mess_tape_control(machine(), container, NULL))); |
| 200 | break; |
| 201 | |
| 202 | case MESS_MENU_BITBANGER_CONTROL: |
| 203 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_mess_bitbanger_control(machine(), container, NULL))); |
| 204 | break; |
| 205 | |
| 206 | case SLOT_DEVICES: |
| 207 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_slot_devices(machine(), container))); |
| 208 | break; |
| 209 | |
| 210 | case NETWORK_DEVICES: |
| 211 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_network_devices(machine(), container))); |
| 212 | break; |
| 213 | |
| 214 | case KEYBOARD_MODE: |
| 215 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_keyboard_mode(machine(), container))); |
| 216 | break; |
| 217 | |
| 218 | case SLIDERS: |
| 219 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_sliders(machine(), container, false))); |
| 220 | break; |
| 221 | |
| 222 | case VIDEO_TARGETS: |
| 223 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_video_targets(machine(), container))); |
| 224 | break; |
| 225 | |
| 226 | case VIDEO_OPTIONS: |
| 227 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_video_options(machine(), container, machine().render().first_target()))); |
| 228 | break; |
| 229 | |
| 230 | case CROSSHAIR: |
| 231 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_crosshair(machine(), container))); |
| 232 | break; |
| 233 | |
| 234 | case CHEAT: |
| 235 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_cheat(machine(), container))); |
| 236 | break; |
| 237 | |
| 238 | case MEMORY_CARD: |
| 239 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_memory_card(machine(), container))); |
| 240 | break; |
| 241 | |
| 242 | case SELECT_GAME: |
| 243 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_select_game(machine(), container, 0))); |
| 244 | break; |
| 245 | |
| 246 | case BIOS_SELECTION: |
| 247 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_bios_selection(machine(), container))); |
| 248 | break; |
| 249 | |
| 250 | case BARCODE_READ: |
| 251 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_barcode_reader(machine(), container))); |
| 252 | break; |
| 253 | |
| 254 | default: |
| 255 | fatalerror("ui_menu_main::handle - unknown reference\n"); |
| 256 | } |
| 257 | } |
| 258 | } |
branches/old_menus/src/emu/ui/ui.c
| r29605 | r29606 | |
| 18 | 18 | #include "rendfont.h" |
| 19 | 19 | #include "ui/ui.h" |
| 20 | 20 | #include "uiinput.h" |
| 21 | #include "ui/mainmenu.h" |
| 21 | 22 | #include "ui/miscmenu.h" |
| 22 | 23 | #include "ui/viewgfx.h" |
| 23 | 24 | #include <ctype.h> |
| 24 | 25 | |
| 25 | 26 | |
| 26 | 27 | /*************************************************************************** |
| 28 | CONSTANTS |
| 29 | ***************************************************************************/ |
| 30 | |
| 31 | enum |
| 32 | { |
| 33 | LOADSAVE_NONE, |
| 34 | LOADSAVE_LOAD, |
| 35 | LOADSAVE_SAVE |
| 36 | }; |
| 37 | |
| 38 | |
| 39 | /*************************************************************************** |
| 27 | 40 | LOCAL VARIABLES |
| 28 | 41 | ***************************************************************************/ |
| 29 | 42 | |
| r29605 | r29606 | |
| 213 | 226 | ui_gfx_init(machine); |
| 214 | 227 | |
| 215 | 228 | // reset instance variables |
| 216 | | m_menubar = NULL; |
| 217 | 229 | m_font = NULL; |
| 218 | 230 | m_handler_callback = NULL; |
| 219 | 231 | m_handler_param = 0; |
| r29605 | r29606 | |
| 348 | 360 | // loop while we have a handler |
| 349 | 361 | while (m_handler_callback != handler_ingame && !machine().scheduled_event_pending() && !ui_menu::stack_has_special_main_menu()) |
| 350 | 362 | machine().video().frame_update(); |
| 363 | |
| 364 | // clear the handler and force an update |
| 365 | set_handler(handler_ingame, 0); |
| 366 | machine().video().frame_update(); |
| 351 | 367 | } |
| 352 | 368 | |
| 353 | 369 | // if we're the empty driver, force the menus on |
| r29605 | r29606 | |
| 458 | 474 | { |
| 459 | 475 | INT32 raw_font_pixel_height = get_font()->pixel_height(); |
| 460 | 476 | render_target &ui_target = machine().render().ui_target(); |
| 461 | | INT32 target_pixel_width = ui_target.width(); |
| 462 | 477 | INT32 target_pixel_height = ui_target.height(); |
| 478 | float one_to_one_line_height; |
| 479 | float scale_factor; |
| 463 | 480 | |
| 464 | | // compute the font pixel width/height at the nominal size |
| 465 | | float one_to_one_line_width = (float)raw_font_pixel_height / (float)target_pixel_width; |
| 466 | | float one_to_one_line_height = (float)raw_font_pixel_height / (float)target_pixel_height; |
| 481 | // compute the font pixel height at the nominal size |
| 482 | one_to_one_line_height = (float)raw_font_pixel_height / (float)target_pixel_height; |
| 467 | 483 | |
| 468 | 484 | // determine the scale factor |
| 469 | | float scale_factor = MIN( |
| 470 | | UI_TARGET_FONT_WIDTH / one_to_one_line_width, |
| 471 | | UI_TARGET_FONT_HEIGHT / one_to_one_line_height); |
| 485 | scale_factor = UI_TARGET_FONT_HEIGHT / one_to_one_line_height; |
| 472 | 486 | |
| 473 | 487 | // if our font is small-ish, do integral scaling |
| 474 | 488 | if (raw_font_pixel_height < 24) |
| r29605 | r29606 | |
| 946 | 960 | |
| 947 | 961 | bool ui_manager::is_menu_active(void) |
| 948 | 962 | { |
| 949 | | return (m_handler_callback == ui_menu::ui_handler) |
| 950 | | || (m_handler_callback == handler_ingame && m_menubar != NULL && m_menubar->has_selection()); |
| 963 | return (m_handler_callback == ui_menu::ui_handler); |
| 951 | 964 | } |
| 952 | 965 | |
| 953 | 966 | |
| r29605 | r29606 | |
| 1435 | 1448 | |
| 1436 | 1449 | UINT32 ui_manager::handler_ingame(running_machine &machine, render_container *container, UINT32 state) |
| 1437 | 1450 | { |
| 1438 | | return machine.ui().handler_ingame_method(container, state); |
| 1439 | | } |
| 1451 | bool is_paused = machine.paused(); |
| 1440 | 1452 | |
| 1453 | // first draw the FPS counter |
| 1454 | if (machine.ui().show_fps_counter()) |
| 1455 | { |
| 1456 | astring tempstring; |
| 1457 | machine.ui().draw_text_full(container, machine.video().speed_text(tempstring), 0.0f, 0.0f, 1.0f, |
| 1458 | JUSTIFY_RIGHT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, NULL, NULL); |
| 1459 | } |
| 1441 | 1460 | |
| 1442 | | //------------------------------------------------- |
| 1443 | | // handler_ingame_method - in-game handler takes |
| 1444 | | // care of the standard keypresses |
| 1445 | | //------------------------------------------------- |
| 1461 | // draw the profiler if visible |
| 1462 | if (machine.ui().show_profiler()) |
| 1463 | { |
| 1464 | const char *text = g_profiler.text(machine); |
| 1465 | machine.ui().draw_text_full(container, text, 0.0f, 0.0f, 1.0f, JUSTIFY_LEFT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, NULL, NULL); |
| 1466 | } |
| 1446 | 1467 | |
| 1447 | | UINT32 ui_manager::handler_ingame_method(render_container *container, UINT32 state) |
| 1448 | | { |
| 1449 | | // no menubar? create it |
| 1450 | | if (m_menubar == NULL) |
| 1451 | | m_menubar = auto_alloc(machine(), ui_emu_menubar(machine())); |
| 1452 | | |
| 1453 | | // handle! |
| 1454 | | m_menubar->handle(container); |
| 1455 | | |
| 1456 | | // did we change out the handler? |
| 1457 | | if (m_handler_callback != handler_ingame) |
| 1458 | | { |
| 1459 | | // if so, flush the menubar... |
| 1460 | | auto_free(machine(), m_menubar); |
| 1461 | | m_menubar = NULL; |
| 1462 | | |
| 1463 | | // ...and then check to see if this is just a "refresh" |
| 1464 | | if (m_handler_callback == NULL) |
| 1465 | | m_handler_callback = handler_ingame; |
| 1466 | | } |
| 1467 | | |
| 1468 | | return m_handler_param; |
| 1468 | // if we're single-stepping, pause now |
| 1469 | if (machine.ui().single_step()) |
| 1470 | { |
| 1471 | machine.pause(); |
| 1472 | machine.ui().set_single_step(false); |
| 1473 | } |
| 1474 | |
| 1475 | // determine if we should disable the rest of the UI |
| 1476 | bool ui_disabled = (machine.ioport().has_keyboard() && !machine.ui_active()); |
| 1477 | |
| 1478 | // is ScrLk UI toggling applicable here? |
| 1479 | if (machine.ioport().has_keyboard()) |
| 1480 | { |
| 1481 | // are we toggling the UI with ScrLk? |
| 1482 | if (ui_input_pressed(machine, IPT_UI_TOGGLE_UI)) |
| 1483 | { |
| 1484 | // toggle the UI |
| 1485 | machine.set_ui_active(!machine.ui_active()); |
| 1486 | |
| 1487 | // display a popup indicating the new status |
| 1488 | if (machine.ui_active()) |
| 1489 | { |
| 1490 | machine.ui().popup_time(2, "%s\n%s\n%s\n%s\n%s\n%s\n", |
| 1491 | "Keyboard Emulation Status", |
| 1492 | "-------------------------", |
| 1493 | "Mode: PARTIAL Emulation", |
| 1494 | "UI: Enabled", |
| 1495 | "-------------------------", |
| 1496 | "**Use ScrLock to toggle**"); |
| 1497 | } |
| 1498 | else |
| 1499 | { |
| 1500 | machine.ui().popup_time(2, "%s\n%s\n%s\n%s\n%s\n%s\n", |
| 1501 | "Keyboard Emulation Status", |
| 1502 | "-------------------------", |
| 1503 | "Mode: FULL Emulation", |
| 1504 | "UI: Disabled", |
| 1505 | "-------------------------", |
| 1506 | "**Use ScrLock to toggle**"); |
| 1507 | } |
| 1508 | } |
| 1509 | } |
| 1510 | |
| 1511 | // is the natural keyboard enabled? |
| 1512 | if (machine.ui().use_natural_keyboard() && (machine.phase() == MACHINE_PHASE_RUNNING)) |
| 1513 | machine.ui().process_natural_keyboard(); |
| 1514 | |
| 1515 | if (!ui_disabled) |
| 1516 | { |
| 1517 | // paste command |
| 1518 | if (ui_input_pressed(machine, IPT_UI_PASTE)) |
| 1519 | machine.ui().paste(); |
| 1520 | } |
| 1521 | |
| 1522 | machine.ui().image_handler_ingame(); |
| 1523 | |
| 1524 | if (ui_disabled) return ui_disabled; |
| 1525 | |
| 1526 | if (ui_input_pressed(machine, IPT_UI_CANCEL)) |
| 1527 | { |
| 1528 | machine.ui().request_quit(); |
| 1529 | return 0; |
| 1530 | } |
| 1531 | |
| 1532 | // turn on menus if requested |
| 1533 | if (ui_input_pressed(machine, IPT_UI_CONFIGURE)) |
| 1534 | return machine.ui().set_handler(ui_menu::ui_handler, 0); |
| 1535 | |
| 1536 | // if the on-screen display isn't up and the user has toggled it, turn it on |
| 1537 | if ((machine.debug_flags & DEBUG_FLAG_ENABLED) == 0 && ui_input_pressed(machine, IPT_UI_ON_SCREEN_DISPLAY)) |
| 1538 | return machine.ui().set_handler(ui_menu_sliders::ui_handler, 1); |
| 1539 | |
| 1540 | // handle a reset request |
| 1541 | if (ui_input_pressed(machine, IPT_UI_RESET_MACHINE)) |
| 1542 | machine.schedule_hard_reset(); |
| 1543 | if (ui_input_pressed(machine, IPT_UI_SOFT_RESET)) |
| 1544 | machine.schedule_soft_reset(); |
| 1545 | |
| 1546 | // handle a request to display graphics/palette |
| 1547 | if (ui_input_pressed(machine, IPT_UI_SHOW_GFX)) |
| 1548 | { |
| 1549 | if (!is_paused) |
| 1550 | machine.pause(); |
| 1551 | return machine.ui().set_handler(ui_gfx_ui_handler, is_paused); |
| 1552 | } |
| 1553 | |
| 1554 | // handle a save state request |
| 1555 | if (ui_input_pressed(machine, IPT_UI_SAVE_STATE)) |
| 1556 | { |
| 1557 | machine.pause(); |
| 1558 | return machine.ui().set_handler(handler_load_save, LOADSAVE_SAVE); |
| 1559 | } |
| 1560 | |
| 1561 | // handle a load state request |
| 1562 | if (ui_input_pressed(machine, IPT_UI_LOAD_STATE)) |
| 1563 | { |
| 1564 | machine.pause(); |
| 1565 | return machine.ui().set_handler(handler_load_save, LOADSAVE_LOAD); |
| 1566 | } |
| 1567 | |
| 1568 | // handle a save snapshot request |
| 1569 | if (ui_input_pressed(machine, IPT_UI_SNAPSHOT)) |
| 1570 | machine.video().save_active_screen_snapshots(); |
| 1571 | |
| 1572 | // toggle pause |
| 1573 | if (ui_input_pressed(machine, IPT_UI_PAUSE)) |
| 1574 | { |
| 1575 | // with a shift key, it is single step |
| 1576 | if (is_paused && (machine.input().code_pressed(KEYCODE_LSHIFT) || machine.input().code_pressed(KEYCODE_RSHIFT))) |
| 1577 | { |
| 1578 | machine.ui().set_single_step(true); |
| 1579 | machine.resume(); |
| 1580 | } |
| 1581 | else |
| 1582 | machine.toggle_pause(); |
| 1583 | } |
| 1584 | |
| 1585 | // handle a toggle cheats request |
| 1586 | if (ui_input_pressed(machine, IPT_UI_TOGGLE_CHEAT)) |
| 1587 | machine.cheat().set_enable(!machine.cheat().enabled()); |
| 1588 | |
| 1589 | // toggle movie recording |
| 1590 | if (ui_input_pressed(machine, IPT_UI_RECORD_MOVIE)) |
| 1591 | machine.video().toggle_record_movie(); |
| 1592 | |
| 1593 | // toggle profiler display |
| 1594 | if (ui_input_pressed(machine, IPT_UI_SHOW_PROFILER)) |
| 1595 | machine.ui().set_show_profiler(!machine.ui().show_profiler()); |
| 1596 | |
| 1597 | // toggle FPS display |
| 1598 | if (ui_input_pressed(machine, IPT_UI_SHOW_FPS)) |
| 1599 | machine.ui().set_show_fps(!machine.ui().show_fps()); |
| 1600 | |
| 1601 | // increment frameskip? |
| 1602 | if (ui_input_pressed(machine, IPT_UI_FRAMESKIP_INC)) |
| 1603 | machine.ui().increase_frameskip(); |
| 1604 | |
| 1605 | // decrement frameskip? |
| 1606 | if (ui_input_pressed(machine, IPT_UI_FRAMESKIP_DEC)) |
| 1607 | machine.ui().decrease_frameskip(); |
| 1608 | |
| 1609 | // toggle throttle? |
| 1610 | if (ui_input_pressed(machine, IPT_UI_THROTTLE)) |
| 1611 | machine.video().toggle_throttle(); |
| 1612 | |
| 1613 | // check for fast forward |
| 1614 | if (machine.ioport().type_pressed(IPT_UI_FAST_FORWARD)) |
| 1615 | { |
| 1616 | machine.video().set_fastforward(true); |
| 1617 | machine.ui().show_fps_temp(0.5); |
| 1618 | } |
| 1619 | else |
| 1620 | machine.video().set_fastforward(false); |
| 1621 | |
| 1622 | return 0; |
| 1469 | 1623 | } |
| 1470 | 1624 | |
| 1471 | 1625 | |
| 1472 | 1626 | //------------------------------------------------- |
| 1473 | | // ui_handler_load_save - leads the user through |
| 1627 | // handler_load_save - leads the user through |
| 1474 | 1628 | // specifying a game to save or load |
| 1475 | 1629 | //------------------------------------------------- |
| 1476 | 1630 | |
| 1477 | | UINT32 ui_manager::ui_handler_load_save(running_machine &machine, render_container *container, UINT32 state) |
| 1631 | UINT32 ui_manager::handler_load_save(running_machine &machine, render_container *container, UINT32 state) |
| 1478 | 1632 | { |
| 1479 | 1633 | char filename[20]; |
| 1480 | 1634 | input_code code; |