summaryrefslogtreecommitdiff
path: root/apps/gui/option_select.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/option_select.c')
-rw-r--r--apps/gui/option_select.c487
1 files changed, 486 insertions, 1 deletions
diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c
index 0098cf198f..7d74e202be 100644
--- a/apps/gui/option_select.c
+++ b/apps/gui/option_select.c
@@ -8,6 +8,7 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2005 by Kevin Ferrare 10 * Copyright (C) 2005 by Kevin Ferrare
11 * Copyright (C) 2007 by Jonathan Gordon
11 * 12 *
12 * All files in this archive are subject to the GNU General Public License. 13 * 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. 14 * See the file COPYING in the source tree root for full license agreement.
@@ -16,12 +17,496 @@
16 * KIND, either express or implied. 17 * KIND, either express or implied.
17 * 18 *
18 ****************************************************************************/ 19 ****************************************************************************/
19 20#include <stdlib.h>
21#include "config.h"
20#include "option_select.h" 22#include "option_select.h"
21#include "sprintf.h" 23#include "sprintf.h"
22#include "kernel.h" 24#include "kernel.h"
23#include "lang.h" 25#include "lang.h"
26#include "talk.h"
27#include "settings_list.h"
28#include "sound.h"
29#include "list.h"
30#include "action.h"
31#include "statusbar.h"
32#include "misc.h"
33#include "splash.h"
34
35static const char *unit_strings[] =
36{
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",
43 [UNIT_HERTZ] = "Hz",
44 [UNIT_MB] = "MB", [UNIT_KBIT] = "kb/s",
45};
46
47char *option_get_valuestring(struct settings_list *setting,
48 char *buffer, int buf_len,
49 intptr_t temp_var)
50{
51 if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
52 {
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));
57 }
58#if 0 /* probably dont need this one */
59 else if ((setting->flags & F_FILENAME) == F_FILENAME)
60 {
61 struct filename_setting *info = setting->filename_setting;
62 snprintf(buffer, buf_len, "%s%s%s", info->prefix,
63 (char*)temp_var, info->suffix);
64 }
65#endif
66 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
67 {
68 struct int_setting *info = setting->int_setting;
69 if (info->formatter)
70 info->formatter(buffer, buf_len, (int)temp_var,
71 unit_strings[info->unit]);
72 else
73 snprintf(buffer, buf_len, "%d %s", (int)temp_var,
74 unit_strings[info->unit]?
75 unit_strings[info->unit]:"");
76 }
77 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
78 {
79 char sign = ' ', *unit;
80 unit = (char*)sound_unit(setting->sound_setting->setting);
81 if (sound_numdecimals(setting->sound_setting->setting))
82 {
83 int integer, dec;
84 int val = sound_val2phys(setting->sound_setting->setting,
85 (int)temp_var);
86 if(val < 0)
87 {
88 sign = '-';
89 val = abs(val);
90 }
91 integer = val / 10; dec = val % 10;
92 snprintf(buffer, buf_len, "%c%d.%d %s", sign, integer, dec, unit);
93 }
94 else
95 snprintf(buffer, buf_len, "%d %s", (int)temp_var, unit);
96 }
97 else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)
98 {
99 if (setting->flags & F_CHOICETALKS)
100 {
101 int setting_id;
102 find_setting(setting->setting, &setting_id);
103 cfg_int_to_string(setting_id, (int)temp_var, buffer, buf_len);
104 }
105 else
106 {
107 int value= (int)temp_var;
108 char *val = P2STR(setting->choice_setting->desc[value]);
109 snprintf(buffer, buf_len, "%s", val);
110 }
111 }
112 return buffer;
113}
114
115void option_talk(struct settings_list *setting, int temp_var)
116{
117 if (!talk_menus_enabled())
118 return;
119 if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
120 {
121 bool val = temp_var==1?true:false;
122 talk_id(val? setting->bool_setting->lang_yes :
123 setting->bool_setting->lang_no, false);
124 }
125#if 0 /* probably dont need this one */
126 else if ((setting->flags & F_FILENAME) == F_FILENAME)
127 {
128 }
129#endif
130 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
131 {
132 struct int_setting *info = setting->int_setting;
133 if (info->get_talk_id)
134 talk_id(info->get_talk_id((int)temp_var), false);
135 else
136 talk_value((int)temp_var, info->unit, false);
137 }
138 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
139 {
140 int talkunit = UNIT_DB;
141 const char *unit = sound_unit(setting->sound_setting->setting);
142 /* crude reconstruction */
143 if (*unit == '%')
144 talkunit = UNIT_PERCENT;
145 else if (*unit == 'H')
146 talkunit = UNIT_HERTZ;
147 talk_value((int)temp_var, talkunit, false);
148 }
149 else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)
150 {
151 int value = (int)temp_var;
152 if (setting->flags & F_CHOICETALKS)
153 {
154 talk_id(setting->choice_setting->talks[value], false);
155 }
156 else
157 {
158 talk_id(P2ID(setting->choice_setting->desc[value]), false);
159 }
160 }
161}
162#if 0
163int option_select_next_val(struct settings_list *setting,
164 intptr_t temp_var)
165{
166 int val = 0;
167 if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
168 {
169 val = (bool)temp_var ? 0 : 1;
170 }
171 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
172 {
173 struct int_setting *info = setting->int_setting;
174 val = (int)temp_var + info->step;
175 if (val > info->max)
176 val = info->min;
177 }
178 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
179 {
180 int setting_id = setting->sound_setting->setting;
181 int steps = sound_steps(setting_id);
182 int min = sound_min(setting_id);
183 int max = sound_max(setting_id);
184 val = (int)temp_var + steps;
185 if (val > max)
186 val = min;
187 }
188 else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)
189 {
190 struct choice_setting *info = setting->choice_setting;
191 val = (int)temp_var;
192 if (val > info->count)
193 val = 0;
194 }
195 return val;
196}
197
198int option_select_prev_val(struct settings_list *setting,
199 intptr_t temp_var)
200{
201 int val = 0;
202 if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
203 {
204 val = (bool)temp_var ? 0 : 1;
205 }
206 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
207 {
208 struct int_setting *info = setting->int_setting;
209 val = (int)temp_var - info->step;
210 if (val < info->min)
211 val = info->max;
212 }
213 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
214 {
215 int setting_id = setting->sound_setting->setting;
216 int steps = sound_steps(setting_id);
217 int min = sound_min(setting_id);
218 int max = sound_max(setting_id);
219 val = (int)temp_var -+ steps;
220 if (val < min)
221 val = max;
222 }
223 else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)
224 {
225 struct choice_setting *info = setting->choice_setting;
226 val = (int)temp_var;
227 if (val < 0)
228 val = info->count - 1;
229 }
230 return val;
231}
232#endif
233
234static int selection_to_val(struct settings_list *setting, int selection)
235{
236 int min = 0, max = 0, step = 1;
237 if (((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) ||
238 ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING))
239 return selection;
240 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
241 {
242 int setting_id = setting->sound_setting->setting;
243 step = sound_steps(setting_id);
244 max = sound_max(setting_id);
245 min = sound_min(setting_id);
246 }
247 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
248 {
249 struct int_setting *info = setting->int_setting;
250 min = info->min;
251 max = info->max;
252 step = info->step;
253 }
254 if (setting->flags & F_FLIPLIST)
255 {
256 int a;
257 a = min; min = max; max = a;
258 step = -step;
259 }
260 return max- (selection * step);
261}
262static char * value_setting_get_name_cb(int selected_item,
263 void * data, char *buffer)
264{
265 selected_item = selection_to_val(data, selected_item);
266 return option_get_valuestring(data, buffer, MAX_PATH, selected_item);
267}
268
269/* wrapper to convert from int param to bool param in option_screen */
270static void (*boolfunction)(bool);
271static void bool_funcwrapper(int value)
272{
273 if (value)
274 boolfunction(true);
275 else
276 boolfunction(false);
277}
278
279bool option_screen(struct settings_list *setting, bool use_temp_var)
280{
281 int action;
282 bool done = false;
283 struct gui_synclist lists;
284 int oldvalue, nb_items = 0, selected = 0, temp_var;
285 int *variable;
286 bool allow_wrap = ((int*)setting->setting != &global_settings.volume);
287 int var_type = setting->flags&F_T_MASK;
288 void (*function)(int) = NULL;
289
290 if (var_type == F_T_INT || var_type == F_T_UINT)
291 {
292 variable = use_temp_var ? &temp_var: (int*)setting->setting;
293 temp_var = oldvalue = *(int*)setting->setting;
294 }
295 else if (var_type == F_T_BOOL)
296 {
297 /* bools always use the temp variable...
298 if use_temp_var is false it will be copied to setting->setting every change */
299 variable = &temp_var;
300 temp_var = oldvalue = *(bool*)setting->setting?1:0;
301 }
302 else return false; /* only int/bools can go here */
303 gui_synclist_init(&lists, value_setting_get_name_cb,
304 (void*)setting, false, 1);
305 if (setting->lang_id == -1)
306 gui_synclist_set_title(&lists,
307 (char*)setting->cfg_vals, Icon_Questionmark);
308 else
309 gui_synclist_set_title(&lists,
310 str(setting->lang_id), Icon_Questionmark);
311 gui_synclist_set_icon_callback(&lists, NULL);
312
313 /* set the number of items and current selection */
314 if (var_type == F_T_INT || var_type == F_T_UINT)
315 {
316 if (setting->flags&F_CHOICE_SETTING)
317 {
318 nb_items = setting->choice_setting->count;
319 selected = oldvalue;
320 function = setting->choice_setting->option_callback;
321 }
322 else if (setting->flags&F_T_SOUND)
323 {
324 int setting_id = setting->sound_setting->setting;
325 int steps = sound_steps(setting_id);
326 int min = sound_min(setting_id);
327 int max = sound_max(setting_id);
328 nb_items = (max-min)/steps + 1;
329 selected = (max-oldvalue)/steps;
330 function = sound_get_fn(setting_id);
331 }
332 else
333 {
334 struct int_setting *info = setting->int_setting;
335 int min, max, step;
336 if (setting->flags&F_FLIPLIST)
337 {
338 min = info->max;
339 max = info->min;
340 step = -info->step;
341 }
342 else
343 {
344 max = info->max;
345 min = info->min;
346 step = info->step;
347 }
348 nb_items = (max-min)/step + 1;
349 selected = (max - oldvalue)/step;
350 function = info->option_callback;
351 }
352 }
353 else if (var_type == F_T_BOOL)
354 {
355 selected = oldvalue;
356 nb_items = 2;
357 boolfunction = setting->bool_setting->option_callback;
358 if (boolfunction)
359 function = bool_funcwrapper;
360 }
361
362 gui_synclist_set_nb_items(&lists, nb_items);
363 gui_synclist_select_item(&lists, selected);
364
365 gui_synclist_limit_scroll(&lists, true);
366 gui_synclist_draw(&lists);
367 action_signalscreenchange();
368 /* talk the item */
369 option_talk(setting, *variable);
370 while (!done)
371 {
372 action = get_action(CONTEXT_LIST, TIMEOUT_BLOCK);
373 if (action == ACTION_NONE)
374 continue;
375 if (gui_synclist_do_button(&lists,action,
376 allow_wrap? LIST_WRAP_UNLESS_HELD: LIST_WRAP_OFF))
377 {
378 selected = gui_synclist_get_sel_pos(&lists);
379 *variable = selection_to_val(setting, selected);
380 if (var_type == F_T_BOOL)
381 {
382 if (!use_temp_var)
383 *(bool*)setting->setting = selected==1?true:false;
384 }
385 /* talk */
386 option_talk(setting, *variable);
387 }
388 else if (action == ACTION_STD_CANCEL)
389 {
390 bool show_cancel = false;
391 if (use_temp_var)
392 show_cancel = true;
393 else if (var_type == F_T_INT || var_type == F_T_UINT)
394 {
395 if (*variable != oldvalue)
396 {
397 show_cancel = true;
398 *variable = oldvalue;
399 }
400 }
401 else
402 {
403 if (*variable != oldvalue)
404 {
405 show_cancel = true;
406 if (!use_temp_var)
407 *(bool*)setting->setting = oldvalue==1?true:false;
408 *variable = oldvalue;
409 }
410 }
411 if (show_cancel)
412 gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL));
413 done = true;
414 }
415 else if (action == ACTION_STD_OK)
416 {
417 done = true;
418 }
419 else if(default_event_handler(action) == SYS_USB_CONNECTED)
420 return true;
421 gui_syncstatusbar_draw(&statusbars, false);
422 /* callback */
423 if ( function )
424 function(*variable);
425 }
426
427 if (use_temp_var)
428 {
429 if (var_type == F_T_INT || var_type == F_T_UINT)
430 {
431 if (oldvalue != *variable)
432 {
433 *(int*)setting->setting = *variable;
434 settings_save();
435 }
436 }
437 else if (oldvalue != *variable)
438 {
439 *(bool*)setting->setting = *variable?true:false;
440 settings_save();
441 }
442 }
443
444 action_signalscreenchange();
445 return false;
446}
447
448/******************************************************
449 Compatability functions
450*******************************************************/
451#define MAX_OPTIONS 32
452bool set_option(const char* string, void* variable, enum optiontype type,
453 const struct opt_items* options,
454 int numoptions, void (*function)(int))
455{
456 int temp;
457 char *strings[MAX_OPTIONS];
458 struct choice_setting data;
459 struct settings_list item;
460 for (temp=0; temp<MAX_OPTIONS && temp<numoptions; temp++)
461 strings[temp] = (char*)options[temp].string;
462 if (type == BOOL)
463 {
464 temp = *(bool*)variable? 1: 0;
465 item.setting = &temp;
466 }
467 else
468 item.setting = variable;
469 item.flags = F_CHOICE_SETTING|F_T_INT;
470 item.lang_id = -1;
471 item.cfg_vals = (char*)string;
472 data.count = numoptions<MAX_OPTIONS ? numoptions: MAX_OPTIONS;
473 data.desc = (void*)strings; /* shutup gcc... */
474 data.option_callback = function;
475 item.choice_setting = &data;
476 option_screen(&item, false);
477 if (type == BOOL)
478 {
479 *(bool*)variable = (temp == 1? true: false);
480 }
481 return false;
482}
483
484bool set_int_ex(const unsigned char* string,
485 const char* unit,
486 int voice_unit,
487 int* variable,
488 void (*function)(int),
489 int step,
490 int min,
491 int max,
492 void (*formatter)(char*, int, int, const char*),
493 long (*get_talk_id)(int))
494{
495 (void)unit;
496 struct settings_list item;
497 struct int_setting data = {
498 function, voice_unit, min, max, step,
499 formatter, get_talk_id
500 };
501 item.int_setting = &data;
502 item.flags = F_INT_SETTING|F_T_INT;
503 item.lang_id = -1;
504 item.cfg_vals = (char*)string;
505 item.setting = variable;
506 return option_screen(&item, false);
507}
24 508
509/* to be replaced */
25void option_select_init_items(struct option_select * opt, 510void option_select_init_items(struct option_select * opt,
26 const char * title, 511 const char * title,
27 int selected, 512 int selected,