make sure closing the application aborts the remaining HttpGet objects. Should fix...
[Rockbox.git] / apps / menus / display_menu.c
blobc1e574a974d987367a3b1d305572edc3132fd80e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Jonathan Gordon
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <limits.h>
23 #include "config.h"
24 #include "lang.h"
25 #include "action.h"
26 #include "settings.h"
27 #include "menu.h"
28 #include "tree.h"
29 #include "list.h"
30 #ifdef HAVE_LCD_BITMAP
31 #include "peakmeter.h"
32 #endif
33 #include "talk.h"
34 #include "color_picker.h"
35 #include "lcd.h"
36 #include "lcd-remote.h"
38 #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
39 #include "backdrop.h"
40 #endif
43 #ifdef HAVE_BACKLIGHT
44 int filterfirstkeypress_callback(int action,const struct menu_item_ex *this_item)
46 (void)this_item;
47 switch (action)
49 case ACTION_EXIT_MENUITEM:
50 set_backlight_filter_keypress(global_settings.bl_filter_first_keypress);
51 #ifdef HAVE_REMOTE_LCD
52 set_remote_backlight_filter_keypress(
53 global_settings.remote_bl_filter_first_keypress);
54 #endif
56 break;
58 return action;
60 #endif
61 #ifdef HAVE_LCD_BITMAP
62 int flipdisplay_callback(int action,const struct menu_item_ex *this_item)
64 (void)this_item;
65 switch (action)
67 case ACTION_EXIT_MENUITEM:
68 button_set_flip(global_settings.flip_display);
69 lcd_set_flip(global_settings.flip_display);
70 #ifdef HAVE_REMOTE_LCD
71 lcd_remote_set_flip(global_settings.remote_flip_display);
72 lcd_remote_update();
73 #endif
74 break;
76 return action;
78 #endif
80 /***********************************/
81 /* LCD MENU */
82 #ifdef HAVE_BACKLIGHT
83 MENUITEM_SETTING(backlight_timeout, &global_settings.backlight_timeout, NULL);
84 #if CONFIG_CHARGING
85 MENUITEM_SETTING(backlight_timeout_plugged,
86 &global_settings.backlight_timeout_plugged, NULL);
87 #endif
88 #ifdef HAS_BUTTON_HOLD
89 MENUITEM_SETTING(backlight_on_button_hold,
90 &global_settings.backlight_on_button_hold, NULL);
91 #endif
92 MENUITEM_SETTING(caption_backlight, &global_settings.caption_backlight, NULL);
93 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
94 MENUITEM_SETTING(backlight_fade_in, &global_settings.backlight_fade_in, NULL);
95 MENUITEM_SETTING(backlight_fade_out, &global_settings.backlight_fade_out, NULL);
96 #endif
97 MENUITEM_SETTING(bl_filter_first_keypress,
98 &global_settings.bl_filter_first_keypress,
99 filterfirstkeypress_callback);
100 #ifdef HAVE_LCD_SLEEP
101 MENUITEM_SETTING(lcd_sleep_after_backlight_off,
102 &global_settings.lcd_sleep_after_backlight_off, NULL);
103 #endif
104 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
105 MENUITEM_SETTING(brightness_item, &global_settings.brightness, NULL);
106 #endif
107 #endif /* HAVE_BACKLIGHT */
108 #ifdef HAVE_LCD_CONTRAST
109 MENUITEM_SETTING(contrast, &global_settings.contrast, NULL);
110 #endif
111 #ifdef HAVE_LCD_BITMAP
112 #ifdef HAVE_LCD_INVERT
113 MENUITEM_SETTING(invert, &global_settings.invert, NULL);
114 #endif
115 #ifdef HAVE_LCD_FLIP
116 MENUITEM_SETTING(flip_display, &global_settings.flip_display, flipdisplay_callback);
117 #endif
118 MENUITEM_SETTING(invert_cursor, &global_settings.invert_cursor, NULL);
119 #endif /* HAVE_LCD_BITMAP */
120 #if LCD_DEPTH > 1
122 * Menu to clear the backdrop image
124 static int clear_main_backdrop(void)
126 global_settings.backdrop_file[0]=0;
127 unload_main_backdrop();
128 show_main_backdrop();
129 settings_save();
130 return 0;
132 MENUITEM_FUNCTION(clear_main_bd, 0, ID2P(LANG_CLEAR_BACKDROP),
133 clear_main_backdrop, NULL, NULL, Icon_NOICON);
134 #endif /* LCD_DEPTH > 1 */
135 #ifdef HAVE_LCD_COLOR
137 * Menu for fore/back colors
139 static int set_fg_color(void)
141 int res;
142 res = (int)set_color(&screens[SCREEN_MAIN],str(LANG_FOREGROUND_COLOR),
143 &global_settings.fg_color,global_settings.bg_color);
145 screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
146 settings_save();
147 return res;
150 static int set_bg_color(void)
152 int res;
153 res = (int)set_color(&screens[SCREEN_MAIN],str(LANG_BACKGROUND_COLOR),
154 &global_settings.bg_color,global_settings.fg_color);
156 screens[SCREEN_MAIN].set_background(global_settings.bg_color);
157 settings_save();
158 return res;
160 static int reset_color(void)
162 global_settings.fg_color = LCD_DEFAULT_FG;
163 global_settings.bg_color = LCD_DEFAULT_BG;
165 screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
166 screens[SCREEN_MAIN].set_background(global_settings.bg_color);
167 settings_save();
168 return 0;
170 MENUITEM_FUNCTION(set_bg_col, 0, ID2P(LANG_BACKGROUND_COLOR),
171 set_bg_color, NULL, NULL, Icon_NOICON);
172 MENUITEM_FUNCTION(set_fg_col, 0, ID2P(LANG_FOREGROUND_COLOR),
173 set_fg_color, NULL, NULL, Icon_NOICON);
174 MENUITEM_FUNCTION(reset_colors, 0, ID2P(LANG_RESET_COLORS),
175 reset_color, NULL, NULL, Icon_NOICON);
176 #endif
178 /* now the actual menu */
179 MAKE_MENU(lcd_settings,ID2P(LANG_LCD_MENU),
180 NULL, Icon_Display_menu
181 #ifdef HAVE_BACKLIGHT
182 ,&backlight_timeout
183 # if CONFIG_CHARGING
184 ,&backlight_timeout_plugged
185 # endif
186 # ifdef HAS_BUTTON_HOLD
187 ,&backlight_on_button_hold
188 # endif
189 ,&caption_backlight
190 # if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
191 ,&backlight_fade_in, &backlight_fade_out
192 # endif
193 ,&bl_filter_first_keypress
194 # ifdef HAVE_LCD_SLEEP
195 ,&lcd_sleep_after_backlight_off
196 # endif
197 # ifdef HAVE_BACKLIGHT_BRIGHTNESS
198 ,&brightness_item
199 # endif
200 #endif /* HAVE_BACKLIGHT */
201 #ifdef HAVE_LCD_CONTRAST
202 ,&contrast
203 #endif
204 #ifdef HAVE_LCD_BITMAP
205 # ifdef HAVE_LCD_INVERT
206 ,&invert
207 # endif
208 # ifdef HAVE_LCD_FLIP
209 ,&flip_display
210 # endif
211 ,&invert_cursor
212 #endif /* HAVE_LCD_BITMAP */
213 #if LCD_DEPTH > 1
214 ,&clear_main_bd,
215 #endif
216 #ifdef HAVE_LCD_COLOR
217 &set_bg_col, &set_fg_col, &reset_colors
218 #endif
220 /* LCD MENU */
221 /***********************************/
224 /********************************/
225 /* Remote LCD settings menu */
226 #ifdef HAVE_REMOTE_LCD
227 MENUITEM_SETTING(remote_backlight_timeout,
228 &global_settings.remote_backlight_timeout, NULL);
230 #if CONFIG_CHARGING
231 MENUITEM_SETTING(remote_backlight_timeout_plugged,
232 &global_settings.remote_backlight_timeout_plugged, NULL);
233 #endif
235 #ifdef HAS_REMOTE_BUTTON_HOLD
236 MENUITEM_SETTING(remote_backlight_on_button_hold,
237 &global_settings.remote_backlight_on_button_hold, NULL);
238 #endif
240 MENUITEM_SETTING(remote_caption_backlight,
241 &global_settings.remote_caption_backlight, NULL);
242 MENUITEM_SETTING(remote_bl_filter_first_keypress,
243 &global_settings.remote_bl_filter_first_keypress,
244 filterfirstkeypress_callback);
245 MENUITEM_SETTING(remote_contrast,
246 &global_settings.remote_contrast, NULL);
247 MENUITEM_SETTING(remote_invert,
248 &global_settings.remote_invert, NULL);
250 MENUITEM_SETTING(remote_flip_display,
251 &global_settings.remote_flip_display, flipdisplay_callback);
253 #ifdef HAVE_REMOTE_LCD_TICKING
254 int ticking_callback(int action,const struct menu_item_ex *this_item)
256 (void)this_item;
257 switch (action)
259 case ACTION_EXIT_MENUITEM:
260 lcd_remote_emireduce(global_settings.remote_reduce_ticking);
261 break;
263 return action;
265 MENUITEM_SETTING(remote_reduce_ticking,
266 &global_settings.remote_reduce_ticking, ticking_callback);
267 #endif
269 MAKE_MENU(lcd_remote_settings, ID2P(LANG_LCD_REMOTE_MENU),
270 NULL, Icon_Remote_Display_menu,
271 &remote_backlight_timeout,
272 #if CONFIG_CHARGING
273 &remote_backlight_timeout_plugged,
274 #endif
275 #ifdef HAS_REMOTE_BUTTON_HOLD
276 &remote_backlight_on_button_hold,
277 #endif
278 &remote_caption_backlight, &remote_bl_filter_first_keypress,
279 &remote_contrast, &remote_invert, &remote_flip_display
280 #ifdef HAVE_REMOTE_LCD_TICKING
281 ,&remote_reduce_ticking
282 #endif
285 #endif /* HAVE_REMOTE_LCD */
286 /* Remote LCD settings menu */
287 /********************************/
289 /***********************************/
290 /* SCROLL MENU */
291 MENUITEM_SETTING_W_TEXT(scroll_speed, &global_settings.scroll_speed,
292 ID2P(LANG_SCROLL), NULL);
293 MENUITEM_SETTING(scroll_delay, &global_settings.scroll_delay, NULL);
294 #ifdef HAVE_LCD_BITMAP
295 MENUITEM_SETTING_W_TEXT(scroll_step, &global_settings.scroll_step,
296 ID2P(LANG_SCROLL_STEP_EXAMPLE), NULL);
297 #endif
298 MENUITEM_SETTING(bidir_limit, &global_settings.bidir_limit, NULL);
299 #ifdef HAVE_REMOTE_LCD
300 MENUITEM_SETTING_W_TEXT(remote_scroll_speed, &global_settings.remote_scroll_speed,
301 ID2P(LANG_SCROLL), NULL);
302 MENUITEM_SETTING(remote_scroll_delay, &global_settings.remote_scroll_delay, NULL);
303 MENUITEM_SETTING_W_TEXT(remote_scroll_step, &global_settings.remote_scroll_step,
304 ID2P(LANG_SCROLL_STEP_EXAMPLE), NULL);
305 MENUITEM_SETTING(remote_bidir_limit, &global_settings.remote_bidir_limit, NULL);
307 MAKE_MENU(remote_scroll_sets, ID2P(LANG_REMOTE_SCROLL_SETS), 0, Icon_NOICON,
308 &remote_scroll_speed, &remote_scroll_delay,
309 &remote_scroll_step, &remote_bidir_limit);
310 #endif /* HAVE_REMOTE_LCD */
311 #ifdef HAVE_LCD_CHARCELLS
312 MENUITEM_SETTING(jump_scroll, &global_settings.jump_scroll, NULL);
313 MENUITEM_SETTING(jump_scroll_delay, &global_settings.jump_scroll_delay, NULL);
314 #endif
315 /* list acceleration */
316 #ifndef HAVE_SCROLLWHEEL
317 MENUITEM_SETTING(list_accel_start_delay,
318 &global_settings.list_accel_start_delay, NULL);
319 MENUITEM_SETTING(list_accel_wait, &global_settings.list_accel_wait, NULL);
320 #endif /* HAVE_SCROLLWHEEL */
321 #ifdef HAVE_LCD_BITMAP
322 int screenscroll_callback(int action,const struct menu_item_ex *this_item)
324 (void)this_item;
325 switch (action)
327 case ACTION_EXIT_MENUITEM:
328 gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
329 break;
331 return action;
333 MENUITEM_SETTING(offset_out_of_view, &global_settings.offset_out_of_view,
334 screenscroll_callback);
335 MENUITEM_SETTING(screen_scroll_step, &global_settings.screen_scroll_step, NULL);
336 #endif
337 MENUITEM_SETTING(scroll_paginated, &global_settings.scroll_paginated, NULL);
339 MAKE_MENU(scroll_settings_menu, ID2P(LANG_SCROLL_MENU), 0, Icon_NOICON,
340 &scroll_speed, &scroll_delay,
341 #ifdef HAVE_LCD_BITMAP
342 &scroll_step,
343 #endif
344 &bidir_limit,
345 #ifdef HAVE_REMOTE_LCD
346 &remote_scroll_sets,
347 #endif
348 #ifdef HAVE_LCD_CHARCELLS
349 &jump_scroll, &jump_scroll_delay,
350 #endif
351 #ifdef HAVE_LCD_BITMAP
352 &offset_out_of_view, &screen_scroll_step,
353 #endif
354 &scroll_paginated,
355 #ifndef HAVE_SCROLLWHEEL
356 &list_accel_start_delay, &list_accel_wait
357 #endif
359 /* SCROLL MENU */
360 /***********************************/
362 /***********************************/
363 /* BARS MENU */
364 #ifdef HAVE_LCD_BITMAP
365 MENUITEM_SETTING(scrollbar_item, &global_settings.scrollbar, NULL);
366 MENUITEM_SETTING(statusbar, &global_settings.statusbar, NULL);
367 #if CONFIG_KEYPAD == RECORDER_PAD
368 MENUITEM_SETTING(buttonbar, &global_settings.buttonbar, NULL);
369 #endif
370 MENUITEM_SETTING(volume_type, &global_settings.volume_type, NULL);
371 MENUITEM_SETTING(battery_display, &global_settings.battery_display, NULL);
372 MAKE_MENU(bars_menu, ID2P(LANG_BARS_MENU), 0, Icon_NOICON,
373 &scrollbar_item, &statusbar,
374 #if CONFIG_KEYPAD == RECORDER_PAD
375 &buttonbar,
376 #endif
377 &volume_type, &battery_display);
378 #endif /* HAVE_LCD_BITMAP */
379 /* BARS MENU */
380 /***********************************/
383 /***********************************/
384 /* PEAK METER MENU */
386 #ifdef HAVE_LCD_BITMAP
387 int peakmeter_callback(int action,const struct menu_item_ex *this_item)
389 (void)this_item;
390 switch (action)
392 case ACTION_EXIT_MENUITEM:
393 peak_meter_init_times(global_settings.peak_meter_release,
394 global_settings.peak_meter_hold,
395 global_settings.peak_meter_clip_hold);
396 break;
398 return action;
400 MENUITEM_SETTING(peak_meter_hold,
401 &global_settings.peak_meter_hold, peakmeter_callback);
402 MENUITEM_SETTING(peak_meter_clip_hold,
403 &global_settings.peak_meter_clip_hold, peakmeter_callback);
404 #ifdef HAVE_RECORDING
405 MENUITEM_SETTING(peak_meter_clipcounter,
406 &global_settings.peak_meter_clipcounter, NULL);
407 #endif
408 MENUITEM_SETTING(peak_meter_release,
409 &global_settings.peak_meter_release, peakmeter_callback);
411 * Menu to select wether the scale of the meter
412 * displays dBfs of linear values.
414 static int peak_meter_scale(void) {
415 bool retval = false;
416 bool use_dbfs = global_settings.peak_meter_dbfs;
417 retval = set_bool_options(str(LANG_PM_SCALE),
418 &use_dbfs,
419 STR(LANG_PM_DBFS), STR(LANG_PM_LINEAR),
420 NULL);
422 /* has the user really changed the scale? */
423 if (use_dbfs != global_settings.peak_meter_dbfs) {
425 /* store the change */
426 global_settings.peak_meter_dbfs = use_dbfs;
427 peak_meter_set_use_dbfs(use_dbfs);
429 /* If the user changed the scale mode the meaning of
430 peak_meter_min (peak_meter_max) has changed. Thus we have
431 to convert the values stored in global_settings. */
432 if (use_dbfs) {
434 /* we only store -dBfs */
435 global_settings.peak_meter_min = -peak_meter_get_min() / 100;
436 global_settings.peak_meter_max = -peak_meter_get_max() / 100;
438 /* limit the returned value to the allowed range */
439 if(global_settings.peak_meter_min > 89)
440 global_settings.peak_meter_min = 89;
441 } else {
442 int max;
444 /* linear percent */
445 global_settings.peak_meter_min = peak_meter_get_min();
447 /* converting dBfs -> percent results in a precision loss.
448 I assume that the user doesn't bother that conversion
449 dBfs <-> percent isn't symmetrical for odd values but that
450 he wants 0 dBfs == 100%. Thus I 'correct' the percent value
451 resulting from dBfs -> percent manually here */
452 max = peak_meter_get_max();
453 global_settings.peak_meter_max = max < 99 ? max : 100;
455 settings_apply_pm_range();
457 return retval;
461 * Adjust the min value of the value range that
462 * the peak meter shall visualize.
464 static int peak_meter_min(void) {
465 bool retval = false;
466 if (global_settings.peak_meter_dbfs) {
468 /* for dBfs scale */
469 int range_max = -global_settings.peak_meter_max;
470 int min = -global_settings.peak_meter_min;
472 retval = set_int(str(LANG_PM_MIN), str(LANG_PM_DBFS), UNIT_DB,
473 &min, NULL, 1, -89, range_max, NULL);
475 global_settings.peak_meter_min = - min;
478 /* for linear scale */
479 else {
480 int min = global_settings.peak_meter_min;
482 retval = set_int(str(LANG_PM_MIN), "%", UNIT_PERCENT,
483 &min, NULL,
484 1, 0, global_settings.peak_meter_max - 1, NULL);
486 global_settings.peak_meter_min = (unsigned char)min;
489 settings_apply_pm_range();
490 return retval;
495 * Adjust the max value of the value range that
496 * the peak meter shall visualize.
498 static int peak_meter_max(void) {
499 bool retval = false;
500 if (global_settings.peak_meter_dbfs) {
502 /* for dBfs scale */
503 int range_min = -global_settings.peak_meter_min;
504 int max = -global_settings.peak_meter_max;;
506 retval = set_int(str(LANG_PM_MAX), str(LANG_PM_DBFS), UNIT_DB,
507 &max, NULL, 1, range_min, 0, NULL);
509 global_settings.peak_meter_max = - max;
513 /* for linear scale */
514 else {
515 int max = global_settings.peak_meter_max;
517 retval = set_int(str(LANG_PM_MAX), "%", UNIT_PERCENT,
518 &max, NULL,
519 1, global_settings.peak_meter_min + 1, 100, NULL);
521 global_settings.peak_meter_max = (unsigned char)max;
524 settings_apply_pm_range();
525 return retval;
527 MENUITEM_FUNCTION(peak_meter_scale_item, 0, ID2P(LANG_PM_SCALE),
528 peak_meter_scale, NULL, NULL, Icon_NOICON);
529 MENUITEM_FUNCTION(peak_meter_min_item, 0, ID2P(LANG_PM_MIN),
530 peak_meter_min, NULL, NULL, Icon_NOICON);
531 MENUITEM_FUNCTION(peak_meter_max_item, 0, ID2P(LANG_PM_MAX),
532 peak_meter_max, NULL, NULL, Icon_NOICON);
533 MAKE_MENU(peak_meter_menu, ID2P(LANG_PM_MENU), NULL, Icon_NOICON,
534 &peak_meter_release, &peak_meter_hold,
535 &peak_meter_clip_hold,
536 #ifdef HAVE_RECORDING
537 &peak_meter_clipcounter,
538 #endif
539 &peak_meter_scale_item, &peak_meter_min_item, &peak_meter_max_item);
540 #endif /* HAVE_LCD_BITMAP */
541 /* PEAK METER MENU */
542 /***********************************/
546 struct browse_folder_info {
547 const char* dir;
548 int show_options;
550 #ifdef HAVE_LCD_BITMAP
551 static struct browse_folder_info fonts = {FONT_DIR, SHOW_FONT};
552 #endif
553 static struct browse_folder_info wps = {WPS_DIR, SHOW_WPS};
554 #ifdef HAVE_REMOTE_LCD
555 static struct browse_folder_info rwps = {WPS_DIR, SHOW_RWPS};
556 #endif
558 static int browse_folder(void *param)
560 const struct browse_folder_info *info =
561 (const struct browse_folder_info*)param;
562 return rockbox_browse(info->dir, info->show_options);
565 #ifdef HAVE_LCD_BITMAP
566 MENUITEM_FUNCTION(browse_fonts, MENU_FUNC_USEPARAM,
567 ID2P(LANG_CUSTOM_FONT),
568 browse_folder, (void*)&fonts, NULL, Icon_NOICON);
569 #endif
570 MENUITEM_FUNCTION(browse_wps, MENU_FUNC_USEPARAM,
571 ID2P(LANG_WHILE_PLAYING),
572 browse_folder, (void*)&wps, NULL, Icon_NOICON);
573 #ifdef HAVE_REMOTE_LCD
574 MENUITEM_FUNCTION(browse_rwps, MENU_FUNC_USEPARAM,
575 ID2P(LANG_REMOTE_WHILE_PLAYING),
576 browse_folder, (void*)&rwps, NULL, Icon_NOICON);
577 #endif
579 MENUITEM_SETTING(show_icons, &global_settings.show_icons, NULL);
580 MENUITEM_SETTING(codepage_setting, &global_settings.default_codepage, NULL);
583 MAKE_MENU(display_menu, ID2P(LANG_DISPLAY),
584 NULL, Icon_Display_menu,
585 #ifdef HAVE_LCD_BITMAP
586 &browse_fonts,
587 #endif
588 &browse_wps,
589 #ifdef HAVE_REMOTE_LCD
590 &browse_rwps,
591 #endif
592 &lcd_settings,
593 #ifdef HAVE_REMOTE_LCD
594 &lcd_remote_settings,
595 #endif
596 &show_icons, &scroll_settings_menu,
597 #ifdef HAVE_LCD_BITMAP
598 &bars_menu, &peak_meter_menu,
599 #endif
600 &codepage_setting,