Colour targets: Revert an optimisation from almost 18 months ago that actually turned...
[Rockbox.git] / apps / menus / display_menu.c
bloba938f590a9e9bedf9dfa4ebe85ce206777cb8687
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <stdbool.h>
23 #include <stddef.h>
24 #include <limits.h>
25 #include "config.h"
26 #include "events.h"
27 #include "lang.h"
28 #include "action.h"
29 #include "settings.h"
30 #include "menu.h"
31 #include "tree.h"
32 #include "list.h"
33 #ifdef HAVE_LCD_BITMAP
34 #include "peakmeter.h"
35 #endif
36 #include "talk.h"
37 #include "color_picker.h"
38 #include "lcd.h"
39 #include "lcd-remote.h"
40 #include "backdrop.h"
41 #include "statusbar.h"
43 #ifdef HAVE_BACKLIGHT
44 static 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_FLIP
62 static 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 lcd_update();
71 #ifdef HAVE_REMOTE_LCD
72 lcd_remote_set_flip(global_settings.remote_flip_display);
73 lcd_remote_update();
74 #endif
75 break;
77 return action;
79 #endif
81 /***********************************/
82 /* LCD MENU */
83 #ifdef HAVE_BACKLIGHT
84 MENUITEM_SETTING(backlight_timeout, &global_settings.backlight_timeout, NULL);
85 #if CONFIG_CHARGING
86 MENUITEM_SETTING(backlight_timeout_plugged,
87 &global_settings.backlight_timeout_plugged, NULL);
88 #endif
89 #ifdef HAS_BUTTON_HOLD
90 MENUITEM_SETTING(backlight_on_button_hold,
91 &global_settings.backlight_on_button_hold, NULL);
92 #endif
93 MENUITEM_SETTING(caption_backlight, &global_settings.caption_backlight, NULL);
94 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
95 MENUITEM_SETTING(backlight_fade_in, &global_settings.backlight_fade_in, NULL);
96 MENUITEM_SETTING(backlight_fade_out, &global_settings.backlight_fade_out, NULL);
97 #endif
98 MENUITEM_SETTING(bl_filter_first_keypress,
99 &global_settings.bl_filter_first_keypress,
100 filterfirstkeypress_callback);
101 #ifdef HAVE_LCD_SLEEP_SETTING
102 MENUITEM_SETTING(lcd_sleep_after_backlight_off,
103 &global_settings.lcd_sleep_after_backlight_off, NULL);
104 #endif
105 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
106 MENUITEM_SETTING(brightness_item, &global_settings.brightness, NULL);
107 #endif
108 #endif /* HAVE_BACKLIGHT */
109 #ifdef HAVE_LCD_CONTRAST
110 MENUITEM_SETTING(contrast, &global_settings.contrast, NULL);
111 #endif
112 #ifdef HAVE_LCD_BITMAP
113 #ifdef HAVE_LCD_INVERT
114 MENUITEM_SETTING(invert, &global_settings.invert, NULL);
115 #endif
116 #ifdef HAVE_LCD_FLIP
117 MENUITEM_SETTING(flip_display, &global_settings.flip_display, flipdisplay_callback);
118 #endif
119 #endif /* HAVE_LCD_BITMAP */
121 /* now the actual menu */
122 MAKE_MENU(lcd_settings,ID2P(LANG_LCD_MENU),
123 NULL, Icon_Display_menu
124 #ifdef HAVE_BACKLIGHT
125 ,&backlight_timeout
126 # if CONFIG_CHARGING
127 ,&backlight_timeout_plugged
128 # endif
129 # ifdef HAS_BUTTON_HOLD
130 ,&backlight_on_button_hold
131 # endif
132 ,&caption_backlight
133 # if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
134 ,&backlight_fade_in, &backlight_fade_out
135 # endif
136 ,&bl_filter_first_keypress
137 # ifdef HAVE_LCD_SLEEP_SETTING
138 ,&lcd_sleep_after_backlight_off
139 # endif
140 # ifdef HAVE_BACKLIGHT_BRIGHTNESS
141 ,&brightness_item
142 # endif
143 #endif /* HAVE_BACKLIGHT */
144 #ifdef HAVE_LCD_CONTRAST
145 ,&contrast
146 #endif
147 #ifdef HAVE_LCD_BITMAP
148 # ifdef HAVE_LCD_INVERT
149 ,&invert
150 # endif
151 # ifdef HAVE_LCD_FLIP
152 ,&flip_display
153 # endif
154 #endif /* HAVE_LCD_BITMAP */
156 /* LCD MENU */
157 /***********************************/
160 /********************************/
161 /* Remote LCD settings menu */
162 #ifdef HAVE_REMOTE_LCD
163 MENUITEM_SETTING(remote_backlight_timeout,
164 &global_settings.remote_backlight_timeout, NULL);
166 #if CONFIG_CHARGING
167 MENUITEM_SETTING(remote_backlight_timeout_plugged,
168 &global_settings.remote_backlight_timeout_plugged, NULL);
169 #endif
171 #ifdef HAS_REMOTE_BUTTON_HOLD
172 MENUITEM_SETTING(remote_backlight_on_button_hold,
173 &global_settings.remote_backlight_on_button_hold, NULL);
174 #endif
176 MENUITEM_SETTING(remote_caption_backlight,
177 &global_settings.remote_caption_backlight, NULL);
178 MENUITEM_SETTING(remote_bl_filter_first_keypress,
179 &global_settings.remote_bl_filter_first_keypress,
180 filterfirstkeypress_callback);
181 MENUITEM_SETTING(remote_contrast,
182 &global_settings.remote_contrast, NULL);
183 MENUITEM_SETTING(remote_invert,
184 &global_settings.remote_invert, NULL);
186 MENUITEM_SETTING(remote_flip_display,
187 &global_settings.remote_flip_display, flipdisplay_callback);
189 #ifdef HAVE_REMOTE_LCD_TICKING
190 int ticking_callback(int action,const struct menu_item_ex *this_item)
192 (void)this_item;
193 switch (action)
195 case ACTION_EXIT_MENUITEM:
196 lcd_remote_emireduce(global_settings.remote_reduce_ticking);
197 break;
199 return action;
201 MENUITEM_SETTING(remote_reduce_ticking,
202 &global_settings.remote_reduce_ticking, ticking_callback);
203 #endif
205 MAKE_MENU(lcd_remote_settings, ID2P(LANG_LCD_REMOTE_MENU),
206 NULL, Icon_Remote_Display_menu,
207 &remote_backlight_timeout,
208 #if CONFIG_CHARGING
209 &remote_backlight_timeout_plugged,
210 #endif
211 #ifdef HAS_REMOTE_BUTTON_HOLD
212 &remote_backlight_on_button_hold,
213 #endif
214 &remote_caption_backlight, &remote_bl_filter_first_keypress,
215 &remote_contrast, &remote_invert, &remote_flip_display
216 #ifdef HAVE_REMOTE_LCD_TICKING
217 ,&remote_reduce_ticking
218 #endif
221 #endif /* HAVE_REMOTE_LCD */
222 /* Remote LCD settings menu */
223 /********************************/
225 /***********************************/
226 /* SCROLL MENU */
227 MENUITEM_SETTING_W_TEXT(scroll_speed, &global_settings.scroll_speed,
228 ID2P(LANG_SCROLL), NULL);
229 MENUITEM_SETTING(scroll_delay, &global_settings.scroll_delay, NULL);
230 #ifdef HAVE_LCD_BITMAP
231 MENUITEM_SETTING_W_TEXT(scroll_step, &global_settings.scroll_step,
232 ID2P(LANG_SCROLL_STEP_EXAMPLE), NULL);
233 #endif
234 MENUITEM_SETTING(bidir_limit, &global_settings.bidir_limit, NULL);
235 #ifdef HAVE_REMOTE_LCD
236 MENUITEM_SETTING_W_TEXT(remote_scroll_speed, &global_settings.remote_scroll_speed,
237 ID2P(LANG_SCROLL), NULL);
238 MENUITEM_SETTING(remote_scroll_delay, &global_settings.remote_scroll_delay, NULL);
239 MENUITEM_SETTING_W_TEXT(remote_scroll_step, &global_settings.remote_scroll_step,
240 ID2P(LANG_SCROLL_STEP_EXAMPLE), NULL);
241 MENUITEM_SETTING(remote_bidir_limit, &global_settings.remote_bidir_limit, NULL);
243 MAKE_MENU(remote_scroll_sets, ID2P(LANG_REMOTE_SCROLL_SETS), 0, Icon_NOICON,
244 &remote_scroll_speed, &remote_scroll_delay,
245 &remote_scroll_step, &remote_bidir_limit);
246 #endif /* HAVE_REMOTE_LCD */
247 #ifdef HAVE_LCD_CHARCELLS
248 MENUITEM_SETTING(jump_scroll, &global_settings.jump_scroll, NULL);
249 MENUITEM_SETTING(jump_scroll_delay, &global_settings.jump_scroll_delay, NULL);
250 #endif
251 /* list acceleration */
252 #ifndef HAVE_SCROLLWHEEL
253 MENUITEM_SETTING(list_accel_start_delay,
254 &global_settings.list_accel_start_delay, NULL);
255 MENUITEM_SETTING(list_accel_wait, &global_settings.list_accel_wait, NULL);
256 #endif /* HAVE_SCROLLWHEEL */
257 #ifdef HAVE_LCD_BITMAP
258 static int screenscroll_callback(int action,const struct menu_item_ex *this_item)
260 (void)this_item;
261 switch (action)
263 case ACTION_EXIT_MENUITEM:
264 gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
265 break;
267 return action;
269 MENUITEM_SETTING(offset_out_of_view, &global_settings.offset_out_of_view,
270 screenscroll_callback);
271 MENUITEM_SETTING(screen_scroll_step, &global_settings.screen_scroll_step, NULL);
272 #endif
273 MENUITEM_SETTING(scroll_paginated, &global_settings.scroll_paginated, NULL);
275 MAKE_MENU(scroll_settings_menu, ID2P(LANG_SCROLL_MENU), 0, Icon_NOICON,
276 &scroll_speed, &scroll_delay,
277 #ifdef HAVE_LCD_BITMAP
278 &scroll_step,
279 #endif
280 &bidir_limit,
281 #ifdef HAVE_REMOTE_LCD
282 &remote_scroll_sets,
283 #endif
284 #ifdef HAVE_LCD_CHARCELLS
285 &jump_scroll, &jump_scroll_delay,
286 #endif
287 #ifdef HAVE_LCD_BITMAP
288 &offset_out_of_view, &screen_scroll_step,
289 #endif
290 &scroll_paginated,
291 #ifndef HAVE_SCROLLWHEEL
292 &list_accel_start_delay, &list_accel_wait
293 #endif
295 /* SCROLL MENU */
296 /***********************************/
298 /***********************************/
299 /* BARS MENU */
300 #ifdef HAVE_LCD_BITMAP
301 static int statusbar_callback(int action,const struct menu_item_ex *this_item)
303 (void)this_item;
304 switch (action)
306 case ACTION_EXIT_MENUITEM:
307 send_event(STATUSBAR_TOGGLE_EVENT, NULL);
308 /* this should be changed so only the viewports are reloaded */
309 settings_apply(false);
310 break;
312 return action;
314 MENUITEM_SETTING(scrollbar_item, &global_settings.scrollbar, NULL);
315 MENUITEM_SETTING(statusbar, &global_settings.statusbar, statusbar_callback);
316 #if CONFIG_KEYPAD == RECORDER_PAD
317 MENUITEM_SETTING(buttonbar, &global_settings.buttonbar, NULL);
318 #endif
319 MENUITEM_SETTING(volume_type, &global_settings.volume_type, NULL);
320 MENUITEM_SETTING(battery_display, &global_settings.battery_display, NULL);
321 MAKE_MENU(bars_menu, ID2P(LANG_BARS_MENU), 0, Icon_NOICON,
322 &scrollbar_item, &statusbar,
323 #if CONFIG_KEYPAD == RECORDER_PAD
324 &buttonbar,
325 #endif
326 &volume_type, &battery_display);
327 #endif /* HAVE_LCD_BITMAP */
328 /* BARS MENU */
329 /***********************************/
332 /***********************************/
333 /* PEAK METER MENU */
335 #ifdef HAVE_LCD_BITMAP
336 static int peakmeter_callback(int action,const struct menu_item_ex *this_item)
338 (void)this_item;
339 switch (action)
341 case ACTION_EXIT_MENUITEM:
342 peak_meter_init_times(global_settings.peak_meter_release,
343 global_settings.peak_meter_hold,
344 global_settings.peak_meter_clip_hold);
345 break;
347 return action;
349 MENUITEM_SETTING(peak_meter_hold,
350 &global_settings.peak_meter_hold, peakmeter_callback);
351 MENUITEM_SETTING(peak_meter_clip_hold,
352 &global_settings.peak_meter_clip_hold, peakmeter_callback);
353 #ifdef HAVE_RECORDING
354 MENUITEM_SETTING(peak_meter_clipcounter,
355 &global_settings.peak_meter_clipcounter, NULL);
356 #endif
357 MENUITEM_SETTING(peak_meter_release,
358 &global_settings.peak_meter_release, peakmeter_callback);
360 * Menu to select wether the scale of the meter
361 * displays dBfs of linear values.
363 static int peak_meter_scale(void) {
364 bool retval = false;
365 bool use_dbfs = global_settings.peak_meter_dbfs;
366 retval = set_bool_options(str(LANG_PM_SCALE),
367 &use_dbfs,
368 STR(LANG_PM_DBFS), STR(LANG_PM_LINEAR),
369 NULL);
371 /* has the user really changed the scale? */
372 if (use_dbfs != global_settings.peak_meter_dbfs) {
374 /* store the change */
375 global_settings.peak_meter_dbfs = use_dbfs;
376 peak_meter_set_use_dbfs(use_dbfs);
378 /* If the user changed the scale mode the meaning of
379 peak_meter_min (peak_meter_max) has changed. Thus we have
380 to convert the values stored in global_settings. */
381 if (use_dbfs) {
383 /* we only store -dBfs */
384 global_settings.peak_meter_min = -peak_meter_get_min() / 100;
385 global_settings.peak_meter_max = -peak_meter_get_max() / 100;
387 /* limit the returned value to the allowed range */
388 if(global_settings.peak_meter_min > 89)
389 global_settings.peak_meter_min = 89;
390 } else {
391 int max;
393 /* linear percent */
394 global_settings.peak_meter_min = peak_meter_get_min();
396 /* converting dBfs -> percent results in a precision loss.
397 I assume that the user doesn't bother that conversion
398 dBfs <-> percent isn't symmetrical for odd values but that
399 he wants 0 dBfs == 100%. Thus I 'correct' the percent value
400 resulting from dBfs -> percent manually here */
401 max = peak_meter_get_max();
402 global_settings.peak_meter_max = max < 99 ? max : 100;
404 settings_apply_pm_range();
406 return retval;
410 * Adjust the min value of the value range that
411 * the peak meter shall visualize.
413 static int peak_meter_min(void) {
414 bool retval = false;
415 if (global_settings.peak_meter_dbfs) {
417 /* for dBfs scale */
418 int range_max = -global_settings.peak_meter_max;
419 int min = -global_settings.peak_meter_min;
421 retval = set_int(str(LANG_PM_MIN), str(LANG_PM_DBFS), UNIT_DB,
422 &min, NULL, 1, -89, range_max, NULL);
424 global_settings.peak_meter_min = - min;
427 /* for linear scale */
428 else {
429 int min = global_settings.peak_meter_min;
431 retval = set_int(str(LANG_PM_MIN), "%", UNIT_PERCENT,
432 &min, NULL,
433 1, 0, global_settings.peak_meter_max - 1, NULL);
435 global_settings.peak_meter_min = (unsigned char)min;
438 settings_apply_pm_range();
439 return retval;
444 * Adjust the max value of the value range that
445 * the peak meter shall visualize.
447 static int peak_meter_max(void) {
448 bool retval = false;
449 if (global_settings.peak_meter_dbfs) {
451 /* for dBfs scale */
452 int range_min = -global_settings.peak_meter_min;
453 int max = -global_settings.peak_meter_max;;
455 retval = set_int(str(LANG_PM_MAX), str(LANG_PM_DBFS), UNIT_DB,
456 &max, NULL, 1, range_min, 0, NULL);
458 global_settings.peak_meter_max = - max;
462 /* for linear scale */
463 else {
464 int max = global_settings.peak_meter_max;
466 retval = set_int(str(LANG_PM_MAX), "%", UNIT_PERCENT,
467 &max, NULL,
468 1, global_settings.peak_meter_min + 1, 100, NULL);
470 global_settings.peak_meter_max = (unsigned char)max;
473 settings_apply_pm_range();
474 return retval;
476 MENUITEM_FUNCTION(peak_meter_scale_item, 0, ID2P(LANG_PM_SCALE),
477 peak_meter_scale, NULL, NULL, Icon_NOICON);
478 MENUITEM_FUNCTION(peak_meter_min_item, 0, ID2P(LANG_PM_MIN),
479 peak_meter_min, NULL, NULL, Icon_NOICON);
480 MENUITEM_FUNCTION(peak_meter_max_item, 0, ID2P(LANG_PM_MAX),
481 peak_meter_max, NULL, NULL, Icon_NOICON);
482 MAKE_MENU(peak_meter_menu, ID2P(LANG_PM_MENU), NULL, Icon_NOICON,
483 &peak_meter_release, &peak_meter_hold,
484 &peak_meter_clip_hold,
485 #ifdef HAVE_RECORDING
486 &peak_meter_clipcounter,
487 #endif
488 &peak_meter_scale_item, &peak_meter_min_item, &peak_meter_max_item);
489 #endif /* HAVE_LCD_BITMAP */
490 /* PEAK METER MENU */
491 /***********************************/
495 MENUITEM_SETTING(codepage_setting, &global_settings.default_codepage, NULL);
498 MAKE_MENU(display_menu, ID2P(LANG_DISPLAY),
499 NULL, Icon_Display_menu,
500 &lcd_settings,
501 #ifdef HAVE_REMOTE_LCD
502 &lcd_remote_settings,
503 #endif
504 &scroll_settings_menu,
505 #ifdef HAVE_LCD_BITMAP
506 &bars_menu, &peak_meter_menu,
507 #endif
508 &codepage_setting,