From d5e6bc7a8c413218ec1372fd54157e9639ab67b4 Mon Sep 17 00:00:00 2001 From: Jeffrey Goode Date: Thu, 1 Apr 2010 03:14:44 +0000 Subject: FS#11081 - Hotkey patch. Many targets supported, but some keymaps need work before they can be switched on git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25414 a1c6a512-1295-4272-9138-f99709370657 --- apps/onplay.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 191 insertions(+), 15 deletions(-) (limited to 'apps/onplay.c') diff --git a/apps/onplay.c b/apps/onplay.c index f9c75ab253..5a28c53cd4 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -528,7 +528,7 @@ static int remove_dir(char* dirname, int len) /* share code for file and directory deletion, saves space */ -static bool delete_handler(bool is_dir) +static bool delete_file_dir(void) { char file_to_delete[MAX_PATH]; strcpy(file_to_delete, selected_file); @@ -551,7 +551,7 @@ static bool delete_handler(bool is_dir) splash(0, str(LANG_DELETING)); int res; - if (is_dir) + if (selected_file_attr & ATTR_DIRECTORY) /* true if directory */ { char pathname[MAX_PATH]; /* space to go deep */ cpu_boost(true); @@ -568,16 +568,6 @@ static bool delete_handler(bool is_dir) return (res == 0); } -static bool delete_file(void) -{ - return delete_handler(false); -} - -static bool delete_dir(void) -{ - return delete_handler(true); -} - static bool rename_file(void) { char newname[MAX_PATH]; @@ -988,9 +978,9 @@ MENUITEM_FUNCTION(clipboard_copy_item, 0, ID2P(LANG_COPY), MENUITEM_FUNCTION(clipboard_paste_item, 0, ID2P(LANG_PASTE), clipboard_paste, NULL, clipboard_callback, Icon_NOICON); MENUITEM_FUNCTION(delete_file_item, 0, ID2P(LANG_DELETE), - delete_file, NULL, clipboard_callback, Icon_NOICON); + delete_file_dir, NULL, clipboard_callback, Icon_NOICON); MENUITEM_FUNCTION(delete_dir_item, 0, ID2P(LANG_DELETE_DIR), - delete_dir, NULL, clipboard_callback, Icon_NOICON); + delete_file_dir, NULL, clipboard_callback, Icon_NOICON); MENUITEM_FUNCTION(create_dir_item, 0, ID2P(LANG_CREATE_DIR), create_dir, NULL, clipboard_callback, Icon_NOICON); @@ -1180,19 +1170,205 @@ static int onplaymenu_callback(int action,const struct menu_item_ex *this_item) } return action; } -int onplay(char* file, int attr, int from) + +#ifdef HAVE_HOTKEY +/* direct function calls, no need for menu callbacks */ +static bool delete_item(void) +{ +#ifdef HAVE_MULTIVOLUME + /* no delete for volumes */ + if ((selected_file_attr & FAT_ATTR_VOLUME) || + (selected_file_attr & ATTR_VOLUME)) + return false; +#endif + return delete_file_dir(); +} + +static bool open_with(void) +{ + /* only open files */ + if (selected_file_attr & ATTR_DIRECTORY) + return false; +#ifdef HAVE_MULTIVOLUME + if (selected_file_attr & ATTR_VOLUME) + return false; +#endif + return list_viewers(); +} + +extern const struct menu_item_ex *selected_menu_item; +extern bool hotkey_settable_menu; + +#define HOT_MASK 0x0FF +#define HOT_WPS 0x100 +#define HOT_TREE 0x200 + +struct hotkey_assignment { + int item; + struct menu_func func; + int return_code; + const struct menu_item_ex *menu_addr; +}; + +#define HOTKEY_FUNC(func, param) {{(void *)func}, param} + +/* Any desired hotkey functions go here... */ +enum hotkey_settings { + HOTKEY_OFF = 0, + HOTKEY_VIEW_PLAYLIST = 1, + HOTKEY_SHOW_TRACK_INFO, + HOTKEY_PITCHSCREEN, + HOTKEY_OPEN_WITH, + HOTKEY_DELETE, + HOTKEY_INSERT, +}; + +/* ... and here. Order is not important. */ +static struct hotkey_assignment hotkey_items[] = { + { HOTKEY_VIEW_PLAYLIST | HOT_WPS, + HOTKEY_FUNC(NULL, NULL), + ONPLAY_PLAYLIST, &view_cur_playlist }, + { HOTKEY_SHOW_TRACK_INFO| HOT_WPS, + HOTKEY_FUNC(browse_id3, NULL), + ONPLAY_RELOAD_DIR, &browse_id3_item }, +#ifdef HAVE_PITCHSCREEN + { HOTKEY_PITCHSCREEN | HOT_WPS, + HOTKEY_FUNC(gui_syncpitchscreen_run, NULL), + ONPLAY_RELOAD_DIR, &pitch_screen_item }, +#endif + { HOTKEY_OPEN_WITH | HOT_WPS | HOT_TREE, + HOTKEY_FUNC(open_with, NULL), + ONPLAY_RELOAD_DIR, &list_viewers_item }, + { HOTKEY_DELETE | HOT_WPS | HOT_TREE, + HOTKEY_FUNC(delete_item, NULL), + ONPLAY_RELOAD_DIR, &delete_file_item }, + { HOTKEY_DELETE | HOT_TREE, + HOTKEY_FUNC(delete_item, NULL), + ONPLAY_RELOAD_DIR, &delete_dir_item }, + { HOTKEY_INSERT | HOT_TREE, + HOTKEY_FUNC(playlist_insert_func, (intptr_t*)PLAYLIST_INSERT), + ONPLAY_START_PLAY, &i_pl_item }, +}; + +static const int num_hotkey_items = sizeof(hotkey_items) / sizeof(hotkey_items[0]); + +/* Execute the hotkey function, if listed for this screen */ +static int execute_hotkey(bool is_wps) +{ + int i; + struct hotkey_assignment *this_item; + const int context = is_wps ? HOT_WPS : HOT_TREE; + const int this_hotkey = (is_wps ? global_settings.hotkey_wps : + global_settings.hotkey_tree); + + /* search assignment struct for a match for the hotkey setting */ + for (i = 0; i < num_hotkey_items; i++) + { + this_item = &hotkey_items[i]; + if ((this_item->item & context) && + ((this_item->item & HOT_MASK) == this_hotkey)) + { + /* run the associated function (with optional param), if any */ + const struct menu_func func = this_item->func; + if (func.function != NULL) + { + if (func.param != NULL) + (*(func.function_w_param))(func.param); + else + (*(func.function))(); + } + /* return with the associated code */ + return this_item->return_code; + } + } + + /* no valid hotkey set */ + splash(HZ, ID2P(LANG_HOTKEY_NOT_SET)); + return ONPLAY_RELOAD_DIR; +} + +/* Set the hotkey to the current context menu function, if listed */ +static void set_hotkey(bool is_wps) +{ + int i; + struct hotkey_assignment *this_item; + const int context = is_wps ? HOT_WPS : HOT_TREE; + int *hk_func = is_wps ? &global_settings.hotkey_wps : + &global_settings.hotkey_tree, + *hk_desc = is_wps ? &global_settings.hotkey_wps_desc_id : + &global_settings.hotkey_tree_desc_id; + int this_hk, + this_id; + bool match_found = false; + + /* search assignment struct for a function that matches the current menu item */ + for (i = 0; i < num_hotkey_items; i++) + { + this_item = &hotkey_items[i]; + if ((this_item->item & context) && + (this_item->menu_addr == selected_menu_item)) + { + this_hk = this_item->item & HOT_MASK; + this_id = P2ID((selected_menu_item->callback_and_desc)->desc); + match_found = true; + break; + } + } + + /* ignore the hotkey if no match found or no change to setting */ + if (!match_found || (this_hk == *hk_func)) return; + + char line1_buf[100]; + char line2_buf[101]; + char *line1 = line1_buf; + char *line2 = line2_buf; + char **line1_ptr = &line1; + char **line2_ptr = &line2; + const struct text_message message={(const char **)line2_ptr, 1}; + const struct text_message yes_message={(const char **)line1_ptr, 1}; + + snprintf(line1, 100, str(LANG_SET_HOTKEY), str(this_id)); + strcat(strcpy(line2, line1), "?"); + + /* confirm the hotkey setting change */ + if(gui_syncyesno_run(&message, &yes_message, NULL)==YESNO_YES) + { + /* store the hotkey settings */ + *hk_func = this_hk; + *hk_desc = this_id; + + settings_save(); + splash(HZ*2, line1); + } +} +#endif /* HOTKEY */ + +int onplay(char* file, int attr, int from, bool hotkey) { const struct menu_item_ex *menu; onplay_result = ONPLAY_OK; context = from; selected_file = file; selected_file_attr = attr; +#ifdef HAVE_HOTKEY + if (hotkey) + return execute_hotkey(context == CONTEXT_WPS); + hotkey_settable_menu = true; +#else + (void)hotkey; +#endif if (context == CONTEXT_WPS) menu = &wps_onplay_menu; else menu = &tree_onplay_menu; switch (do_menu(menu, NULL, NULL, false)) { +#ifdef HAVE_HOTKEY + hotkey_settable_menu = false; + case MENU_SELECTED_HOTKEY: + set_hotkey(context == CONTEXT_WPS); + return ONPLAY_RELOAD_DIR; +#endif case GO_TO_WPS: return ONPLAY_START_PLAY; case GO_TO_ROOT: -- cgit v1.2.3