diff options
-rw-r--r-- | apps/menu.c | 23 | ||||
-rw-r--r-- | apps/menu.h | 7 | ||||
-rw-r--r-- | apps/onplay.c | 724 |
3 files changed, 387 insertions, 367 deletions
diff --git a/apps/menu.c b/apps/menu.c index 283cc4c1b7..a71b21a6ec 100644 --- a/apps/menu.c +++ b/apps/menu.c | |||
@@ -429,8 +429,6 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected) | |||
429 | 429 | ||
430 | talk_menu_item(menu, &lists); | 430 | talk_menu_item(menu, &lists); |
431 | 431 | ||
432 | gui_synclist_draw(&lists); | ||
433 | gui_syncstatusbar_draw(&statusbars, true); | ||
434 | action_signalscreenchange(); | 432 | action_signalscreenchange(); |
435 | 433 | ||
436 | /* load the callback, and only reload it if menu changes */ | 434 | /* load the callback, and only reload it if menu changes */ |
@@ -438,6 +436,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected) | |||
438 | 436 | ||
439 | while (!done) | 437 | while (!done) |
440 | { | 438 | { |
439 | gui_syncstatusbar_draw(&statusbars, true); | ||
440 | gui_synclist_draw(&lists); | ||
441 | action = get_action(CONTEXT_MAINMENU,HZ); | 441 | action = get_action(CONTEXT_MAINMENU,HZ); |
442 | /* HZ so the status bar redraws corectly */ | 442 | /* HZ so the status bar redraws corectly */ |
443 | if (action == ACTION_NONE) | 443 | if (action == ACTION_NONE) |
@@ -494,10 +494,14 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected) | |||
494 | if (menu_callback) | 494 | if (menu_callback) |
495 | menu_callback(ACTION_EXIT_MENUITEM, menu); | 495 | menu_callback(ACTION_EXIT_MENUITEM, menu); |
496 | 496 | ||
497 | if (menu->flags&MENU_EXITAFTERTHISMENU) | ||
498 | done = true; | ||
497 | if (stack_top > 0) | 499 | if (stack_top > 0) |
498 | { | 500 | { |
499 | stack_top--; | 501 | stack_top--; |
500 | menu = menu_stack[stack_top]; | 502 | menu = menu_stack[stack_top]; |
503 | if (menu->flags&MENU_EXITAFTERTHISMENU) | ||
504 | done = true; | ||
501 | init_menu_lists(menu, &lists, | 505 | init_menu_lists(menu, &lists, |
502 | menu_stack_selected_item[stack_top], false); | 506 | menu_stack_selected_item[stack_top], false); |
503 | talk_menu_item(menu, &lists); | 507 | talk_menu_item(menu, &lists); |
@@ -600,12 +604,21 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected) | |||
600 | done = true; | 604 | done = true; |
601 | break; | 605 | break; |
602 | } | 606 | } |
603 | if (type != MT_MENU && menu_callback) | 607 | if (type != MT_MENU) |
604 | menu_callback(ACTION_EXIT_MENUITEM,temp); | 608 | { |
609 | if (menu_callback) | ||
610 | menu_callback(ACTION_EXIT_MENUITEM,temp); | ||
611 | } | ||
605 | if (current_submenus_menu != menu) | 612 | if (current_submenus_menu != menu) |
606 | init_menu_lists(menu,&lists,selected,true); | 613 | init_menu_lists(menu,&lists,selected,true); |
607 | /* callback was changed, so reload the menu's callback */ | 614 | /* callback was changed, so reload the menu's callback */ |
608 | get_menu_callback(menu, &menu_callback); | 615 | get_menu_callback(menu, &menu_callback); |
616 | if ((menu->flags&MENU_EXITAFTERTHISMENU) && | ||
617 | !(temp->flags&MENU_EXITAFTERTHISMENU)) | ||
618 | { | ||
619 | done = true; | ||
620 | break; | ||
621 | } | ||
609 | #ifdef HAS_BUTTONBAR | 622 | #ifdef HAS_BUTTONBAR |
610 | gui_buttonbar_set(&buttonbar, "<<<", "", ""); | 623 | gui_buttonbar_set(&buttonbar, "<<<", "", ""); |
611 | gui_buttonbar_draw(&buttonbar); | 624 | gui_buttonbar_draw(&buttonbar); |
@@ -616,8 +629,6 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected) | |||
616 | ret = MENU_ATTACHED_USB; | 629 | ret = MENU_ATTACHED_USB; |
617 | done = true; | 630 | done = true; |
618 | } | 631 | } |
619 | gui_syncstatusbar_draw(&statusbars, true); | ||
620 | gui_synclist_draw(&lists); | ||
621 | } | 632 | } |
622 | action_signalscreenchange(); | 633 | action_signalscreenchange(); |
623 | if (start_selected) | 634 | if (start_selected) |
diff --git a/apps/menu.h b/apps/menu.h index a86155374e..3d1bd43cb3 100644 --- a/apps/menu.h +++ b/apps/menu.h | |||
@@ -53,13 +53,14 @@ struct menu_func { | |||
53 | /* these next two are mutually exclusive */ | 53 | /* these next two are mutually exclusive */ |
54 | #define MENU_HAS_DESC 0x10 | 54 | #define MENU_HAS_DESC 0x10 |
55 | #define MENU_DYNAMIC_DESC 0x20 | 55 | #define MENU_DYNAMIC_DESC 0x20 |
56 | #define MENU_EXITAFTERTHISMENU 0x40 | ||
56 | 57 | ||
57 | /* Flags for MT_FUNCTION_CALL */ | 58 | /* Flags for MT_FUNCTION_CALL */ |
58 | #define MENU_FUNC_USEPARAM 0x40 | 59 | #define MENU_FUNC_USEPARAM 0x80 |
59 | #define MENU_FUNC_CHECK_RETVAL 0x80 | 60 | #define MENU_FUNC_CHECK_RETVAL 0x100 |
60 | 61 | ||
61 | #define MENU_COUNT_MASK 0xFFF | 62 | #define MENU_COUNT_MASK 0xFFF |
62 | #define MENU_COUNT_SHIFT 8 | 63 | #define MENU_COUNT_SHIFT 12 |
63 | #define MENU_ITEM_COUNT(c) ((c&MENU_COUNT_MASK)<<MENU_COUNT_SHIFT) | 64 | #define MENU_ITEM_COUNT(c) ((c&MENU_COUNT_MASK)<<MENU_COUNT_SHIFT) |
64 | #define MENU_GET_COUNT(flags) ((flags>>MENU_COUNT_SHIFT)&MENU_COUNT_MASK) | 65 | #define MENU_GET_COUNT(flags) ((flags>>MENU_COUNT_SHIFT)&MENU_COUNT_MASK) |
65 | 66 | ||
diff --git a/apps/onplay.c b/apps/onplay.c index 0bd2b01c1c..37818b64e0 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "action.h" | 50 | #include "action.h" |
51 | #include "splash.h" | 51 | #include "splash.h" |
52 | #include "yesno.h" | 52 | #include "yesno.h" |
53 | #include "menus/exported_menus.h" | ||
53 | #ifdef HAVE_LCD_BITMAP | 54 | #ifdef HAVE_LCD_BITMAP |
54 | #include "icons.h" | 55 | #include "icons.h" |
55 | #endif | 56 | #endif |
@@ -76,52 +77,59 @@ static char clipboard_selection[MAX_PATH]; | |||
76 | static int clipboard_selection_attr = 0; | 77 | static int clipboard_selection_attr = 0; |
77 | static bool clipboard_is_copy = false; | 78 | static bool clipboard_is_copy = false; |
78 | 79 | ||
79 | /* For playlist options */ | 80 | /* redefine MAKE_MENU so the MENU_EXITAFTERTHISMENU flag can be added easily */ |
80 | struct playlist_args { | 81 | #define MAKE_ONPLAYMENU( name, str, callback, icon, ... ) \ |
81 | int position; | 82 | static const struct menu_item_ex *name##_[] = {__VA_ARGS__}; \ |
82 | bool queue; | 83 | static const struct menu_callback_with_desc name##__ = {callback,str,icon};\ |
83 | }; | 84 | static const struct menu_item_ex name = \ |
85 | {MT_MENU|MENU_HAS_DESC|MENU_EXITAFTERTHISMENU| \ | ||
86 | MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \ | ||
87 | { (void*)name##_},{.callback_and_desc = & name##__}}; | ||
88 | |||
84 | 89 | ||
85 | /* ----------------------------------------------------------------------- */ | 90 | /* ----------------------------------------------------------------------- */ |
86 | /* Displays the bookmark menu options for the user to decide. This is an */ | 91 | /* Displays the bookmark menu options for the user to decide. This is an */ |
87 | /* interface function. */ | 92 | /* interface function. */ |
88 | /* ----------------------------------------------------------------------- */ | 93 | /* ----------------------------------------------------------------------- */ |
89 | static bool bookmark_menu(void) | ||
90 | { | ||
91 | int i,m; | ||
92 | bool result; | ||
93 | struct menu_item items[3]; | ||
94 | 94 | ||
95 | i=0; | 95 | static int bookmark_menu_callback(int action,const struct menu_item_ex *this_item); |
96 | 96 | MENUITEM_FUNCTION(bookmark_create_menu_item, 0, | |
97 | if ((audio_status() & AUDIO_STATUS_PLAY)) | 97 | ID2P(LANG_BOOKMARK_MENU_CREATE), |
98 | bookmark_create_menu, NULL, NULL, Icon_Bookmark); | ||
99 | MENUITEM_FUNCTION(bookmark_load_menu_item, 0, | ||
100 | ID2P(LANG_BOOKMARK_MENU_LIST), | ||
101 | bookmark_load_menu, NULL, | ||
102 | bookmark_menu_callback, Icon_Bookmark); | ||
103 | MAKE_MENU(bookmark_menu, ID2P(LANG_BOOKMARK_MENU), bookmark_menu_callback, | ||
104 | Icon_Bookmark, &bookmark_create_menu_item, &bookmark_load_menu_item); | ||
105 | static int bookmark_menu_callback(int action,const struct menu_item_ex *this_item) | ||
106 | { | ||
107 | (void)this_item; | ||
108 | switch (action) | ||
98 | { | 109 | { |
99 | items[i].desc = ID2P(LANG_BOOKMARK_MENU_CREATE); | 110 | case ACTION_REQUEST_MENUITEM: |
100 | items[i].function = bookmark_create_menu; | 111 | if (this_item == &bookmark_load_menu_item) |
101 | i++; | 112 | { |
102 | 113 | if (bookmark_exist() == 0) | |
103 | if (bookmark_exist()) | 114 | return ACTION_EXIT_MENUITEM; |
104 | { | 115 | } |
105 | items[i].desc = ID2P(LANG_BOOKMARK_MENU_LIST); | 116 | /* hide the bookmark menu if there is no playback */ |
106 | items[i].function = bookmark_load_menu; | 117 | else if ((audio_status() & AUDIO_STATUS_PLAY) == 0) |
107 | i++; | 118 | return ACTION_EXIT_MENUITEM; |
108 | } | 119 | break; |
109 | } | ||
110 | |||
111 | m=menu_init( items, i, NULL, str(LANG_BOOKMARK_MENU), NULL, NULL ); | ||
112 | |||
113 | #ifdef HAVE_LCD_CHARCELLS | 120 | #ifdef HAVE_LCD_CHARCELLS |
114 | status_set_param(true); | 121 | case ACTION_ENTER_MENUITEM: |
122 | status_set_param(true); | ||
123 | break; | ||
115 | #endif | 124 | #endif |
116 | result = menu_run(m); | 125 | case ACTION_EXIT_MENUITEM: |
117 | #ifdef HAVE_LCD_CHARCELLS | 126 | #ifdef HAVE_LCD_CHARCELLS |
118 | status_set_param(false); | 127 | status_set_param(false); |
119 | #endif | 128 | #endif |
120 | menu_exit(m); | 129 | settings_save(); |
121 | 130 | break; | |
122 | settings_save(); | 131 | } |
123 | 132 | return action; | |
124 | return result; | ||
125 | } | 133 | } |
126 | 134 | ||
127 | static bool list_viewers(void) | 135 | static bool list_viewers(void) |
@@ -233,159 +241,181 @@ static bool cat_add_to_a_new_playlist(void) | |||
233 | return catalog_add_to_a_playlist(selected_file, selected_file_attr, true); | 241 | return catalog_add_to_a_playlist(selected_file, selected_file_attr, true); |
234 | } | 242 | } |
235 | 243 | ||
236 | static bool cat_playlist_options(void) | ||
237 | { | ||
238 | struct menu_item items[3]; | ||
239 | int m, i=0, result; | ||
240 | bool ret = false; | ||
241 | 244 | ||
242 | if ((audio_status() & AUDIO_STATUS_PLAY && context == CONTEXT_WPS) || | 245 | static int cat_playlist_callback(int action,const struct menu_item_ex *this_item); |
243 | context == CONTEXT_TREE) | 246 | MENUITEM_FUNCTION(cat_view_lists, 0, ID2P(LANG_CATALOG_VIEW), |
247 | catalog_view_playlists, 0, cat_playlist_callback, Icon_Playlist); | ||
248 | MENUITEM_FUNCTION(cat_add_to_list, 0, ID2P(LANG_CATALOG_ADD_TO), | ||
249 | cat_add_to_a_playlist, 0, NULL, Icon_Playlist); | ||
250 | MENUITEM_FUNCTION(cat_add_to_new, 0, ID2P(LANG_CATALOG_ADD_TO_NEW), | ||
251 | cat_add_to_a_new_playlist, 0, NULL, Icon_Playlist); | ||
252 | MAKE_MENU( cat_playlist_menu, ID2P(LANG_CATALOG), cat_playlist_callback, | ||
253 | Icon_Playlist, &cat_view_lists, | ||
254 | &cat_add_to_list, &cat_add_to_new ); | ||
255 | |||
256 | static int cat_playlist_callback(int action,const struct menu_item_ex *this_item) | ||
257 | { | ||
258 | switch (action) | ||
244 | { | 259 | { |
245 | if (context == CONTEXT_WPS) | 260 | case ACTION_REQUEST_MENUITEM: |
246 | { | 261 | if (this_item == &cat_view_lists) |
247 | items[i].desc = ID2P(LANG_CATALOG_VIEW); | 262 | { |
248 | items[i].function = catalog_view_playlists; | 263 | if (context == CONTEXT_WPS) |
249 | i++; | 264 | return action; |
250 | } | 265 | } |
251 | 266 | else if (selected_file && /* set before calling this menu, so safe */ | |
252 | items[i].desc = ID2P(LANG_CATALOG_ADD_TO); | 267 | ((audio_status() & AUDIO_STATUS_PLAY && |
253 | items[i].function = cat_add_to_a_playlist; | 268 | context == CONTEXT_WPS) || |
254 | i++; | 269 | context == CONTEXT_TREE)) |
255 | items[i].desc = ID2P(LANG_CATALOG_ADD_TO_NEW); | 270 | { |
256 | items[i].function = cat_add_to_a_new_playlist; | 271 | return action; |
257 | i++; | 272 | } |
273 | else | ||
274 | return ACTION_EXIT_MENUITEM; | ||
275 | break; | ||
258 | } | 276 | } |
277 | return action; | ||
278 | } | ||
259 | 279 | ||
260 | m = menu_init( items, i, NULL, str(LANG_CATALOG), NULL, NULL ); | ||
261 | result = menu_show(m); | ||
262 | if(result >= 0) | ||
263 | ret = items[result].function(); | ||
264 | menu_exit(m); | ||
265 | 280 | ||
266 | return ret; | 281 | /* CONTEXT_WPS playlist options */ |
282 | MENUITEM_FUNCTION(playlist_viewer_item, 0, | ||
283 | ID2P(LANG_VIEW_DYNAMIC_PLAYLIST), playlist_viewer, | ||
284 | NULL, NULL, Icon_Playlist); | ||
285 | MENUITEM_FUNCTION(search_playlist_item, 0, | ||
286 | ID2P(LANG_SEARCH_IN_PLAYLIST), search_playlist, | ||
287 | NULL, NULL, Icon_Playlist); | ||
288 | MENUITEM_FUNCTION(playlist_save_item, 0, ID2P(LANG_SAVE_DYNAMIC_PLAYLIST), | ||
289 | save_playlist, NULL, NULL, Icon_Playlist); | ||
290 | MENUITEM_FUNCTION(reshuffle_item, 0, ID2P(LANG_SHUFFLE_PLAYLIST), | ||
291 | shuffle_playlist, NULL, NULL, Icon_Playlist); | ||
292 | MAKE_ONPLAYMENU( wps_playlist_menu, ID2P(LANG_PLAYLIST_MENU), | ||
293 | NULL, Icon_Playlist, | ||
294 | &playlist_viewer_item, &search_playlist_item, | ||
295 | &playlist_save_item, &reshuffle_item | ||
296 | ); | ||
297 | |||
298 | /* CONTEXT_[TREE|ID3DB] playlist options */ | ||
299 | static int playlist_insert_func(void *param) | ||
300 | { | ||
301 | add_to_playlist((intptr_t)param, false); | ||
302 | return 0; | ||
267 | } | 303 | } |
268 | 304 | static int playlist_queue_func(void *param) | |
269 | /* Sub-menu for playlist options */ | ||
270 | static bool playlist_options(void) | ||
271 | { | 305 | { |
272 | struct menu_item items[13]; | 306 | add_to_playlist((intptr_t)param, true); |
273 | struct playlist_args args[13]; /* increase these 2 if you add entries! */ | 307 | return 0; |
274 | int m, i=0, pstart=0, result; | 308 | } |
275 | bool ret = false; | 309 | static int treeplaylist_wplayback_callback(int action, |
276 | 310 | const struct menu_item_ex *this_item) | |
277 | if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U && | 311 | { |
278 | context == CONTEXT_TREE) | 312 | (void)this_item; |
279 | { | 313 | switch (action) |
280 | items[i].desc = ID2P(LANG_VIEW); | ||
281 | items[i].function = view_playlist; | ||
282 | i++; | ||
283 | pstart++; | ||
284 | } | ||
285 | |||
286 | if (audio_status() & AUDIO_STATUS_PLAY && | ||
287 | context == CONTEXT_WPS) | ||
288 | { | 314 | { |
289 | items[i].desc = ID2P(LANG_VIEW_DYNAMIC_PLAYLIST); | 315 | case ACTION_REQUEST_MENUITEM: |
290 | items[i].function = playlist_viewer; | 316 | if (audio_status() & AUDIO_STATUS_PLAY) |
291 | i++; | 317 | return action; |
292 | pstart++; | 318 | else |
293 | 319 | return ACTION_EXIT_MENUITEM; | |
294 | items[i].desc = ID2P(LANG_SEARCH_IN_PLAYLIST); | 320 | break; |
295 | items[i].function = search_playlist; | ||
296 | i++; | ||
297 | pstart++; | ||
298 | |||
299 | items[i].desc = ID2P(LANG_SAVE_DYNAMIC_PLAYLIST); | ||
300 | items[i].function = save_playlist; | ||
301 | i++; | ||
302 | pstart++; | ||
303 | |||
304 | items[i].desc = ID2P(LANG_SHUFFLE_PLAYLIST); | ||
305 | items[i].function = shuffle_playlist; | ||
306 | i++; | ||
307 | pstart++; | ||
308 | } | 321 | } |
322 | return action; | ||
323 | } | ||
309 | 324 | ||
310 | if (context == CONTEXT_TREE || context == CONTEXT_ID3DB) | 325 | static int treeplaylist_callback(int action, |
326 | const struct menu_item_ex *this_item); | ||
327 | |||
328 | /* insert items */ | ||
329 | MENUITEM_FUNCTION(i_pl_item, 0, ID2P(LANG_INSERT), | ||
330 | playlist_insert_func, (intptr_t*)PLAYLIST_INSERT, | ||
331 | treeplaylist_callback, Icon_Playlist); | ||
332 | MENUITEM_FUNCTION(i_first_pl_item, 0, ID2P(LANG_INSERT_FIRST), | ||
333 | playlist_insert_func, (intptr_t*)PLAYLIST_INSERT_FIRST, | ||
334 | treeplaylist_wplayback_callback, Icon_Playlist); | ||
335 | MENUITEM_FUNCTION(i_last_pl_item, 0, ID2P(LANG_INSERT_LAST), | ||
336 | playlist_insert_func, (intptr_t*)PLAYLIST_INSERT_LAST, | ||
337 | treeplaylist_wplayback_callback, Icon_Playlist); | ||
338 | MENUITEM_FUNCTION(i_shuf_pl_item, 0, ID2P(LANG_INSERT_SHUFFLED), | ||
339 | playlist_insert_func, (intptr_t*)PLAYLIST_INSERT_SHUFFLED, | ||
340 | treeplaylist_callback, Icon_Playlist); | ||
341 | /* queue items */ | ||
342 | MENUITEM_FUNCTION(q_pl_item, 0, ID2P(LANG_QUEUE), | ||
343 | playlist_queue_func, (intptr_t*)PLAYLIST_INSERT, | ||
344 | treeplaylist_wplayback_callback, Icon_Playlist); | ||
345 | MENUITEM_FUNCTION(q_first_pl_item, 0, ID2P(LANG_QUEUE_FIRST), | ||
346 | playlist_queue_func, (intptr_t*)PLAYLIST_INSERT_FIRST, | ||
347 | treeplaylist_wplayback_callback, Icon_Playlist); | ||
348 | MENUITEM_FUNCTION(q_last_pl_item, 0, ID2P(LANG_QUEUE_LAST), | ||
349 | playlist_queue_func, (intptr_t*)PLAYLIST_INSERT_LAST, | ||
350 | treeplaylist_wplayback_callback, Icon_Playlist); | ||
351 | MENUITEM_FUNCTION(q_shuf_pl_item, 0, ID2P(LANG_QUEUE_SHUFFLED), | ||
352 | playlist_queue_func, (intptr_t*)PLAYLIST_INSERT_SHUFFLED, | ||
353 | treeplaylist_wplayback_callback, Icon_Playlist); | ||
354 | /* replace playlist */ | ||
355 | MENUITEM_FUNCTION(replace_pl_item, 0, ID2P(LANG_REPLACE), | ||
356 | playlist_insert_func, (intptr_t*)PLAYLIST_REPLACE, | ||
357 | treeplaylist_wplayback_callback, Icon_Playlist); | ||
358 | /* others */ | ||
359 | |||
360 | MENUITEM_FUNCTION(view_playlist_item, 0, ID2P(LANG_VIEW), | ||
361 | view_playlist, NULL, | ||
362 | treeplaylist_callback, Icon_Playlist); | ||
363 | |||
364 | MAKE_ONPLAYMENU( tree_playlist_menu, ID2P(LANG_PLAYLIST_MENU), | ||
365 | treeplaylist_callback, Icon_Playlist, &view_playlist_item, | ||
366 | /* insert */ | ||
367 | &i_pl_item, &i_first_pl_item, &i_last_pl_item, &i_shuf_pl_item, | ||
368 | /* queue */ | ||
369 | &q_pl_item, &q_first_pl_item, &q_last_pl_item, &q_shuf_pl_item, | ||
370 | /* replace */ | ||
371 | &replace_pl_item | ||
372 | ); | ||
373 | static int treeplaylist_callback(int action, | ||
374 | const struct menu_item_ex *this_item) | ||
375 | { | ||
376 | (void)this_item; | ||
377 | switch (action) | ||
311 | { | 378 | { |
312 | if (audio_status() & AUDIO_STATUS_PLAY) | 379 | case ACTION_REQUEST_MENUITEM: |
313 | { | 380 | if (this_item == &tree_playlist_menu) |
314 | items[i].desc = ID2P(LANG_INSERT); | ||
315 | args[i].position = PLAYLIST_INSERT; | ||
316 | args[i].queue = false; | ||
317 | i++; | ||
318 | |||
319 | items[i].desc = ID2P(LANG_INSERT_FIRST); | ||
320 | args[i].position = PLAYLIST_INSERT_FIRST; | ||
321 | args[i].queue = false; | ||
322 | i++; | ||
323 | |||
324 | items[i].desc = ID2P(LANG_INSERT_LAST); | ||
325 | args[i].position = PLAYLIST_INSERT_LAST; | ||
326 | args[i].queue = false; | ||
327 | i++; | ||
328 | |||
329 | items[i].desc = ID2P(LANG_INSERT_SHUFFLED); | ||
330 | args[i].position = PLAYLIST_INSERT_SHUFFLED; | ||
331 | args[i].queue = false; | ||
332 | i++; | ||
333 | |||
334 | items[i].desc = ID2P(LANG_QUEUE); | ||
335 | args[i].position = PLAYLIST_INSERT; | ||
336 | args[i].queue = true; | ||
337 | i++; | ||
338 | |||
339 | items[i].desc = ID2P(LANG_QUEUE_FIRST); | ||
340 | args[i].position = PLAYLIST_INSERT_FIRST; | ||
341 | args[i].queue = true; | ||
342 | i++; | ||
343 | |||
344 | items[i].desc = ID2P(LANG_QUEUE_LAST); | ||
345 | args[i].position = PLAYLIST_INSERT_LAST; | ||
346 | args[i].queue = true; | ||
347 | i++; | ||
348 | |||
349 | items[i].desc = ID2P(LANG_QUEUE_SHUFFLED); | ||
350 | args[i].position = PLAYLIST_INSERT_SHUFFLED; | ||
351 | args[i].queue = true; | ||
352 | i++; | ||
353 | |||
354 | items[i].desc = ID2P(LANG_REPLACE); | ||
355 | args[i].position = PLAYLIST_REPLACE; | ||
356 | args[i].queue = false; | ||
357 | i++; | ||
358 | } | ||
359 | else if (((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) || | ||
360 | (selected_file_attr & ATTR_DIRECTORY)) | ||
361 | { | ||
362 | items[i].desc = ID2P(LANG_INSERT); | ||
363 | args[i].position = PLAYLIST_INSERT_LAST; | ||
364 | args[i].queue = false; | ||
365 | i++; | ||
366 | |||
367 | if (selected_file_attr & ATTR_DIRECTORY) | ||
368 | { | 381 | { |
369 | items[i].desc = ID2P(LANG_INSERT_SHUFFLED); | 382 | if (((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) || |
370 | args[i].position = PLAYLIST_INSERT_SHUFFLED; | 383 | (selected_file_attr & ATTR_DIRECTORY)) |
371 | args[i].queue = false; | 384 | { |
372 | i++; | 385 | return action; |
386 | } | ||
387 | else | ||
388 | return ACTION_EXIT_MENUITEM; | ||
373 | } | 389 | } |
374 | } | 390 | else if (this_item == &view_playlist_item) |
391 | { | ||
392 | if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U && | ||
393 | context == CONTEXT_TREE) | ||
394 | return action; | ||
395 | else | ||
396 | return ACTION_EXIT_MENUITEM; | ||
397 | } | ||
398 | if (this_item == &i_pl_item) | ||
399 | return action; | ||
400 | else if (this_item == &i_shuf_pl_item) | ||
401 | { | ||
402 | |||
403 | if (audio_status() & AUDIO_STATUS_PLAY) | ||
404 | { | ||
405 | return action; | ||
406 | } | ||
407 | else if ((this_item == &i_shuf_pl_item) && | ||
408 | (selected_file_attr & ATTR_DIRECTORY)) | ||
409 | { | ||
410 | return action; | ||
411 | } | ||
412 | return ACTION_EXIT_MENUITEM; | ||
413 | } | ||
414 | break; | ||
375 | } | 415 | } |
376 | 416 | return action; | |
377 | m = menu_init( items, i, NULL, str(LANG_PLAYLIST_MENU), NULL, NULL ); | ||
378 | result = menu_show(m); | ||
379 | if (result >= 0 && result < pstart) | ||
380 | ret = items[result].function(); | ||
381 | else if (result >= pstart) | ||
382 | ret = add_to_playlist(args[result].position, args[result].queue); | ||
383 | menu_exit(m); | ||
384 | |||
385 | return ret; | ||
386 | } | 417 | } |
387 | 418 | ||
388 | |||
389 | /* helper function to remove a non-empty directory */ | 419 | /* helper function to remove a non-empty directory */ |
390 | static int remove_dir(char* dirname, int len) | 420 | static int remove_dir(char* dirname, int len) |
391 | { | 421 | { |
@@ -839,31 +869,29 @@ static bool clipboard_paste(void) | |||
839 | return true; | 869 | return true; |
840 | } | 870 | } |
841 | 871 | ||
842 | static bool exit_to_main; | 872 | static int onplaymenu_callback(int action,const struct menu_item_ex *this_item) |
843 | |||
844 | /* catch MENU_EXIT_MENU within context menu to call the main menu afterwards */ | ||
845 | static int onplay_callback(int key, int menu) | ||
846 | { | 873 | { |
847 | (void)menu; | 874 | (void)this_item; |
848 | 875 | switch (action) | |
849 | if (key == ACTION_STD_MENU) | 876 | { |
850 | exit_to_main = true; | 877 | case ACTION_EXIT_MENUITEM: |
851 | 878 | return ACTION_EXIT_AFTER_THIS_MENUITEM; | |
852 | return key; | 879 | break; |
880 | } | ||
881 | return action; | ||
853 | } | 882 | } |
854 | |||
855 | #ifdef HAVE_TAGCACHE | 883 | #ifdef HAVE_TAGCACHE |
856 | char rating_menu_string[32]; | 884 | char *rating_name(int selected_item, void * data, char *buffer) |
857 | |||
858 | static void create_rating_menu(void) | ||
859 | { | 885 | { |
886 | (void)selected_item; (void)data; | ||
860 | struct mp3entry* id3 = audio_current_track(); | 887 | struct mp3entry* id3 = audio_current_track(); |
861 | if(id3) | 888 | if(id3) |
862 | snprintf(rating_menu_string, sizeof rating_menu_string, | 889 | snprintf(buffer, MAX_PATH, |
863 | "%s: %d", str(LANG_MENU_SET_RATING), id3->rating); | 890 | "%s: %d", str(LANG_MENU_SET_RATING), id3->rating); |
864 | else | 891 | else |
865 | snprintf(rating_menu_string, sizeof rating_menu_string, | 892 | snprintf(buffer, MAX_PATH, |
866 | "%s: -", str(LANG_MENU_SET_RATING)); | 893 | "%s: -", str(LANG_MENU_SET_RATING)); |
894 | return buffer; | ||
867 | } | 895 | } |
868 | 896 | ||
869 | static bool set_rating_inline(void) | 897 | static bool set_rating_inline(void) |
@@ -874,207 +902,187 @@ static bool set_rating_inline(void) | |||
874 | id3->rating++; | 902 | id3->rating++; |
875 | else | 903 | else |
876 | id3->rating=0; | 904 | id3->rating=0; |
877 | } | 905 | } |
878 | create_rating_menu(); | ||
879 | return false; | 906 | return false; |
880 | } | 907 | } |
881 | #endif | 908 | static int ratingitem_callback(int action,const struct menu_item_ex *this_item) |
882 | |||
883 | int onplay(char* file, int attr, int from) | ||
884 | { | 909 | { |
885 | #if CONFIG_CODEC == SWCODEC | 910 | (void)this_item; |
886 | struct menu_item items[14]; /* increase this if you add entries! */ | 911 | switch (action) |
887 | #else | ||
888 | struct menu_item items[12]; | ||
889 | #endif | ||
890 | int m, i=0, result; | ||
891 | #if LCD_DEPTH > 1 | ||
892 | char *suffix; | ||
893 | #endif | ||
894 | |||
895 | onplay_result = ONPLAY_OK; | ||
896 | context=from; | ||
897 | exit_to_main = false; | ||
898 | selected_file = file; | ||
899 | selected_file_attr = attr; | ||
900 | |||
901 | if (context == CONTEXT_WPS) | ||
902 | { | ||
903 | items[i].desc = ID2P(LANG_SOUND_SETTINGS); | ||
904 | items[i].function = sound_menu; | ||
905 | i++; | ||
906 | } | ||
907 | |||
908 | if (file && (context == CONTEXT_WPS || | ||
909 | context == CONTEXT_TREE || | ||
910 | context == CONTEXT_ID3DB)) | ||
911 | { | 912 | { |
912 | items[i].desc = ID2P(LANG_PLAYLIST); | 913 | case ACTION_REQUEST_MENUITEM: |
913 | items[i].function = playlist_options; | 914 | if (!selected_file || !global_settings.runtimedb) |
914 | i++; | 915 | return ACTION_EXIT_MENUITEM; |
915 | items[i].desc = ID2P(LANG_CATALOG); | 916 | break; |
916 | items[i].function = cat_playlist_options; | ||
917 | i++; | ||
918 | } | 917 | } |
919 | 918 | return action; | |
920 | if (context == CONTEXT_WPS) | 919 | } |
921 | { | 920 | MENUITEM_FUNCTION_DYNTEXT(rating_item, 0, set_rating_inline, |
922 | #ifdef HAVE_TAGCACHE | 921 | NULL, rating_name, NULL, |
923 | if(file && global_settings.runtimedb) | 922 | ratingitem_callback, Icon_Questionmark); |
924 | { | ||
925 | create_rating_menu(); | ||
926 | items[i].desc = rating_menu_string; | ||
927 | items[i].function = set_rating_inline; | ||
928 | i++; | ||
929 | } | ||
930 | #endif | 923 | #endif |
931 | items[i].desc = ID2P(LANG_BOOKMARK_MENU); | ||
932 | items[i].function = bookmark_menu; | ||
933 | i++; | ||
934 | } | ||
935 | 924 | ||
936 | if (file) | 925 | /* CONTEXT_WPS items */ |
937 | { | 926 | MENUITEM_FUNCTION(browse_id3_item, 0, ID2P(LANG_MENU_SHOW_ID3_INFO), |
938 | if (context == CONTEXT_WPS) | 927 | browse_id3, NULL, NULL, Icon_NOICON); |
939 | { | 928 | #ifdef HAVE_PITCHSCREEN |
940 | items[i].desc = ID2P(LANG_MENU_SHOW_ID3_INFO); | 929 | MENUITEM_FUNCTION(pitch_screen_item, 0, ID2P(LANG_PITCH), |
941 | items[i].function = browse_id3; | 930 | pitch_screen, NULL, NULL, Icon_Audio); |
942 | i++; | 931 | #endif |
943 | } | 932 | #if CONFIG_CODEC == SWCODEC |
933 | MENUITEM_FUNCTION(eq_menu_graphical_item, 0, ID2P(LANG_EQUALIZER_GRAPHICAL), | ||
934 | eq_menu_graphical, NULL, NULL, Icon_Audio); | ||
935 | MENUITEM_FUNCTION(eq_browse_presets_item, 0, ID2P(LANG_EQUALIZER_BROWSE), | ||
936 | eq_browse_presets, NULL, NULL, Icon_Audio); | ||
937 | #endif | ||
944 | 938 | ||
945 | #ifdef HAVE_MULTIVOLUME | 939 | /* CONTEXT_[TREE|ID3DB] items */ |
946 | if (!(attr & ATTR_VOLUME)) /* no rename+delete for volumes */ | 940 | static int clipboard_callback(int action,const struct menu_item_ex *this_item); |
941 | MENUITEM_FUNCTION(rename_file_item, 0, ID2P(LANG_RENAME), | ||
942 | rename_file, NULL, clipboard_callback, Icon_NOICON); | ||
943 | MENUITEM_FUNCTION(clipboard_cut_item, 0, ID2P(LANG_CUT), | ||
944 | clipboard_cut, NULL, clipboard_callback, Icon_NOICON); | ||
945 | MENUITEM_FUNCTION(clipboard_copy_item, 0, ID2P(LANG_COPY), | ||
946 | clipboard_copy, NULL, clipboard_callback, Icon_NOICON); | ||
947 | MENUITEM_FUNCTION(clipboard_paste_item, 0, ID2P(LANG_PASTE), | ||
948 | clipboard_paste, NULL, clipboard_callback, Icon_NOICON); | ||
949 | MENUITEM_FUNCTION(delete_file_item, 0, ID2P(LANG_DELETE), | ||
950 | delete_file, NULL, clipboard_callback, Icon_NOICON); | ||
951 | MENUITEM_FUNCTION(delete_dir_item, 0, ID2P(LANG_DELETE_DIR), | ||
952 | delete_dir, NULL, clipboard_callback, Icon_NOICON); | ||
953 | MENUITEM_FUNCTION(properties_item, 0, ID2P(LANG_PROPERTIES), | ||
954 | properties, NULL, clipboard_callback, Icon_NOICON); | ||
955 | MENUITEM_FUNCTION(create_dir_item, 0, ID2P(LANG_CREATE_DIR), | ||
956 | create_dir, NULL, clipboard_callback, Icon_NOICON); | ||
957 | MENUITEM_FUNCTION(list_viewers_item, 0, ID2P(LANG_ONPLAY_OPEN_WITH), | ||
958 | list_viewers, NULL, clipboard_callback, Icon_NOICON); | ||
959 | #if LCD_DEPTH > 1 | ||
960 | MENUITEM_FUNCTION(set_backdrop_item, 0, ID2P(LANG_SET_AS_BACKDROP), | ||
961 | set_backdrop, NULL, clipboard_callback, Icon_NOICON); | ||
947 | #endif | 962 | #endif |
948 | { | ||
949 | if (context == CONTEXT_TREE) | ||
950 | { | ||
951 | items[i].desc = ID2P(LANG_RENAME); | ||
952 | items[i].function = rename_file; | ||
953 | i++; | ||
954 | 963 | ||
955 | items[i].desc = ID2P(LANG_CUT); | ||
956 | items[i].function = clipboard_cut; | ||
957 | i++; | ||
958 | 964 | ||
959 | items[i].desc = ID2P(LANG_COPY); | ||
960 | items[i].function = clipboard_copy; | ||
961 | i++; | ||
962 | 965 | ||
963 | if (clipboard_selection[0] != 0) /* Something in the clipboard? */ | 966 | static int clipboard_callback(int action,const struct menu_item_ex *this_item) |
964 | { | 967 | { |
965 | items[i].desc = ID2P(LANG_PASTE); | 968 | switch (action) |
966 | items[i].function = clipboard_paste; | 969 | { |
967 | i++; | 970 | case ACTION_REQUEST_MENUITEM: |
968 | } | 971 | if (context == CONTEXT_ID3DB) |
972 | return ACTION_EXIT_MENUITEM; | ||
973 | if (this_item == &clipboard_paste_item) | ||
974 | { /* visible if there is something to paste */ | ||
975 | return (clipboard_selection[0] != 0) ? | ||
976 | action : ACTION_EXIT_MENUITEM; | ||
969 | } | 977 | } |
970 | 978 | else if ((this_item == &create_dir_item) || | |
971 | if (!(attr & ATTR_DIRECTORY) && context == CONTEXT_TREE) | 979 | (this_item == &properties_item) || |
980 | (this_item == &rename_file_item) || | ||
981 | (this_item == &clipboard_cut_item) || | ||
982 | (this_item == &clipboard_copy_item) | ||
983 | ) | ||
972 | { | 984 | { |
973 | items[i].desc = ID2P(LANG_DELETE); | 985 | /* always visible */ |
974 | items[i].function = delete_file; | 986 | return action; |
975 | i++; | 987 | } |
976 | |||
977 | #if LCD_DEPTH > 1 | 988 | #if LCD_DEPTH > 1 |
978 | suffix = strrchr(file, '.'); | 989 | else if (this_item == &set_backdrop_item) |
979 | if (suffix) | 990 | { |
991 | if (selected_file) | ||
980 | { | 992 | { |
981 | if (strcasecmp(suffix, ".bmp") == 0) | 993 | char *suffix = strrchr(selected_file, '.'); |
994 | if (suffix) | ||
982 | { | 995 | { |
983 | items[i].desc = ID2P(LANG_SET_AS_BACKDROP); | 996 | if (strcasecmp(suffix, ".bmp") == 0) |
984 | items[i].function = set_backdrop; | 997 | { |
985 | i++; | 998 | return action; |
999 | } | ||
986 | } | 1000 | } |
987 | } | 1001 | } |
1002 | return ACTION_EXIT_MENUITEM; | ||
1003 | } | ||
988 | #endif | 1004 | #endif |
1005 | else if ((selected_file_attr & ATTR_DIRECTORY)) | ||
1006 | { | ||
1007 | if ((this_item == &delete_dir_item) | ||
1008 | ) | ||
1009 | return action; | ||
989 | } | 1010 | } |
990 | else | 1011 | else if (selected_file |
1012 | #ifdef HAVE_MULTIVOLUME | ||
1013 | /* no rename+delete for volumes */ | ||
1014 | && !(selected_file_attr & ATTR_VOLUME) | ||
1015 | #endif | ||
1016 | ) | ||
991 | { | 1017 | { |
992 | if (context == CONTEXT_TREE) | 1018 | if ((this_item == &delete_file_item) || |
1019 | (this_item == &list_viewers_item)) | ||
993 | { | 1020 | { |
994 | items[i].desc = ID2P(LANG_DELETE_DIR); | 1021 | return action; |
995 | items[i].function = delete_dir; | ||
996 | i++; | ||
997 | } | 1022 | } |
998 | } | 1023 | } |
999 | } | 1024 | return ACTION_EXIT_MENUITEM; |
1000 | 1025 | break; | |
1001 | if (!(attr & ATTR_DIRECTORY)) | ||
1002 | { | ||
1003 | items[i].desc = ID2P(LANG_ONPLAY_OPEN_WITH); | ||
1004 | items[i].function = list_viewers; | ||
1005 | i++; | ||
1006 | } | ||
1007 | } | ||
1008 | else | ||
1009 | { | ||
1010 | if (strlen(clipboard_selection) != 0) | ||
1011 | { | ||
1012 | items[i].desc = ID2P(LANG_PASTE); | ||
1013 | items[i].function = clipboard_paste; | ||
1014 | i++; | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | if (context == CONTEXT_TREE) | ||
1019 | { | ||
1020 | items[i].desc = ID2P(LANG_CREATE_DIR); | ||
1021 | items[i].function = create_dir; | ||
1022 | i++; | ||
1023 | if (file) | ||
1024 | { | ||
1025 | items[i].desc = ID2P(LANG_PROPERTIES); | ||
1026 | items[i].function = properties; | ||
1027 | i++; | ||
1028 | } | ||
1029 | } | 1026 | } |
1027 | return action; | ||
1028 | } | ||
1029 | /* used when onplay() is called in the CONTEXT_WPS context */ | ||
1030 | 1030 | ||
1031 | if (context == CONTEXT_WPS) | 1031 | |
1032 | { | 1032 | MAKE_ONPLAYMENU( wps_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE), |
1033 | onplaymenu_callback, Icon_Audio, | ||
1034 | &sound_settings, &wps_playlist_menu, &cat_playlist_menu, | ||
1035 | #ifdef HAVE_TAGCACHE | ||
1036 | &rating_item, | ||
1037 | #endif | ||
1038 | &bookmark_menu, &browse_id3_item, | ||
1033 | #ifdef HAVE_PITCHSCREEN | 1039 | #ifdef HAVE_PITCHSCREEN |
1034 | /* Pitch screen access */ | 1040 | &pitch_screen_item, |
1035 | items[i].desc = ID2P(LANG_PITCH); | ||
1036 | items[i].function = pitch_screen; | ||
1037 | i++; | ||
1038 | #endif | 1041 | #endif |
1039 | #if CONFIG_CODEC == SWCODEC | 1042 | #if CONFIG_CODEC == SWCODEC |
1040 | /* Equalizer menu items */ | 1043 | &eq_menu_graphical_item, &eq_browse_presets_item, |
1041 | items[i].desc = ID2P(LANG_EQUALIZER_GRAPHICAL); | ||
1042 | items[i].function = eq_menu_graphical; | ||
1043 | i++; | ||
1044 | items[i].desc = ID2P(LANG_EQUALIZER_BROWSE); | ||
1045 | items[i].function = eq_browse_presets; | ||
1046 | i++; | ||
1047 | #endif | 1044 | #endif |
1048 | } | 1045 | ); |
1049 | 1046 | /* used when onplay() is not called in the CONTEXT_WPS context */ | |
1050 | /* DIY menu handling, since we want to exit after selection */ | 1047 | MAKE_ONPLAYMENU( tree_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE), |
1051 | if (i) | 1048 | onplaymenu_callback, Icon_file_view_menu, |
1049 | &tree_playlist_menu, &cat_playlist_menu, | ||
1050 | &rename_file_item, &clipboard_cut_item, &clipboard_copy_item, | ||
1051 | &clipboard_paste_item, &delete_file_item, &delete_dir_item, | ||
1052 | #if LCD_DEPTH > 1 | ||
1053 | &set_backdrop_item, | ||
1054 | #endif | ||
1055 | &list_viewers_item, &create_dir_item, &properties_item | ||
1056 | ); | ||
1057 | int onplay(char* file, int attr, int from) | ||
1058 | { | ||
1059 | int menu_result; | ||
1060 | int selected_item = 0; /* this is a bit of a hack to reopen | ||
1061 | the menu if certain items are selected */ | ||
1062 | onplay_result = ONPLAY_OK; | ||
1063 | context = from; | ||
1064 | selected_file = file; | ||
1065 | selected_file_attr = attr; | ||
1066 | if (context == CONTEXT_WPS) | ||
1052 | { | 1067 | { |
1053 | m = menu_init( items, i, onplay_callback, | 1068 | #ifdef HAVE_TAGCACHE |
1054 | str(LANG_ONPLAY_MENU_TITLE), NULL, NULL ); | 1069 | do { |
1055 | #ifdef HAVE_TAGCACHE | 1070 | #endif |
1056 | do | 1071 | menu_result = do_menu(&wps_onplay_menu, &selected_item); |
1057 | { | 1072 | #ifdef HAVE_TAGCACHE |
1058 | #endif | 1073 | } while ((wps_onplay_menu_[selected_item] == &rating_item)); |
1059 | result = menu_show(m); | ||
1060 | if (result >= 0) | ||
1061 | items[result].function(); | ||
1062 | #ifdef HAVE_TAGCACHE | ||
1063 | } | ||
1064 | while (items[result].function == set_rating_inline); | ||
1065 | #endif | ||
1066 | menu_exit(m); | ||
1067 | |||
1068 | if (exit_to_main) | ||
1069 | onplay_result = ONPLAY_MAINMENU; | ||
1070 | |||
1071 | #ifdef HAVE_LCD_BITMAP | ||
1072 | if (global_settings.statusbar) | ||
1073 | lcd_setmargins(0, STATUSBAR_HEIGHT); | ||
1074 | else | ||
1075 | lcd_setmargins(0, 0); | ||
1076 | #endif | 1074 | #endif |
1077 | } | 1075 | } |
1078 | 1076 | else | |
1079 | return onplay_result; | 1077 | menu_result = do_menu(&tree_onplay_menu, NULL); |
1078 | switch (menu_result) | ||
1079 | { | ||
1080 | case GO_TO_WPS: | ||
1081 | return ONPLAY_START_PLAY; | ||
1082 | case GO_TO_ROOT: | ||
1083 | case GO_TO_MAINMENU: | ||
1084 | return ONPLAY_MAINMENU; | ||
1085 | default: | ||
1086 | return context == CONTEXT_WPS ? ONPLAY_OK : ONPLAY_RELOAD_DIR; | ||
1087 | } | ||
1080 | } | 1088 | } |