Allow recording source to be set from recording context menu. Not a very nice solutio...
[Rockbox.git] / apps / menus / main_menu.c
blob9f6d9a527c70af0439b6ab3bb3c96ce98ca33f32
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 "string.h"
25 #include "lang.h"
26 #include "action.h"
27 #include "settings.h"
28 #include "powermgmt.h"
29 #include "menu.h"
30 #include "misc.h"
31 #include "exported_menus.h"
32 #include "tree.h"
33 #ifdef HAVE_RECORDING
34 #include "recording.h"
35 #endif
36 #include "bookmark.h"
37 #include "yesno.h"
38 #include "keyboard.h"
39 #include "screens.h"
40 #include "plugin.h"
41 #include "talk.h"
42 #include "buffer.h"
43 #include "splash.h"
44 #include "debug_menu.h"
45 #if defined(SIMULATOR) && defined(ROCKBOX_HAS_LOGF)
46 #include "logfdisp.h"
47 #endif
48 #include "version.h"
52 struct browse_folder_info {
53 const char* dir;
54 int show_options;
56 static struct browse_folder_info theme = {THEME_DIR, SHOW_CFG};
57 static struct browse_folder_info config = {ROCKBOX_DIR, SHOW_CFG};
58 int browse_folder(void *param)
60 const struct browse_folder_info *info =
61 (const struct browse_folder_info*)param;
62 return rockbox_browse(info->dir, info->show_options);
65 /***********************************/
66 /* MANAGE SETTINGS MENU */
68 static int reset_settings(void)
70 unsigned char *lines[]={ID2P(LANG_RESET_ASK)};
71 unsigned char *yes_lines[]={
72 str(LANG_SETTINGS),
73 ID2P(LANG_RESET_DONE_CLEAR)
75 unsigned char *no_lines[]={yes_lines[0], ID2P(LANG_CANCEL)};
76 struct text_message message={(char **)lines, 1};
77 struct text_message yes_message={(char **)yes_lines, 2};
78 struct text_message no_message={(char **)no_lines, 2};
80 switch(gui_syncyesno_run(&message, &yes_message, &no_message))
82 case YESNO_YES:
83 settings_reset();
84 settings_apply();
85 settings_save();
86 break;
87 case YESNO_NO:
88 break;
89 case YESNO_USB:
90 return 1;
92 return 0;
94 static int write_settings_file(void* param)
96 return settings_save_config((intptr_t)param);
99 MENUITEM_FUNCTION(browse_configs, MENU_FUNC_USEPARAM, ID2P(LANG_CUSTOM_CFG),
100 browse_folder, (void*)&config, NULL, Icon_NOICON);
101 MENUITEM_FUNCTION(save_settings_item, MENU_FUNC_USEPARAM, ID2P(LANG_SAVE_SETTINGS),
102 write_settings_file, (void*)SETTINGS_SAVE_ALL, NULL, Icon_NOICON);
103 MENUITEM_FUNCTION(save_theme_item, MENU_FUNC_USEPARAM, ID2P(LANG_SAVE_THEME),
104 write_settings_file, (void*)SETTINGS_SAVE_THEME, NULL, Icon_NOICON);
105 MENUITEM_FUNCTION(reset_settings_item, 0, ID2P(LANG_RESET),
106 reset_settings, NULL, NULL, Icon_NOICON);
108 MAKE_MENU(manage_settings, ID2P(LANG_MANAGE_MENU), NULL, Icon_Config,
109 &browse_configs, &reset_settings_item,
110 &save_settings_item, &save_theme_item);
111 /* MANAGE SETTINGS MENU */
112 /**********************************/
114 /***********************************/
115 /* INFO MENU */
117 static bool show_credits(void)
119 if (plugin_load(VIEWERS_DIR "/credits.rock",NULL) != PLUGIN_OK)
121 /* show the rockbox logo and version untill a button is pressed */
122 show_logo();
123 get_action(CONTEXT_STD, TIMEOUT_BLOCK);
125 return false;
128 #ifdef SIMULATOR
129 extern bool simulate_usb(void);
130 #endif
132 #ifdef HAVE_LCD_CHARCELLS
133 #define SIZE_FMT "%s%s"
134 #else
135 #define SIZE_FMT "%s %s"
136 #endif
138 static bool show_info(void)
140 char s[64], s1[32];
141 unsigned long size, free;
142 long buflen = ((audiobufend - audiobuf) * 2) / 2097; /* avoid overflow */
143 int key;
144 int i;
145 bool done = false;
146 bool new_info = true;
147 #ifdef HAVE_MULTIVOLUME
148 char s2[32];
149 unsigned long size2, free2;
150 #endif
151 #ifdef HAVE_LCD_CHARCELLS
152 int page = 0;
153 #endif
155 const unsigned char *kbyte_units[] = {
156 ID2P(LANG_KILOBYTE),
157 ID2P(LANG_MEGABYTE),
158 ID2P(LANG_GIGABYTE)
160 #if defined(HAVE_LCD_BITMAP)
161 FOR_NB_SCREENS(i)
162 screens[i].setmargins(0, 0);
163 #endif
164 while (!done)
166 int y=0;
168 if (new_info)
170 fat_size( IF_MV2(0,) &size, &free );
171 #ifdef HAVE_MULTIVOLUME
172 if (fat_ismounted(1))
173 fat_size( 1, &size2, &free2 );
174 else
175 size2 = 0;
176 #endif
178 if (talk_menus_enabled())
180 /* say whatever is reasonable, no real connection to the screen */
181 bool enqueue = false; /* enqueue all but the first */
182 if (battery_level() >= 0)
184 talk_id(LANG_BATTERY_TIME, enqueue);
185 enqueue = true;
186 talk_value(battery_level(), UNIT_PERCENT, true);
187 #if CONFIG_CHARGING >= CHARGING_MONITOR
188 if (charge_state == CHARGING)
189 talk_id(LANG_BATTERY_CHARGE, true);
190 #if CONFIG_CHARGING == CHARGING_CONTROL
191 else if (charge_state == TOPOFF)
192 talk_id(LANG_BATTERY_TOPOFF_CHARGE, true);
193 #endif
194 else if (charge_state == TRICKLE)
195 talk_id(LANG_BATTERY_TRICKLE_CHARGE, true);
196 #endif
199 talk_id(LANG_DISK_FREE_INFO, enqueue);
200 #ifdef HAVE_MULTIVOLUME
201 talk_id(LANG_DISK_NAME_INTERNAL, true);
202 output_dyn_value(NULL, 0, free, kbyte_units, true);
203 if (size2)
205 talk_id(LANG_DISK_NAME_MMC, true);
206 output_dyn_value(NULL, 0, free2, kbyte_units, true);
208 #else
209 output_dyn_value(NULL, 0, free, kbyte_units, true);
210 #endif
212 #if CONFIG_RTC
214 struct tm* tm = get_time();
215 talk_id(VOICE_CURRENT_TIME, true);
216 talk_value(tm->tm_hour, UNIT_HOUR, true);
217 talk_value(tm->tm_min, UNIT_MIN, true);
218 talk_value(tm->tm_sec, UNIT_SEC, true);
219 talk_id(LANG_MONTH_JANUARY + tm->tm_mon, true);
220 talk_number(tm->tm_mday, true);
221 talk_number(1900 + tm->tm_year, true);
223 #endif
225 new_info = false;
228 FOR_NB_SCREENS(i)
230 screens[i].clear_display();
231 #ifdef HAVE_LCD_BITMAP
232 screens[i].puts(0, y, str(LANG_ROCKBOX_INFO));
233 #endif
235 #ifdef HAVE_LCD_BITMAP
236 y++;
237 #endif
238 #ifdef HAVE_LCD_CHARCELLS
239 if (page == 0)
240 #endif
242 snprintf(s, sizeof(s), "%s: %s", str(LANG_VERSION), appsversion);
243 FOR_NB_SCREENS(i)
244 screens[i].puts_scroll(0, y, (unsigned char *)s);
245 #ifdef HAVE_LCD_BITMAP
246 y += 2;
247 #endif
250 #ifdef HAVE_LCD_CHARCELLS
251 if (page == 1)
252 #endif
254 int integer = buflen / 1000;
255 int decimal = buflen % 1000;
257 snprintf(s, sizeof(s), (char *)str(LANG_BUFFER_STAT),
258 integer, decimal);
260 FOR_NB_SCREENS(i)
261 screens[i].puts_scroll(0, y, (unsigned char *)s);
262 y++;
263 #if CONFIG_CHARGING == CHARGING_CONTROL
264 if (charge_state == CHARGING)
265 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_CHARGE));
266 else if (charge_state == TOPOFF)
267 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TOPOFF_CHARGE));
268 else if (charge_state == TRICKLE)
269 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TRICKLE_CHARGE));
270 else
271 #endif
272 if (battery_level() >= 0)
273 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TIME), battery_level(),
274 battery_time() / 60, battery_time() % 60);
275 else
276 strncpy(s, "(n/a)", sizeof(s));
277 FOR_NB_SCREENS(i)
278 screens[i].puts_scroll(0, y, (unsigned char *)s);
279 y++;
282 #ifdef HAVE_LCD_CHARCELLS
283 if (page == 2)
284 #endif
286 #ifdef HAVE_MULTIVOLUME
287 output_dyn_value(s1, sizeof s1, free, kbyte_units, true);
288 output_dyn_value(s2, sizeof s2, size, kbyte_units, true);
289 snprintf(s, sizeof s, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL),
290 s1, s2);
291 FOR_NB_SCREENS(i)
292 screens[i].puts_scroll(0, y, (unsigned char *)s);
293 y++;
295 if (size2) {
296 output_dyn_value(s1, sizeof s1, free2, kbyte_units, true);
297 output_dyn_value(s2, sizeof s2, size2, kbyte_units, true);
298 snprintf(s, sizeof s, "%s %s/%s", str(LANG_DISK_NAME_MMC),
299 s1, s2);
300 FOR_NB_SCREENS(i)
301 screens[i].puts_scroll(0, y, (unsigned char *)s);
302 y++;
304 #else
305 output_dyn_value(s1, sizeof s1, size, kbyte_units, true);
306 snprintf(s, sizeof s, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1);
307 FOR_NB_SCREENS(i)
308 screens[i].puts_scroll(0, y, (unsigned char *)s);
309 y++;
310 output_dyn_value(s1, sizeof s1, free, kbyte_units, true);
311 snprintf(s, sizeof s, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1);
312 FOR_NB_SCREENS(i)
313 screens[i].puts_scroll(0, y, (unsigned char *)s);
314 y++;
315 #endif
318 FOR_NB_SCREENS(i)
319 screens[i].update();
321 /* Wait for a key to be pushed */
322 key = get_action(CONTEXT_MAINMENU,HZ*5);
323 switch(key) {
325 case ACTION_STD_CANCEL:
326 done = true;
327 break;
329 #ifdef HAVE_LCD_CHARCELLS
330 case ACTION_STD_NEXT:
331 page = (page+1)%3;
332 break;
333 case ACTION_STD_PREV:
334 page--;
335 if (page < 0)
336 page = 2;
337 break;
338 #endif
340 #ifndef SIMULATOR
341 case ACTION_STD_OK:
342 gui_syncsplash(0, str(LANG_SCANNING_DISK));
343 fat_recalc_free(IF_MV(0));
344 #ifdef HAVE_MULTIVOLUME
345 if (fat_ismounted(1))
346 fat_recalc_free(1);
347 #endif
348 new_info = true;
349 break;
350 #endif
352 default:
353 if (default_event_handler(key) == SYS_USB_CONNECTED)
354 return true;
355 break;
358 return false;
360 MENUITEM_FUNCTION(show_info_item, 0, ID2P(LANG_ROCKBOX_INFO),
361 (menu_function)show_info, NULL, NULL, Icon_NOICON);
364 /* sleep Menu */
365 static void sleep_timer_formatter(char* buffer, int buffer_size, int value,
366 const char* unit)
368 int minutes, hours;
370 (void) unit;
372 if (value) {
373 hours = value / 60;
374 minutes = value - (hours * 60);
375 snprintf(buffer, buffer_size, "%d:%02d", hours, minutes);
376 } else {
377 snprintf(buffer, buffer_size, "%s", str(LANG_OFF));
381 static void sleep_timer_set(int minutes)
383 set_sleep_timer(minutes * 60);
386 static int sleep_timer(void)
388 int minutes = (get_sleep_timer() + 59) / 60; /* round up */
389 return (int)set_int(str(LANG_SLEEP_TIMER), "", UNIT_MIN, &minutes,
390 &sleep_timer_set, -5, 300, 0, sleep_timer_formatter);
393 MENUITEM_FUNCTION(sleep_timer_call, 0, ID2P(LANG_SLEEP_TIMER), sleep_timer,
394 NULL, NULL, Icon_Menu_setting); /* make it look like a
395 setting to the user */
396 MENUITEM_FUNCTION(show_credits_item, 0, ID2P(LANG_VERSION),
397 (menu_function)show_credits, NULL, NULL, Icon_NOICON);
398 MENUITEM_FUNCTION(show_runtime_item, 0, ID2P(LANG_RUNNING_TIME),
399 (menu_function)view_runtime, NULL, NULL, Icon_NOICON);
400 MENUITEM_FUNCTION(debug_menu_item, 0, ID2P(LANG_DEBUG),
401 (menu_function)debug_menu, NULL, NULL, Icon_NOICON);
402 #ifdef SIMULATOR
403 MENUITEM_FUNCTION(simulate_usb_item, 0, ID2P(LANG_USB),
404 (menu_function)simulate_usb, NULL, NULL, Icon_NOICON);
405 #endif
407 MAKE_MENU(info_menu, ID2P(LANG_SYSTEM), 0, Icon_Questionmark,
408 &show_info_item, &show_credits_item, &show_runtime_item,
409 &sleep_timer_call, &debug_menu_item
410 #ifdef SIMULATOR
411 ,&simulate_usb_item
412 #endif
414 /* INFO MENU */
415 /***********************************/
417 /***********************************/
418 /* MAIN MENU */
420 MENUITEM_FUNCTION(browse_themes, MENU_FUNC_USEPARAM, ID2P(LANG_CUSTOM_THEME),
421 browse_folder, (void*)&theme, NULL, Icon_Folder);
423 #ifdef HAVE_LCD_CHARCELLS
424 int mainmenu_callback(int action,const struct menu_item_ex *this_item)
426 (void)this_item;
427 switch (action)
429 case ACTION_ENTER_MENUITEM:
430 status_set_param(true);
431 break;
432 case ACTION_EXIT_MENUITEM:
433 status_set_param(false);
434 break;
436 return action;
438 #else
439 #define mainmenu_callback NULL
440 #endif
441 MAKE_MENU(main_menu_, ID2P(LANG_SETTINGS), mainmenu_callback,
442 Icon_Submenu_Entered,
443 &sound_settings,
444 &settings_menu_item, &manage_settings, &browse_themes,
445 #ifdef HAVE_RECORDING
446 &recording_settings,
447 #endif
449 /* MAIN MENU */
450 /***********************************/