diff options
author | Jeffrey Goode <jeffg7@gmail.com> | 2010-04-01 03:14:44 +0000 |
---|---|---|
committer | Jeffrey Goode <jeffg7@gmail.com> | 2010-04-01 03:14:44 +0000 |
commit | d5e6bc7a8c413218ec1372fd54157e9639ab67b4 (patch) | |
tree | 2be93c700ef9c5e8f85cc7dbbfab7f9f842c92f0 /apps/onplay.c | |
parent | 39e78993f317349dacfc4e8d1abb703117636696 (diff) | |
download | rockbox-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.c | 206 |
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) | |||
528 | 528 | ||
529 | 529 | ||
530 | /* share code for file and directory deletion, saves space */ | 530 | /* share code for file and directory deletion, saves space */ |
531 | static bool delete_handler(bool is_dir) | 531 | static bool delete_file_dir(void) |
532 | { | 532 | { |
533 | char file_to_delete[MAX_PATH]; | 533 | char file_to_delete[MAX_PATH]; |
534 | strcpy(file_to_delete, selected_file); | 534 | strcpy(file_to_delete, selected_file); |
@@ -551,7 +551,7 @@ static bool delete_handler(bool is_dir) | |||
551 | splash(0, str(LANG_DELETING)); | 551 | splash(0, str(LANG_DELETING)); |
552 | 552 | ||
553 | int res; | 553 | int res; |
554 | if (is_dir) | 554 | if (selected_file_attr & ATTR_DIRECTORY) /* true if directory */ |
555 | { | 555 | { |
556 | char pathname[MAX_PATH]; /* space to go deep */ | 556 | char pathname[MAX_PATH]; /* space to go deep */ |
557 | cpu_boost(true); | 557 | cpu_boost(true); |
@@ -568,16 +568,6 @@ static bool delete_handler(bool is_dir) | |||
568 | return (res == 0); | 568 | return (res == 0); |
569 | } | 569 | } |
570 | 570 | ||
571 | static bool delete_file(void) | ||
572 | { | ||
573 | return delete_handler(false); | ||
574 | } | ||
575 | |||
576 | static bool delete_dir(void) | ||
577 | { | ||
578 | return delete_handler(true); | ||
579 | } | ||
580 | |||
581 | static bool rename_file(void) | 571 | static bool rename_file(void) |
582 | { | 572 | { |
583 | char newname[MAX_PATH]; | 573 | char newname[MAX_PATH]; |
@@ -988,9 +978,9 @@ MENUITEM_FUNCTION(clipboard_copy_item, 0, ID2P(LANG_COPY), | |||
988 | MENUITEM_FUNCTION(clipboard_paste_item, 0, ID2P(LANG_PASTE), | 978 | MENUITEM_FUNCTION(clipboard_paste_item, 0, ID2P(LANG_PASTE), |
989 | clipboard_paste, NULL, clipboard_callback, Icon_NOICON); | 979 | clipboard_paste, NULL, clipboard_callback, Icon_NOICON); |
990 | MENUITEM_FUNCTION(delete_file_item, 0, ID2P(LANG_DELETE), | 980 | MENUITEM_FUNCTION(delete_file_item, 0, ID2P(LANG_DELETE), |
991 | delete_file, NULL, clipboard_callback, Icon_NOICON); | 981 | delete_file_dir, NULL, clipboard_callback, Icon_NOICON); |
992 | MENUITEM_FUNCTION(delete_dir_item, 0, ID2P(LANG_DELETE_DIR), | 982 | MENUITEM_FUNCTION(delete_dir_item, 0, ID2P(LANG_DELETE_DIR), |
993 | delete_dir, NULL, clipboard_callback, Icon_NOICON); | 983 | delete_file_dir, NULL, clipboard_callback, Icon_NOICON); |
994 | MENUITEM_FUNCTION(create_dir_item, 0, ID2P(LANG_CREATE_DIR), | 984 | MENUITEM_FUNCTION(create_dir_item, 0, ID2P(LANG_CREATE_DIR), |
995 | create_dir, NULL, clipboard_callback, Icon_NOICON); | 985 | create_dir, NULL, clipboard_callback, Icon_NOICON); |
996 | 986 | ||
@@ -1180,19 +1170,205 @@ static int onplaymenu_callback(int action,const struct menu_item_ex *this_item) | |||
1180 | } | 1170 | } |
1181 | return action; | 1171 | return action; |
1182 | } | 1172 | } |
1183 | int onplay(char* file, int attr, int from) | 1173 | |
1174 | #ifdef HAVE_HOTKEY | ||
1175 | /* direct function calls, no need for menu callbacks */ | ||
1176 | static bool delete_item(void) | ||
1177 | { | ||
1178 | #ifdef HAVE_MULTIVOLUME | ||
1179 | /* no delete for volumes */ | ||
1180 | if ((selected_file_attr & FAT_ATTR_VOLUME) || | ||
1181 | (selected_file_attr & ATTR_VOLUME)) | ||
1182 | return false; | ||
1183 | #endif | ||
1184 | return delete_file_dir(); | ||
1185 | } | ||
1186 | |||
1187 | static bool open_with(void) | ||
1188 | { | ||
1189 | /* only open files */ | ||
1190 | if (selected_file_attr & ATTR_DIRECTORY) | ||
1191 | return false; | ||
1192 | #ifdef HAVE_MULTIVOLUME | ||
1193 | if (selected_file_attr & ATTR_VOLUME) | ||
1194 | return false; | ||
1195 | #endif | ||
1196 | return list_viewers(); | ||
1197 | } | ||
1198 | |||
1199 | extern const struct menu_item_ex *selected_menu_item; | ||
1200 | extern bool hotkey_settable_menu; | ||
1201 | |||
1202 | #define HOT_MASK 0x0FF | ||
1203 | #define HOT_WPS 0x100 | ||
1204 | #define HOT_TREE 0x200 | ||
1205 | |||
1206 | struct hotkey_assignment { | ||
1207 | int item; | ||
1208 | struct menu_func func; | ||
1209 | int return_code; | ||
1210 | const struct menu_item_ex *menu_addr; | ||
1211 | }; | ||
1212 | |||
1213 | #define HOTKEY_FUNC(func, param) {{(void *)func}, param} | ||
1214 | |||
1215 | /* Any desired hotkey functions go here... */ | ||
1216 | enum hotkey_settings { | ||
1217 | HOTKEY_OFF = 0, | ||
1218 | HOTKEY_VIEW_PLAYLIST = 1, | ||
1219 | HOTKEY_SHOW_TRACK_INFO, | ||
1220 | HOTKEY_PITCHSCREEN, | ||
1221 | HOTKEY_OPEN_WITH, | ||
1222 | HOTKEY_DELETE, | ||
1223 | HOTKEY_INSERT, | ||
1224 | }; | ||
1225 | |||
1226 | /* ... and here. Order is not important. */ | ||
1227 | static struct hotkey_assignment hotkey_items[] = { | ||
1228 | { HOTKEY_VIEW_PLAYLIST | HOT_WPS, | ||
1229 | HOTKEY_FUNC(NULL, NULL), | ||
1230 | ONPLAY_PLAYLIST, &view_cur_playlist }, | ||
1231 | { HOTKEY_SHOW_TRACK_INFO| HOT_WPS, | ||
1232 | HOTKEY_FUNC(browse_id3, NULL), | ||
1233 | ONPLAY_RELOAD_DIR, &browse_id3_item }, | ||
1234 | #ifdef HAVE_PITCHSCREEN | ||
1235 | { HOTKEY_PITCHSCREEN | HOT_WPS, | ||
1236 | HOTKEY_FUNC(gui_syncpitchscreen_run, NULL), | ||
1237 | ONPLAY_RELOAD_DIR, &pitch_screen_item }, | ||
1238 | #endif | ||
1239 | { HOTKEY_OPEN_WITH | HOT_WPS | HOT_TREE, | ||
1240 | HOTKEY_FUNC(open_with, NULL), | ||
1241 | ONPLAY_RELOAD_DIR, &list_viewers_item }, | ||
1242 | { HOTKEY_DELETE | HOT_WPS | HOT_TREE, | ||
1243 | HOTKEY_FUNC(delete_item, NULL), | ||
1244 | ONPLAY_RELOAD_DIR, &delete_file_item }, | ||
1245 | { HOTKEY_DELETE | HOT_TREE, | ||
1246 | HOTKEY_FUNC(delete_item, NULL), | ||
1247 | ONPLAY_RELOAD_DIR, &delete_dir_item }, | ||
1248 | { HOTKEY_INSERT | HOT_TREE, | ||
1249 | HOTKEY_FUNC(playlist_insert_func, (intptr_t*)PLAYLIST_INSERT), | ||
1250 | ONPLAY_START_PLAY, &i_pl_item }, | ||
1251 | }; | ||
1252 | |||
1253 | static const int num_hotkey_items = sizeof(hotkey_items) / sizeof(hotkey_items[0]); | ||
1254 | |||
1255 | /* Execute the hotkey function, if listed for this screen */ | ||
1256 | static int execute_hotkey(bool is_wps) | ||
1257 | { | ||
1258 | int i; | ||
1259 | struct hotkey_assignment *this_item; | ||
1260 | const int context = is_wps ? HOT_WPS : HOT_TREE; | ||
1261 | const int this_hotkey = (is_wps ? global_settings.hotkey_wps : | ||
1262 | global_settings.hotkey_tree); | ||
1263 | |||
1264 | /* search assignment struct for a match for the hotkey setting */ | ||
1265 | for (i = 0; i < num_hotkey_items; i++) | ||
1266 | { | ||
1267 | this_item = &hotkey_items[i]; | ||
1268 | if ((this_item->item & context) && | ||
1269 | ((this_item->item & HOT_MASK) == this_hotkey)) | ||
1270 | { | ||
1271 | /* run the associated function (with optional param), if any */ | ||
1272 | const struct menu_func func = this_item->func; | ||
1273 | if (func.function != NULL) | ||
1274 | { | ||
1275 | if (func.param != NULL) | ||
1276 | (*(func.function_w_param))(func.param); | ||
1277 | else | ||
1278 | (*(func.function))(); | ||
1279 | } | ||
1280 | /* return with the associated code */ | ||
1281 | return this_item->return_code; | ||
1282 | } | ||
1283 | } | ||
1284 | |||
1285 | /* no valid hotkey set */ | ||
1286 | splash(HZ, ID2P(LANG_HOTKEY_NOT_SET)); | ||
1287 | return ONPLAY_RELOAD_DIR; | ||
1288 | } | ||
1289 | |||
1290 | /* Set the hotkey to the current context menu function, if listed */ | ||
1291 | static void set_hotkey(bool is_wps) | ||
1292 | { | ||
1293 | int i; | ||
1294 | struct hotkey_assignment *this_item; | ||
1295 | const int context = is_wps ? HOT_WPS : HOT_TREE; | ||
1296 | int *hk_func = is_wps ? &global_settings.hotkey_wps : | ||
1297 | &global_settings.hotkey_tree, | ||
1298 | *hk_desc = is_wps ? &global_settings.hotkey_wps_desc_id : | ||
1299 | &global_settings.hotkey_tree_desc_id; | ||
1300 | int this_hk, | ||
1301 | this_id; | ||
1302 | bool match_found = false; | ||
1303 | |||
1304 | /* search assignment struct for a function that matches the current menu item */ | ||
1305 | for (i = 0; i < num_hotkey_items; i++) | ||
1306 | { | ||
1307 | this_item = &hotkey_items[i]; | ||
1308 | if ((this_item->item & context) && | ||
1309 | (this_item->menu_addr == selected_menu_item)) | ||
1310 | { | ||
1311 | this_hk = this_item->item & HOT_MASK; | ||
1312 | this_id = P2ID((selected_menu_item->callback_and_desc)->desc); | ||
1313 | match_found = true; | ||
1314 | break; | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | /* ignore the hotkey if no match found or no change to setting */ | ||
1319 | if (!match_found || (this_hk == *hk_func)) return; | ||
1320 | |||
1321 | char line1_buf[100]; | ||
1322 | char line2_buf[101]; | ||
1323 | char *line1 = line1_buf; | ||
1324 | char *line2 = line2_buf; | ||
1325 | char **line1_ptr = &line1; | ||
1326 | char **line2_ptr = &line2; | ||
1327 | const struct text_message message={(const char **)line2_ptr, 1}; | ||
1328 | const struct text_message yes_message={(const char **)line1_ptr, 1}; | ||
1329 | |||
1330 | snprintf(line1, 100, str(LANG_SET_HOTKEY), str(this_id)); | ||
1331 | strcat(strcpy(line2, line1), "?"); | ||
1332 | |||
1333 | /* confirm the hotkey setting change */ | ||
1334 | if(gui_syncyesno_run(&message, &yes_message, NULL)==YESNO_YES) | ||
1335 | { | ||
1336 | /* store the hotkey settings */ | ||
1337 | *hk_func = this_hk; | ||
1338 | *hk_desc = this_id; | ||
1339 | |||
1340 | settings_save(); | ||
1341 | splash(HZ*2, line1); | ||
1342 | } | ||
1343 | } | ||
1344 | #endif /* HOTKEY */ | ||
1345 | |||
1346 | int onplay(char* file, int attr, int from, bool hotkey) | ||
1184 | { | 1347 | { |
1185 | const struct menu_item_ex *menu; | 1348 | const struct menu_item_ex *menu; |
1186 | onplay_result = ONPLAY_OK; | 1349 | onplay_result = ONPLAY_OK; |
1187 | context = from; | 1350 | context = from; |
1188 | selected_file = file; | 1351 | selected_file = file; |
1189 | selected_file_attr = attr; | 1352 | selected_file_attr = attr; |
1353 | #ifdef HAVE_HOTKEY | ||
1354 | if (hotkey) | ||
1355 | return execute_hotkey(context == CONTEXT_WPS); | ||
1356 | hotkey_settable_menu = true; | ||
1357 | #else | ||
1358 | (void)hotkey; | ||
1359 | #endif | ||
1190 | if (context == CONTEXT_WPS) | 1360 | if (context == CONTEXT_WPS) |
1191 | menu = &wps_onplay_menu; | 1361 | menu = &wps_onplay_menu; |
1192 | else | 1362 | else |
1193 | menu = &tree_onplay_menu; | 1363 | menu = &tree_onplay_menu; |
1194 | switch (do_menu(menu, NULL, NULL, false)) | 1364 | switch (do_menu(menu, NULL, NULL, false)) |
1195 | { | 1365 | { |
1366 | #ifdef HAVE_HOTKEY | ||
1367 | hotkey_settable_menu = false; | ||
1368 | case MENU_SELECTED_HOTKEY: | ||
1369 | set_hotkey(context == CONTEXT_WPS); | ||
1370 | return ONPLAY_RELOAD_DIR; | ||
1371 | #endif | ||
1196 | case GO_TO_WPS: | 1372 | case GO_TO_WPS: |
1197 | return ONPLAY_START_PLAY; | 1373 | return ONPLAY_START_PLAY; |
1198 | case GO_TO_ROOT: | 1374 | case GO_TO_ROOT: |