Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/SDK/menu.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 #include "menu_common.h" | |
| 3 | |
| 4 class NOVTABLE mainmenu_group : public service_base { | |
| 5 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(mainmenu_group); | |
| 6 public: | |
| 7 virtual GUID get_guid() = 0; | |
| 8 virtual GUID get_parent() = 0; | |
| 9 virtual t_uint32 get_sort_priority() = 0; | |
| 10 }; | |
| 11 | |
| 12 class NOVTABLE mainmenu_group_popup : public mainmenu_group { | |
| 13 FB2K_MAKE_SERVICE_INTERFACE(mainmenu_group_popup, mainmenu_group); | |
| 14 public: | |
| 15 virtual void get_display_string(pfc::string_base & p_out) = 0; | |
| 16 void get_name(pfc::string_base & out) {get_display_string(out);} | |
| 17 }; | |
| 18 | |
| 19 //! \since 1.4 | |
| 20 //! Allows you to control whether to render the group as a popup or inline. | |
| 21 class NOVTABLE mainmenu_group_popup_v2 : public mainmenu_group_popup { | |
| 22 FB2K_MAKE_SERVICE_INTERFACE(mainmenu_group_popup_v2, mainmenu_group_popup); | |
| 23 public: | |
| 24 virtual bool popup_condition() = 0; | |
| 25 }; | |
| 26 | |
| 27 class NOVTABLE mainmenu_commands : public service_base { | |
| 28 public: | |
| 29 static constexpr uint32_t | |
| 30 flag_disabled = 1 << 0, | |
| 31 flag_checked = 1 << 1, | |
| 32 flag_radiochecked = 1 << 2, | |
| 33 //! \since 1.0 | |
| 34 //! Replaces the old return-false-from-get_display() behavior - use this to make your command hidden by default but accessible when holding shift. | |
| 35 flag_defaulthidden = 1 << 3, | |
| 36 sort_priority_base = 0x10000, | |
| 37 sort_priority_dontcare = 0x80000000u, | |
| 38 sort_priority_last = UINT32_MAX; | |
| 39 | |
| 40 | |
| 41 //! Retrieves number of implemented commands. Index parameter of other methods must be in 0....command_count-1 range. | |
| 42 virtual t_uint32 get_command_count() = 0; | |
| 43 //! Retrieves GUID of specified command. | |
| 44 virtual GUID get_command(t_uint32 p_index) = 0; | |
| 45 //! Retrieves name of item, for list of commands to assign keyboard shortcuts to etc. | |
| 46 virtual void get_name(t_uint32 p_index,pfc::string_base & p_out) = 0; | |
| 47 //! Retrieves item's description for statusbar etc. | |
| 48 virtual bool get_description(t_uint32 p_index,pfc::string_base & p_out) = 0; | |
| 49 //! Retrieves GUID of owning menu group. | |
| 50 virtual GUID get_parent() = 0; | |
| 51 //! Retrieves sorting priority of the command; the lower the number, the upper in the menu your commands will appear. Third party components should use sorting_priority_base and up (values below are reserved for internal use). In case of equal priority, order is undefined. | |
| 52 virtual t_uint32 get_sort_priority() {return sort_priority_dontcare;} | |
| 53 //! Retrieves display string and display flags to use when menu is about to be displayed. If returns false, menu item won't be displayed. You can create keyboard-shortcut-only commands by always returning false from get_display(). | |
| 54 virtual bool get_display(t_uint32 p_index,pfc::string_base & p_text,t_uint32 & p_flags) {p_flags = 0;get_name(p_index,p_text);return true;} | |
| 55 | |
| 56 typedef service_ptr ctx_t; | |
| 57 | |
| 58 //! Executes the command. p_callback parameter is reserved for future use and should be ignored / set to null pointer. | |
| 59 virtual void execute(t_uint32 p_index,ctx_t p_callback) = 0; | |
| 60 | |
| 61 static bool g_execute(const GUID & p_guid,service_ptr_t<service_base> p_callback = NULL); | |
| 62 static bool g_execute_dynamic(const GUID & p_guid, const GUID & p_subGuid,service_ptr_t<service_base> p_callback = NULL); | |
| 63 static bool g_find_by_name(const char * p_name,GUID & p_guid); | |
| 64 | |
| 65 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(mainmenu_commands); | |
| 66 }; | |
| 67 | |
| 68 class NOVTABLE mainmenu_manager : public service_base { | |
| 69 public: | |
| 70 enum { | |
| 71 flag_show_shortcuts = 1 << 0, | |
| 72 flag_show_shortcuts_global = 1 << 1, | |
| 73 //! \since 1.0 | |
| 74 //! To control which commands are shown, you should specify either flag_view_reduced or flag_view_full. If neither is specified, the implementation will decide automatically based on shift key being pressed, for backwards compatibility. | |
| 75 flag_view_reduced = 1 << 2, | |
| 76 //! \since 1.0 | |
| 77 //! To control which commands are shown, you should specify either flag_view_reduced or flag_view_full. If neither is specified, the implementation will decide automatically based on shift key being pressed, for backwards compatibility. | |
| 78 flag_view_full = 1 << 3, | |
| 79 }; | |
| 80 | |
| 81 virtual void instantiate(const GUID & p_root) = 0; | |
| 82 | |
| 83 #ifdef _WIN32 | |
| 84 virtual void generate_menu_win32(fb2k::hmenu_t p_menu,t_uint32 p_id_base,t_uint32 p_id_count,t_uint32 p_flags) = 0; | |
| 85 #endif // _WIN32 | |
| 86 | |
| 87 //@param p_id Identifier of command to execute, relative to p_id_base of generate_menu_*() | |
| 88 //@returns true if command was executed successfully, false if not (e.g. command with given identifier not found). | |
| 89 virtual bool execute_command(t_uint32 p_id,service_ptr_t<service_base> p_callback = service_ptr_t<service_base>()) = 0; | |
| 90 | |
| 91 virtual bool get_description(t_uint32 p_id,pfc::string_base & p_out) = 0; | |
| 92 | |
| 93 //! Safely prevent destruction from worker threads (some components attempt that). | |
| 94 static bool serviceRequiresMainThreadDestructor() { return true; } | |
| 95 | |
| 96 FB2K_MAKE_SERVICE_COREAPI(mainmenu_manager); | |
| 97 }; | |
| 98 | |
| 99 //! \since 2.0 | |
| 100 class mainmenu_manager_v2 : public mainmenu_manager { | |
| 101 FB2K_MAKE_SERVICE_COREAPI_EXTENSION(mainmenu_manager_v2, mainmenu_manager) | |
| 102 public: | |
| 103 virtual menu_tree_item::ptr generate_menu(uint32_t flags) = 0; | |
| 104 }; | |
| 105 | |
| 106 class mainmenu_groups { | |
| 107 public: | |
| 108 static const GUID file,view,edit,playback,library,help; | |
| 109 static const GUID file_open,file_add,file_playlist,file_etc; | |
| 110 static const GUID playback_controls,playback_etc; | |
| 111 static const GUID view_visualisations, view_alwaysontop, view_dsp; | |
| 112 static const GUID edit_part1,edit_part2,edit_part3; | |
| 113 static const GUID edit_part2_selection,edit_part2_sort,edit_part2_selection_sort; | |
| 114 static const GUID file_etc_preferences, file_etc_exit; | |
| 115 static const GUID help_about; | |
| 116 static const GUID library_refresh; | |
| 117 | |
| 118 enum {priority_edit_part1,priority_edit_part2,priority_edit_part3}; | |
| 119 enum {priority_edit_part2_commands,priority_edit_part2_selection,priority_edit_part2_sort}; | |
| 120 enum {priority_edit_part2_selection_commands,priority_edit_part2_selection_sort}; | |
| 121 enum {priority_file_open,priority_file_add,priority_file_playlist,priority_file_etc = mainmenu_commands::sort_priority_last}; | |
| 122 }; | |
| 123 | |
| 124 | |
| 125 class mainmenu_group_impl : public mainmenu_group { | |
| 126 public: | |
| 127 mainmenu_group_impl(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority) : m_guid(p_guid), m_parent(p_parent), m_priority(p_priority) {} | |
| 128 GUID get_guid() {return m_guid;} | |
| 129 GUID get_parent() {return m_parent;} | |
| 130 t_uint32 get_sort_priority() {return m_priority;} | |
| 131 private: | |
| 132 GUID m_guid,m_parent; t_uint32 m_priority; | |
| 133 }; | |
| 134 | |
| 135 class mainmenu_group_popup_impl : public mainmenu_group_popup { | |
| 136 public: | |
| 137 mainmenu_group_popup_impl(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority,const char * p_name) : m_guid(p_guid), m_parent(p_parent), m_priority(p_priority), m_name(p_name) {} | |
| 138 GUID get_guid() {return m_guid;} | |
| 139 GUID get_parent() {return m_parent;} | |
| 140 t_uint32 get_sort_priority() {return m_priority;} | |
| 141 void get_display_string(pfc::string_base & p_out) {p_out = m_name;} | |
| 142 private: | |
| 143 GUID m_guid,m_parent; t_uint32 m_priority; pfc::string8 m_name; | |
| 144 }; | |
| 145 | |
| 146 typedef service_factory_single_t<mainmenu_group_impl> _mainmenu_group_factory; | |
| 147 typedef service_factory_single_t<mainmenu_group_popup_impl> _mainmenu_group_popup_factory; | |
| 148 | |
| 149 class mainmenu_group_factory : public _mainmenu_group_factory { | |
| 150 public: | |
| 151 mainmenu_group_factory(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority) : _mainmenu_group_factory(p_guid,p_parent,p_priority) {} | |
| 152 }; | |
| 153 | |
| 154 class mainmenu_group_popup_factory : public _mainmenu_group_popup_factory { | |
| 155 public: | |
| 156 mainmenu_group_popup_factory(const GUID & p_guid,const GUID & p_parent,t_uint32 p_priority,const char * p_name) : _mainmenu_group_popup_factory(p_guid,p_parent,p_priority,p_name) {} | |
| 157 }; | |
| 158 | |
| 159 #define FB2K_DECLARE_MAINMENU_GROUP( guid, parent, priority, name ) FB2K_SERVICE_FACTORY_PARAMS(mainmenu_group_impl, guid, parent, priority, name ); | |
| 160 #define FB2K_DECLARE_MAINMENU_GROUP_POPUP( guid, parent, priority, name ) FB2K_SERVICE_FACTORY_PARAMS(mainmenu_group_popup_impl, guid, parent, priority, name ); | |
| 161 | |
| 162 template<typename T> | |
| 163 class mainmenu_commands_factory_t : public service_factory_single_t<T> {}; | |
| 164 | |
| 165 | |
| 166 | |
| 167 | |
| 168 | |
| 169 | |
| 170 //! \since 1.0 | |
| 171 class NOVTABLE mainmenu_node : public service_base { | |
| 172 FB2K_MAKE_SERVICE_INTERFACE(mainmenu_node, service_base) | |
| 173 public: | |
| 174 enum { //same as contextmenu_item_node::t_type | |
| 175 type_group,type_command,type_separator | |
| 176 }; | |
| 177 | |
| 178 virtual t_uint32 get_type() = 0; | |
| 179 virtual void get_display(pfc::string_base & text, t_uint32 & flags) = 0; | |
| 180 //! Valid only if type is type_group. | |
| 181 virtual t_size get_children_count() = 0; | |
| 182 //! Valid only if type is type_group. | |
| 183 virtual ptr get_child(t_size index) = 0; | |
| 184 //! Valid only if type is type_command. | |
| 185 virtual void execute(service_ptr_t<service_base> callback) = 0; | |
| 186 //! Valid only if type is type_command. | |
| 187 virtual GUID get_guid() = 0; | |
| 188 //! Valid only if type is type_command. | |
| 189 virtual bool get_description(pfc::string_base& out) { (void)out; return false; } | |
| 190 | |
| 191 }; | |
| 192 | |
| 193 class mainmenu_node_separator : public mainmenu_node { | |
| 194 public: | |
| 195 t_uint32 get_type() override {return type_separator;} | |
| 196 void get_display(pfc::string_base & text, t_uint32 & flags) override {text = ""; flags = 0;} | |
| 197 t_size get_children_count() override {return 0;} | |
| 198 ptr get_child(t_size index) override { (void)index; throw pfc::exception_invalid_params(); } | |
| 199 void execute(service_ptr_t<service_base>) override {} | |
| 200 GUID get_guid() override {return pfc::guid_null;} | |
| 201 }; | |
| 202 | |
| 203 class mainmenu_node_command : public mainmenu_node { | |
| 204 public: | |
| 205 t_uint32 get_type() override {return type_command;} | |
| 206 t_size get_children_count() override {return 0;} | |
| 207 ptr get_child(t_size index) override { (void)index; throw pfc::exception_invalid_params(); } | |
| 208 /* | |
| 209 void get_display(pfc::string_base & text, t_uint32 & flags); | |
| 210 void execute(service_ptr_t<service_base> callback); | |
| 211 GUID get_guid(); | |
| 212 bool get_description(pfc::string_base & out) {return false;} | |
| 213 */ | |
| 214 }; | |
| 215 | |
| 216 class mainmenu_node_group : public mainmenu_node { | |
| 217 public: | |
| 218 t_uint32 get_type() override {return type_group;} | |
| 219 void execute(service_ptr_t<service_base> callback) override { (void)callback; } | |
| 220 GUID get_guid() override {return pfc::guid_null;} | |
| 221 /* | |
| 222 void get_display(pfc::string_base & text, t_uint32 & flags); | |
| 223 t_size get_children_count(); | |
| 224 ptr get_child(t_size index); | |
| 225 */ | |
| 226 }; | |
| 227 | |
| 228 | |
| 229 //! \since 1.0 | |
| 230 class NOVTABLE mainmenu_commands_v2 : public mainmenu_commands { | |
| 231 FB2K_MAKE_SERVICE_INTERFACE(mainmenu_commands_v2, mainmenu_commands) | |
| 232 public: | |
| 233 virtual bool is_command_dynamic(t_uint32 index); | |
| 234 //! Valid only when is_command_dynamic() returns true. Behavior undefined otherwise. | |
| 235 virtual mainmenu_node::ptr dynamic_instantiate(t_uint32 index); | |
| 236 //! Default fallback implementation provided. | |
| 237 virtual bool dynamic_execute(t_uint32 index, const GUID & subID, service_ptr_t<service_base> callback); | |
| 238 }; | |
| 239 | |
| 240 //! \since 2.0 | |
| 241 //! Introduces callbacks to monitor menu items that act like check boxes. | |
| 242 class NOVTABLE mainmenu_commands_v3 : public mainmenu_commands_v2 { | |
| 243 FB2K_MAKE_SERVICE_INTERFACE(mainmenu_commands_v3, mainmenu_commands_v2) | |
| 244 public: | |
| 245 class state_callback { | |
| 246 public: | |
| 247 //! @param main Command ID | |
| 248 //! @param sub Reserved for future use. | |
| 249 virtual void menu_state_changed(const GUID& main, const GUID& sub) { (void)main; (void)sub; } | |
| 250 state_callback() {} | |
| 251 state_callback(state_callback const&) = delete; | |
| 252 void operator=(state_callback const&) = delete; | |
| 253 }; | |
| 254 | |
| 255 //! Return POSSIBLE values of display flags for this item, specifically flag_checked and flag_radiochecked if this item ever uses such. | |
| 256 //! @param subCmd Subcommand ID reserved for future use. Dynamic commands aren't meant to fire callbacks. | |
| 257 virtual uint32_t allowed_check_flags(uint32_t idx, const GUID& subCmd) = 0; | |
| 258 virtual void add_state_callback(state_callback*) = 0; | |
| 259 virtual void remove_state_callback(state_callback*) = 0; | |
| 260 }; |
