summaryrefslogtreecommitdiffstats
path: root/apps/onplay.c
diff options
context:
space:
mode:
authorJeffrey Goode <jeffg7@gmail.com>2010-04-01 03:14:44 +0000
committerJeffrey Goode <jeffg7@gmail.com>2010-04-01 03:14:44 +0000
commitd5e6bc7a8c413218ec1372fd54157e9639ab67b4 (patch)
tree2be93c700ef9c5e8f85cc7dbbfab7f9f842c92f0 /apps/onplay.c
parent39e78993f317349dacfc4e8d1abb703117636696 (diff)
downloadrockbox-d5e6bc7a8c413218ec1372fd54157e9639ab67b4.tar.gz
rockbox-d5e6bc7a8c413218ec1372fd54157e9639ab67b4.zip
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
Diffstat (limited to 'apps/onplay.c')
-rw-r--r--apps/onplay.c206
1 files changed, 191 insertions, 15 deletions
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: