1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Kevin Ferrare
11 * Copyright (C) 2007 by Jonathan Gordon
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
22 #include "option_select.h"
27 #include "settings_list.h"
31 #include "statusbar.h"
35 static const char *unit_strings
[] =
37 [UNIT_INT
] = "", [UNIT_MS
] = "ms",
38 [UNIT_SEC
] = "s", [UNIT_MIN
] = "min",
39 [UNIT_HOUR
]= "hr", [UNIT_KHZ
] = "KHz",
40 [UNIT_DB
] = "dB", [UNIT_PERCENT
] = "%",
41 [UNIT_MAH
] = "mAh", [UNIT_PIXEL
] = "px",
42 [UNIT_PER_SEC
] = "per sec",
44 [UNIT_MB
] = "MB", [UNIT_KBIT
] = "kb/s",
47 char *option_get_valuestring(struct settings_list
*setting
,
48 char *buffer
, int buf_len
,
51 if ((setting
->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
53 bool val
= (bool)temp_var
;
54 snprintf(buffer
, buf_len
, "%s",
55 str(val
? setting
->bool_setting
->lang_yes
:
56 setting
->bool_setting
->lang_no
));
58 #if 0 /* probably dont need this one */
59 else if ((setting
->flags
& F_FILENAME
) == F_FILENAME
)
61 struct filename_setting
*info
= setting
->filename_setting
;
62 snprintf(buffer
, buf_len
, "%s%s%s", info
->prefix
,
63 (char*)temp_var
, info
->suffix
);
66 else if ((setting
->flags
& F_INT_SETTING
) == F_INT_SETTING
)
68 struct int_setting
*info
= setting
->int_setting
;
70 info
->formatter(buffer
, buf_len
, (int)temp_var
,
71 unit_strings
[info
->unit
]);
73 snprintf(buffer
, buf_len
, "%d %s", (int)temp_var
,
74 unit_strings
[info
->unit
]?
75 unit_strings
[info
->unit
]:"");
77 else if ((setting
->flags
& F_T_SOUND
) == F_T_SOUND
)
79 char sign
= ' ', *unit
;
80 unit
= (char*)sound_unit(setting
->sound_setting
->setting
);
81 if (sound_numdecimals(setting
->sound_setting
->setting
))
84 int val
= sound_val2phys(setting
->sound_setting
->setting
,
91 integer
= val
/ 10; dec
= val
% 10;
92 snprintf(buffer
, buf_len
, "%c%d.%d %s", sign
, integer
, dec
, unit
);
95 snprintf(buffer
, buf_len
, "%d %s", (int)temp_var
, unit
);
97 else if ((setting
->flags
& F_CHOICE_SETTING
) == F_CHOICE_SETTING
)
99 if (setting
->flags
& F_CHOICETALKS
)
102 struct choice_setting
*info
= setting
->choice_setting
;
103 if (info
->talks
[(int)temp_var
] < LANG_LAST_INDEX_IN_ARRAY
)
105 snprintf(buffer
, buf_len
, "%s", str(info
->talks
[(int)temp_var
]));
109 find_setting(setting
->setting
, &setting_id
);
110 cfg_int_to_string(setting_id
, (int)temp_var
, buffer
, buf_len
);
115 int value
= (int)temp_var
;
116 char *val
= P2STR(setting
->choice_setting
->desc
[value
]);
117 snprintf(buffer
, buf_len
, "%s", val
);
123 void option_talk(struct settings_list
*setting
, int temp_var
)
125 if (!talk_menus_enabled())
127 if ((setting
->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
129 bool val
= temp_var
==1?true:false;
130 talk_id(val
? setting
->bool_setting
->lang_yes
:
131 setting
->bool_setting
->lang_no
, false);
133 #if 0 /* probably dont need this one */
134 else if ((setting
->flags
& F_FILENAME
) == F_FILENAME
)
138 else if ((setting
->flags
& F_INT_SETTING
) == F_INT_SETTING
)
140 struct int_setting
*info
= setting
->int_setting
;
141 if (info
->get_talk_id
)
142 talk_id(info
->get_talk_id((int)temp_var
), false);
144 talk_value((int)temp_var
, info
->unit
, false);
146 else if ((setting
->flags
& F_T_SOUND
) == F_T_SOUND
)
148 int talkunit
= UNIT_DB
;
149 const char *unit
= sound_unit(setting
->sound_setting
->setting
);
150 /* crude reconstruction */
152 talkunit
= UNIT_PERCENT
;
153 else if (*unit
== 'H')
154 talkunit
= UNIT_HERTZ
;
155 talk_value((int)temp_var
, talkunit
, false);
157 else if ((setting
->flags
& F_CHOICE_SETTING
) == F_CHOICE_SETTING
)
159 int value
= (int)temp_var
;
160 if (setting
->flags
& F_CHOICETALKS
)
162 talk_id(setting
->choice_setting
->talks
[value
], false);
166 talk_id(P2ID(setting
->choice_setting
->desc
[value
]), false);
171 int option_select_next_val(struct settings_list
*setting
,
175 if ((setting
->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
177 val
= (bool)temp_var
? 0 : 1;
179 else if ((setting
->flags
& F_INT_SETTING
) == F_INT_SETTING
)
181 struct int_setting
*info
= setting
->int_setting
;
182 val
= (int)temp_var
+ info
->step
;
186 else if ((setting
->flags
& F_T_SOUND
) == F_T_SOUND
)
188 int setting_id
= setting
->sound_setting
->setting
;
189 int steps
= sound_steps(setting_id
);
190 int min
= sound_min(setting_id
);
191 int max
= sound_max(setting_id
);
192 val
= (int)temp_var
+ steps
;
196 else if ((setting
->flags
& F_CHOICE_SETTING
) == F_CHOICE_SETTING
)
198 struct choice_setting
*info
= setting
->choice_setting
;
200 if (val
> info
->count
)
206 int option_select_prev_val(struct settings_list
*setting
,
210 if ((setting
->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
212 val
= (bool)temp_var
? 0 : 1;
214 else if ((setting
->flags
& F_INT_SETTING
) == F_INT_SETTING
)
216 struct int_setting
*info
= setting
->int_setting
;
217 val
= (int)temp_var
- info
->step
;
221 else if ((setting
->flags
& F_T_SOUND
) == F_T_SOUND
)
223 int setting_id
= setting
->sound_setting
->setting
;
224 int steps
= sound_steps(setting_id
);
225 int min
= sound_min(setting_id
);
226 int max
= sound_max(setting_id
);
227 val
= (int)temp_var
-+ steps
;
231 else if ((setting
->flags
& F_CHOICE_SETTING
) == F_CHOICE_SETTING
)
233 struct choice_setting
*info
= setting
->choice_setting
;
236 val
= info
->count
- 1;
242 static int selection_to_val(struct settings_list
*setting
, int selection
)
244 int min
= 0, max
= 0, step
= 1;
245 if (((setting
->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
) ||
246 ((setting
->flags
& F_CHOICE_SETTING
) == F_CHOICE_SETTING
))
248 else if ((setting
->flags
& F_T_SOUND
) == F_T_SOUND
)
250 int setting_id
= setting
->sound_setting
->setting
;
251 step
= sound_steps(setting_id
);
252 max
= sound_max(setting_id
);
253 min
= sound_min(setting_id
);
255 else if ((setting
->flags
& F_INT_SETTING
) == F_INT_SETTING
)
257 struct int_setting
*info
= setting
->int_setting
;
262 if (setting
->flags
& F_FLIPLIST
)
265 a
= min
; min
= max
; max
= a
;
268 return max
- (selection
* step
);
270 static char * value_setting_get_name_cb(int selected_item
,
271 void * data
, char *buffer
)
273 selected_item
= selection_to_val(data
, selected_item
);
274 return option_get_valuestring(data
, buffer
, MAX_PATH
, selected_item
);
277 /* wrapper to convert from int param to bool param in option_screen */
278 static void (*boolfunction
)(bool);
279 static void bool_funcwrapper(int value
)
287 bool option_screen(struct settings_list
*setting
,
288 bool use_temp_var
, unsigned char* option_title
)
292 struct gui_synclist lists
;
293 int oldvalue
, nb_items
= 0, selected
= 0, temp_var
;
295 bool allow_wrap
= ((int*)setting
->setting
!= &global_settings
.volume
);
296 int var_type
= setting
->flags
&F_T_MASK
;
297 void (*function
)(int) = NULL
;
299 if (var_type
== F_T_INT
|| var_type
== F_T_UINT
)
301 variable
= use_temp_var
? &temp_var
: (int*)setting
->setting
;
302 temp_var
= oldvalue
= *(int*)setting
->setting
;
304 else if (var_type
== F_T_BOOL
)
306 /* bools always use the temp variable...
307 if use_temp_var is false it will be copied to setting->setting every change */
308 variable
= &temp_var
;
309 temp_var
= oldvalue
= *(bool*)setting
->setting
?1:0;
311 else return false; /* only int/bools can go here */
312 gui_synclist_init(&lists
, value_setting_get_name_cb
,
313 (void*)setting
, false, 1);
314 if (setting
->lang_id
== -1)
315 title
= (char*)setting
->cfg_vals
;
317 title
= P2STR(option_title
);
319 gui_synclist_set_title(&lists
, title
, Icon_Questionmark
);
320 gui_synclist_set_icon_callback(&lists
, NULL
);
322 /* set the number of items and current selection */
323 if (var_type
== F_T_INT
|| var_type
== F_T_UINT
)
325 if (setting
->flags
&F_CHOICE_SETTING
)
327 nb_items
= setting
->choice_setting
->count
;
329 function
= setting
->choice_setting
->option_callback
;
331 else if (setting
->flags
&F_T_SOUND
)
333 int setting_id
= setting
->sound_setting
->setting
;
334 int steps
= sound_steps(setting_id
);
335 int min
= sound_min(setting_id
);
336 int max
= sound_max(setting_id
);
337 nb_items
= (max
-min
)/steps
+ 1;
338 selected
= (max
-oldvalue
)/steps
;
339 function
= sound_get_fn(setting_id
);
343 struct int_setting
*info
= setting
->int_setting
;
345 if (setting
->flags
&F_FLIPLIST
)
357 nb_items
= (max
-min
)/step
+ 1;
358 selected
= (max
- oldvalue
)/step
;
359 function
= info
->option_callback
;
362 else if (var_type
== F_T_BOOL
)
366 boolfunction
= setting
->bool_setting
->option_callback
;
368 function
= bool_funcwrapper
;
371 gui_synclist_set_nb_items(&lists
, nb_items
);
372 gui_synclist_select_item(&lists
, selected
);
374 gui_synclist_limit_scroll(&lists
, true);
375 gui_synclist_draw(&lists
);
377 option_talk(setting
, *variable
);
380 action
= get_action(CONTEXT_LIST
, TIMEOUT_BLOCK
);
381 if (action
== ACTION_NONE
)
383 if (gui_synclist_do_button(&lists
,action
,
384 allow_wrap
? LIST_WRAP_UNLESS_HELD
: LIST_WRAP_OFF
))
386 selected
= gui_synclist_get_sel_pos(&lists
);
387 *variable
= selection_to_val(setting
, selected
);
388 if (var_type
== F_T_BOOL
)
391 *(bool*)setting
->setting
= selected
==1?true:false;
394 option_talk(setting
, *variable
);
396 else if (action
== ACTION_STD_CANCEL
)
398 bool show_cancel
= false;
401 else if (var_type
== F_T_INT
|| var_type
== F_T_UINT
)
403 if (*variable
!= oldvalue
)
406 *variable
= oldvalue
;
411 if (*variable
!= oldvalue
)
415 *(bool*)setting
->setting
= oldvalue
==1?true:false;
416 *variable
= oldvalue
;
420 gui_syncsplash(HZ
/2, str(LANG_CANCEL
));
423 else if (action
== ACTION_STD_OK
)
427 else if(default_event_handler(action
) == SYS_USB_CONNECTED
)
429 gui_syncstatusbar_draw(&statusbars
, false);
435 if (oldvalue
!= *variable
)
439 if (var_type
== F_T_INT
|| var_type
== F_T_UINT
)
440 *(int*)setting
->setting
= *variable
;
442 *(bool*)setting
->setting
= *variable
?true:false;
450 /******************************************************
451 Compatability functions
452 *******************************************************/
453 #define MAX_OPTIONS 32
454 bool set_option(const char* string
, void* variable
, enum optiontype type
,
455 const struct opt_items
* options
,
456 int numoptions
, void (*function
)(int))
459 char *strings
[MAX_OPTIONS
];
460 struct choice_setting data
;
461 struct settings_list item
;
462 for (temp
=0; temp
<MAX_OPTIONS
&& temp
<numoptions
; temp
++)
463 strings
[temp
] = (char*)options
[temp
].string
;
466 temp
= *(bool*)variable
? 1: 0;
467 item
.setting
= &temp
;
470 item
.setting
= variable
;
471 item
.flags
= F_CHOICE_SETTING
|F_T_INT
;
473 item
.cfg_vals
= (char*)string
;
474 data
.count
= numoptions
<MAX_OPTIONS
? numoptions
: MAX_OPTIONS
;
475 data
.desc
= (void*)strings
; /* shutup gcc... */
476 data
.option_callback
= function
;
477 item
.choice_setting
= &data
;
478 option_screen(&item
, false, NULL
);
481 *(bool*)variable
= (temp
== 1? true: false);
486 bool set_int_ex(const unsigned char* string
,
490 void (*function
)(int),
494 void (*formatter
)(char*, int, int, const char*),
495 long (*get_talk_id
)(int))
498 struct settings_list item
;
499 struct int_setting data
= {
500 function
, voice_unit
, min
, max
, step
,
501 formatter
, get_talk_id
503 item
.int_setting
= &data
;
504 item
.flags
= F_INT_SETTING
|F_T_INT
;
506 item
.cfg_vals
= (char*)string
;
507 item
.setting
= variable
;
508 return option_screen(&item
, false, NULL
);
512 void option_select_init_items(struct option_select
* opt
,
515 const struct opt_items
* items
,
520 opt
->max_value
=nb_items
;
521 opt
->option
=selected
;
525 void option_select_next(struct option_select
* opt
)
527 if(opt
->option
+ 1 >= opt
->max_value
)
529 if(opt
->option
==opt
->max_value
-1)
530 opt
->option
=opt
->min_value
;
532 opt
->option
=opt
->max_value
-1;
538 void option_select_prev(struct option_select
* opt
)
540 if(opt
->option
- 1 < opt
->min_value
)
542 /* the dissimilarity to option_select_next() arises from the
543 * sleep timer problem (bug #5000 and #5001):
544 * there we have min=0, step = 5 but the value itself might
545 * not be a multiple of 5 -- as time elapsed;
546 * We need to be able to set timer to 0 (= Off) nevertheless. */
547 if(opt
->option
!=opt
->min_value
)
548 opt
->option
=opt
->min_value
;
550 opt
->option
=opt
->max_value
-1;
556 const char * option_select_get_text(struct option_select
* opt
)
558 return(P2STR(opt
->items
[opt
->option
].string
));