Combine the settings for scrollbar on/off and its position into one with three possib...
[kugel-rb.git] / apps / menus / display_menu.c
blob24e36e5fca88b994310fbe4cf2786a55cf4155e2
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 "appevents.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 "lcd.h"
38 #include "lcd-remote.h"
39 #ifdef HAVE_TOUCHSCREEN
40 #include "screens.h"
41 #endif
42 #include "viewport.h"
44 #ifdef HAVE_BACKLIGHT
45 static int filterfirstkeypress_callback(int action,const struct menu_item_ex *this_item)
47 (void)this_item;
48 switch (action)
50 case ACTION_EXIT_MENUITEM:
51 set_backlight_filter_keypress(global_settings.bl_filter_first_keypress);
52 #ifdef HAVE_REMOTE_LCD
53 set_remote_backlight_filter_keypress(
54 global_settings.remote_bl_filter_first_keypress);
55 #endif
57 break;
59 return action;
61 #endif
62 #ifdef HAVE_LCD_FLIP
63 static int flipdisplay_callback(int action,const struct menu_item_ex *this_item)
65 (void)this_item;
66 switch (action)
68 case ACTION_EXIT_MENUITEM:
69 button_set_flip(global_settings.flip_display);
70 lcd_set_flip(global_settings.flip_display);
71 lcd_update();
72 #ifdef HAVE_REMOTE_LCD
73 lcd_remote_set_flip(global_settings.remote_flip_display);
74 lcd_remote_update();
75 #endif
76 break;
78 return action;
80 #endif
82 /***********************************/
83 /* LCD MENU */
84 #ifdef HAVE_BACKLIGHT
85 MENUITEM_SETTING(backlight_timeout, &global_settings.backlight_timeout, NULL);
86 #if CONFIG_CHARGING
87 MENUITEM_SETTING(backlight_timeout_plugged,
88 &global_settings.backlight_timeout_plugged, NULL);
89 #endif
90 #ifdef HAS_BUTTON_HOLD
91 MENUITEM_SETTING(backlight_on_button_hold,
92 &global_settings.backlight_on_button_hold, NULL);
93 #endif
94 MENUITEM_SETTING(caption_backlight, &global_settings.caption_backlight, NULL);
95 #if defined(HAVE_BACKLIGHT_FADING_INT_SETTING) \
96 || defined(HAVE_BACKLIGHT_FADING_BOOL_SETTING)
97 MENUITEM_SETTING(backlight_fade_in, &global_settings.backlight_fade_in, NULL);
98 MENUITEM_SETTING(backlight_fade_out, &global_settings.backlight_fade_out, NULL);
99 #endif
100 MENUITEM_SETTING(bl_filter_first_keypress,
101 &global_settings.bl_filter_first_keypress,
102 filterfirstkeypress_callback);
103 #ifdef HAVE_LCD_SLEEP_SETTING
104 MENUITEM_SETTING(lcd_sleep_after_backlight_off,
105 &global_settings.lcd_sleep_after_backlight_off, NULL);
106 #endif
107 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
108 MENUITEM_SETTING(brightness_item, &global_settings.brightness, NULL);
109 #endif
110 #endif /* HAVE_BACKLIGHT */
111 #ifdef HAVE_LCD_CONTRAST
112 MENUITEM_SETTING(contrast, &global_settings.contrast, NULL);
113 #endif
114 #ifdef HAVE_LCD_BITMAP
115 #ifdef HAVE_LCD_INVERT
116 MENUITEM_SETTING(invert, &global_settings.invert, NULL);
117 #endif
118 #ifdef HAVE_LCD_FLIP
119 MENUITEM_SETTING(flip_display, &global_settings.flip_display, flipdisplay_callback);
120 #endif
121 #endif /* HAVE_LCD_BITMAP */
123 /* now the actual menu */
124 MAKE_MENU(lcd_settings,ID2P(LANG_LCD_MENU),
125 NULL, Icon_Display_menu
126 #ifdef HAVE_BACKLIGHT
127 ,&backlight_timeout
128 # if CONFIG_CHARGING
129 ,&backlight_timeout_plugged
130 # endif
131 # ifdef HAS_BUTTON_HOLD
132 ,&backlight_on_button_hold
133 # endif
134 ,&caption_backlight
135 #if defined(HAVE_BACKLIGHT_FADING_INT_SETTING) \
136 || defined(HAVE_BACKLIGHT_FADING_BOOL_SETTING)
137 ,&backlight_fade_in, &backlight_fade_out
138 #endif
139 ,&bl_filter_first_keypress
140 # ifdef HAVE_LCD_SLEEP_SETTING
141 ,&lcd_sleep_after_backlight_off
142 # endif
143 # ifdef HAVE_BACKLIGHT_BRIGHTNESS
144 ,&brightness_item
145 # endif
146 #endif /* HAVE_BACKLIGHT */
147 #ifdef HAVE_LCD_CONTRAST
148 ,&contrast
149 #endif
150 #ifdef HAVE_LCD_BITMAP
151 # ifdef HAVE_LCD_INVERT
152 ,&invert
153 # endif
154 # ifdef HAVE_LCD_FLIP
155 ,&flip_display
156 # endif
157 #endif /* HAVE_LCD_BITMAP */
159 /* LCD MENU */
160 /***********************************/
163 /********************************/
164 /* Remote LCD settings menu */
165 #ifdef HAVE_REMOTE_LCD
166 MENUITEM_SETTING(remote_backlight_timeout,
167 &global_settings.remote_backlight_timeout, NULL);
169 #if CONFIG_CHARGING
170 MENUITEM_SETTING(remote_backlight_timeout_plugged,
171 &global_settings.remote_backlight_timeout_plugged, NULL);
172 #endif
174 #ifdef HAS_REMOTE_BUTTON_HOLD
175 MENUITEM_SETTING(remote_backlight_on_button_hold,
176 &global_settings.remote_backlight_on_button_hold, NULL);
177 #endif
179 MENUITEM_SETTING(remote_caption_backlight,
180 &global_settings.remote_caption_backlight, NULL);
181 MENUITEM_SETTING(remote_bl_filter_first_keypress,
182 &global_settings.remote_bl_filter_first_keypress,
183 filterfirstkeypress_callback);
184 MENUITEM_SETTING(remote_contrast,
185 &global_settings.remote_contrast, NULL);
186 MENUITEM_SETTING(remote_invert,
187 &global_settings.remote_invert, NULL);
189 #ifdef HAVE_LCD_FLIP
190 MENUITEM_SETTING(remote_flip_display,
191 &global_settings.remote_flip_display, flipdisplay_callback);
192 #endif
194 #ifdef HAVE_REMOTE_LCD_TICKING
195 static int ticking_callback(int action,const struct menu_item_ex *this_item)
197 (void)this_item;
198 switch (action)
200 case ACTION_EXIT_MENUITEM:
201 lcd_remote_emireduce(global_settings.remote_reduce_ticking);
202 break;
204 return action;
206 MENUITEM_SETTING(remote_reduce_ticking,
207 &global_settings.remote_reduce_ticking, ticking_callback);
208 #endif
210 MAKE_MENU(lcd_remote_settings, ID2P(LANG_LCD_REMOTE_MENU),
211 NULL, Icon_Remote_Display_menu,
212 &remote_backlight_timeout,
213 #if CONFIG_CHARGING
214 &remote_backlight_timeout_plugged,
215 #endif
216 #ifdef HAS_REMOTE_BUTTON_HOLD
217 &remote_backlight_on_button_hold,
218 #endif
219 &remote_caption_backlight, &remote_bl_filter_first_keypress,
220 &remote_contrast, &remote_invert
222 #ifdef HAVE_LCD_FLIP
223 ,&remote_flip_display
224 #endif
225 #ifdef HAVE_REMOTE_LCD_TICKING
226 ,&remote_reduce_ticking
227 #endif
230 #endif /* HAVE_REMOTE_LCD */
231 /* Remote LCD settings menu */
232 /********************************/
234 /***********************************/
235 /* SCROLL MENU */
236 MENUITEM_SETTING_W_TEXT(scroll_speed, &global_settings.scroll_speed,
237 ID2P(LANG_SCROLL), NULL);
238 MENUITEM_SETTING(scroll_delay, &global_settings.scroll_delay, NULL);
239 #ifdef HAVE_LCD_BITMAP
240 MENUITEM_SETTING_W_TEXT(scroll_step, &global_settings.scroll_step,
241 ID2P(LANG_SCROLL_STEP_EXAMPLE), NULL);
242 #endif
243 MENUITEM_SETTING(bidir_limit, &global_settings.bidir_limit, NULL);
244 #ifdef HAVE_REMOTE_LCD
245 MENUITEM_SETTING_W_TEXT(remote_scroll_speed, &global_settings.remote_scroll_speed,
246 ID2P(LANG_SCROLL), NULL);
247 MENUITEM_SETTING(remote_scroll_delay, &global_settings.remote_scroll_delay, NULL);
248 MENUITEM_SETTING_W_TEXT(remote_scroll_step, &global_settings.remote_scroll_step,
249 ID2P(LANG_SCROLL_STEP_EXAMPLE), NULL);
250 MENUITEM_SETTING(remote_bidir_limit, &global_settings.remote_bidir_limit, NULL);
252 MAKE_MENU(remote_scroll_sets, ID2P(LANG_REMOTE_SCROLL_SETS), 0, Icon_NOICON,
253 &remote_scroll_speed, &remote_scroll_delay,
254 &remote_scroll_step, &remote_bidir_limit);
255 #endif /* HAVE_REMOTE_LCD */
256 #ifdef HAVE_LCD_CHARCELLS
257 MENUITEM_SETTING(jump_scroll, &global_settings.jump_scroll, NULL);
258 MENUITEM_SETTING(jump_scroll_delay, &global_settings.jump_scroll_delay, NULL);
259 #endif
260 /* list acceleration */
261 #ifndef HAVE_WHEEL_ACCELERATION
262 MENUITEM_SETTING(list_accel_start_delay,
263 &global_settings.list_accel_start_delay, NULL);
264 MENUITEM_SETTING(list_accel_wait, &global_settings.list_accel_wait, NULL);
265 #endif /* HAVE_WHEEL_ACCELERATION */
266 #ifdef HAVE_LCD_BITMAP
267 static int screenscroll_callback(int action,const struct menu_item_ex *this_item)
269 (void)this_item;
270 switch (action)
272 case ACTION_EXIT_MENUITEM:
273 gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
274 break;
276 return action;
278 MENUITEM_SETTING(offset_out_of_view, &global_settings.offset_out_of_view,
279 screenscroll_callback);
280 MENUITEM_SETTING(screen_scroll_step, &global_settings.screen_scroll_step, NULL);
281 #endif
282 MENUITEM_SETTING(scroll_paginated, &global_settings.scroll_paginated, NULL);
284 MAKE_MENU(scroll_settings_menu, ID2P(LANG_SCROLL_MENU), 0, Icon_NOICON,
285 &scroll_speed, &scroll_delay,
286 #ifdef HAVE_LCD_BITMAP
287 &scroll_step,
288 #endif
289 &bidir_limit,
290 #ifdef HAVE_REMOTE_LCD
291 &remote_scroll_sets,
292 #endif
293 #ifdef HAVE_LCD_CHARCELLS
294 &jump_scroll, &jump_scroll_delay,
295 #endif
296 #ifdef HAVE_LCD_BITMAP
297 &offset_out_of_view, &screen_scroll_step,
298 #endif
299 &scroll_paginated,
300 #ifndef HAVE_WHEEL_ACCELERATION
301 &list_accel_start_delay, &list_accel_wait
302 #endif
304 /* SCROLL MENU */
305 /***********************************/
307 /***********************************/
308 /* BARS MENU */
309 #ifdef HAVE_LCD_BITMAP
310 static int statusbar_callback(int action,const struct menu_item_ex *this_item)
312 (void)this_item;
313 switch (action)
315 case ACTION_EXIT_MENUITEM:
316 send_event(GUI_EVENT_STATUSBAR_TOGGLE, NULL);
317 send_event(GUI_EVENT_ACTIONUPDATE, (void*)true);
318 break;
320 return action;
322 MENUITEM_SETTING(scrollbar_item, &global_settings.scrollbar, NULL);
323 MENUITEM_SETTING(scrollbar_width, &global_settings.scrollbar_width, NULL);
324 MENUITEM_SETTING(statusbar, &global_settings.statusbar, statusbar_callback);
325 #ifdef HAVE_REMOTE_LCD
326 MENUITEM_SETTING(remote_statusbar, &global_settings.remote_statusbar, statusbar_callback);
327 #endif
328 #if CONFIG_KEYPAD == RECORDER_PAD
329 MENUITEM_SETTING(buttonbar, &global_settings.buttonbar, NULL);
330 #endif
331 MENUITEM_SETTING(volume_type, &global_settings.volume_type, NULL);
332 MENUITEM_SETTING(battery_display, &global_settings.battery_display, NULL);
333 MAKE_MENU(bars_menu, ID2P(LANG_BARS_MENU), 0, Icon_NOICON,
334 &scrollbar_item, &scrollbar_width, &statusbar,
335 #ifdef HAVE_REMOTE_LCD
336 &remote_statusbar,
337 #endif
338 #if CONFIG_KEYPAD == RECORDER_PAD
339 &buttonbar,
340 #endif
341 &volume_type, &battery_display);
342 #endif /* HAVE_LCD_BITMAP */
343 /* BARS MENU */
344 /***********************************/
347 /***********************************/
348 /* PEAK METER MENU */
350 #ifdef HAVE_LCD_BITMAP
351 static int peakmeter_callback(int action,const struct menu_item_ex *this_item)
353 (void)this_item;
354 switch (action)
356 case ACTION_EXIT_MENUITEM:
357 peak_meter_init_times(global_settings.peak_meter_release,
358 global_settings.peak_meter_hold,
359 global_settings.peak_meter_clip_hold);
360 break;
362 return action;
364 MENUITEM_SETTING(peak_meter_hold,
365 &global_settings.peak_meter_hold, peakmeter_callback);
366 MENUITEM_SETTING(peak_meter_clip_hold,
367 &global_settings.peak_meter_clip_hold, peakmeter_callback);
368 #ifdef HAVE_RECORDING
369 MENUITEM_SETTING(peak_meter_clipcounter,
370 &global_settings.peak_meter_clipcounter, NULL);
371 #endif
372 MENUITEM_SETTING(peak_meter_release,
373 &global_settings.peak_meter_release, peakmeter_callback);
375 * Menu to select wether the scale of the meter
376 * displays dBfs of linear values.
378 static int peak_meter_scale(void) {
379 bool retval = false;
380 bool use_dbfs = global_settings.peak_meter_dbfs;
381 retval = set_bool_options(str(LANG_PM_SCALE),
382 &use_dbfs,
383 STR(LANG_PM_DBFS), STR(LANG_PM_LINEAR),
384 NULL);
386 /* has the user really changed the scale? */
387 if (use_dbfs != global_settings.peak_meter_dbfs) {
389 /* store the change */
390 global_settings.peak_meter_dbfs = use_dbfs;
391 peak_meter_set_use_dbfs(use_dbfs);
393 /* If the user changed the scale mode the meaning of
394 peak_meter_min (peak_meter_max) has changed. Thus we have
395 to convert the values stored in global_settings. */
396 if (use_dbfs) {
398 /* we only store -dBfs */
399 global_settings.peak_meter_min = -peak_meter_get_min() / 100;
400 global_settings.peak_meter_max = -peak_meter_get_max() / 100;
402 /* limit the returned value to the allowed range */
403 if(global_settings.peak_meter_min > 89)
404 global_settings.peak_meter_min = 89;
405 } else {
406 int max;
408 /* linear percent */
409 global_settings.peak_meter_min = peak_meter_get_min();
411 /* converting dBfs -> percent results in a precision loss.
412 I assume that the user doesn't bother that conversion
413 dBfs <-> percent isn't symmetrical for odd values but that
414 he wants 0 dBfs == 100%. Thus I 'correct' the percent value
415 resulting from dBfs -> percent manually here */
416 max = peak_meter_get_max();
417 global_settings.peak_meter_max = max < 99 ? max : 100;
419 settings_apply_pm_range();
421 return retval;
425 * Adjust the min value of the value range that
426 * the peak meter shall visualize.
428 static int peak_meter_min(void) {
429 bool retval = false;
430 if (global_settings.peak_meter_dbfs) {
432 /* for dBfs scale */
433 int range_max = -global_settings.peak_meter_max;
434 int min = -global_settings.peak_meter_min;
436 retval = set_int(str(LANG_PM_MIN), str(LANG_PM_DBFS), UNIT_DB,
437 &min, NULL, 1, -89, range_max, NULL);
439 global_settings.peak_meter_min = - min;
442 /* for linear scale */
443 else {
444 int min = global_settings.peak_meter_min;
446 retval = set_int(str(LANG_PM_MIN), "%", UNIT_PERCENT,
447 &min, NULL,
448 1, 0, global_settings.peak_meter_max - 1, NULL);
450 global_settings.peak_meter_min = (unsigned char)min;
453 settings_apply_pm_range();
454 return retval;
459 * Adjust the max value of the value range that
460 * the peak meter shall visualize.
462 static int peak_meter_max(void) {
463 bool retval = false;
464 if (global_settings.peak_meter_dbfs) {
466 /* for dBfs scale */
467 int range_min = -global_settings.peak_meter_min;
468 int max = -global_settings.peak_meter_max;
470 retval = set_int(str(LANG_PM_MAX), str(LANG_PM_DBFS), UNIT_DB,
471 &max, NULL, 1, range_min, 0, NULL);
473 global_settings.peak_meter_max = - max;
477 /* for linear scale */
478 else {
479 int max = global_settings.peak_meter_max;
481 retval = set_int(str(LANG_PM_MAX), "%", UNIT_PERCENT,
482 &max, NULL,
483 1, global_settings.peak_meter_min + 1, 100, NULL);
485 global_settings.peak_meter_max = (unsigned char)max;
488 settings_apply_pm_range();
489 return retval;
491 MENUITEM_FUNCTION(peak_meter_scale_item, 0, ID2P(LANG_PM_SCALE),
492 peak_meter_scale, NULL, NULL, Icon_NOICON);
493 MENUITEM_FUNCTION(peak_meter_min_item, 0, ID2P(LANG_PM_MIN),
494 peak_meter_min, NULL, NULL, Icon_NOICON);
495 MENUITEM_FUNCTION(peak_meter_max_item, 0, ID2P(LANG_PM_MAX),
496 peak_meter_max, NULL, NULL, Icon_NOICON);
497 MAKE_MENU(peak_meter_menu, ID2P(LANG_PM_MENU), NULL, Icon_NOICON,
498 &peak_meter_release, &peak_meter_hold,
499 &peak_meter_clip_hold,
500 #ifdef HAVE_RECORDING
501 &peak_meter_clipcounter,
502 #endif
503 &peak_meter_scale_item, &peak_meter_min_item, &peak_meter_max_item);
504 #endif /* HAVE_LCD_BITMAP */
505 /* PEAK METER MENU */
506 /***********************************/
509 #ifdef HAVE_TOUCHSCREEN
510 static int touch_mode_callback(int action,const struct menu_item_ex *this_item)
512 (void)this_item;
513 switch (action)
515 case ACTION_EXIT_MENUITEM: /* on exit */
516 touchscreen_set_mode(global_settings.touch_mode);
517 break;
519 return action;
521 MENUITEM_SETTING(touch_mode, &global_settings.touch_mode, touch_mode_callback);
523 MENUITEM_FUNCTION(touchscreen_menu_calibrate, 0, ID2P(LANG_TOUCHSCREEN_CALIBRATE), calibrate,
524 NULL, NULL, Icon_NOICON);
525 MENUITEM_FUNCTION(touchscreen_menu_reset_calibration, 0, ID2P(LANG_TOUCHSCREEN_RESET_CALIBRATION), reset_mapping,
526 NULL, NULL, Icon_NOICON);
528 MAKE_MENU(touchscreen_menu, ID2P(LANG_TOUCHSCREEN_SETTINGS), NULL, Icon_NOICON, &touch_mode,
529 &touchscreen_menu_calibrate, &touchscreen_menu_reset_calibration);
530 #endif
533 MENUITEM_SETTING(codepage_setting, &global_settings.default_codepage, NULL);
536 MAKE_MENU(display_menu, ID2P(LANG_DISPLAY),
537 NULL, Icon_Display_menu,
538 &lcd_settings,
539 #ifdef HAVE_REMOTE_LCD
540 &lcd_remote_settings,
541 #endif
542 &scroll_settings_menu,
543 #ifdef HAVE_LCD_BITMAP
544 &bars_menu, &peak_meter_menu,
545 #endif
546 &codepage_setting,
547 #ifdef HAVE_TOUCHSCREEN
548 &touchscreen_menu,
549 #endif