Get rid of the 'center' parameter for splashes. There were only 2 of almost 500 splas...
[Rockbox.git] / apps / menus / main_menu.c
blob2e034162e596138f144136bd344e1fc01c1c576c
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 "settings_menu.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
51 struct browse_folder_info {
52 const char* dir;
53 int show_options;
55 static struct browse_folder_info theme = {THEME_DIR, SHOW_CFG};
56 static struct browse_folder_info config = {ROCKBOX_DIR, SHOW_CFG};
57 static int browse_folder(void *param)
59 const struct browse_folder_info *info =
60 (const struct browse_folder_info*)param;
61 return rockbox_browse(info->dir, info->show_options);
64 /***********************************/
65 /* MANAGE SETTINGS MENU */
67 static int reset_settings(void)
69 unsigned char *lines[]={str(LANG_RESET_ASK_RECORDER)};
70 unsigned char *yes_lines[]={
71 str(LANG_RESET_DONE_SETTING),
72 str(LANG_RESET_DONE_CLEAR)
74 unsigned char *no_lines[]={yes_lines[0], str(LANG_RESET_DONE_CANCEL)};
75 struct text_message message={(char **)lines, 1};
76 struct text_message yes_message={(char **)yes_lines, 2};
77 struct text_message no_message={(char **)no_lines, 2};
79 switch(gui_syncyesno_run(&message, &yes_message, &no_message))
81 case YESNO_YES:
82 settings_reset();
83 settings_apply();
84 settings_save();
85 break;
86 case YESNO_NO:
87 break;
88 case YESNO_USB:
89 return 1;
91 return 0;
93 static int write_settings_file(void* param)
95 return settings_save_config((intptr_t)param);
98 MENUITEM_FUNCTION_WPARAM(browse_configs, ID2P(LANG_CUSTOM_CFG),
99 browse_folder, (void*)&config, NULL, Icon_NOICON);
100 MENUITEM_FUNCTION_WPARAM(save_settings_item, ID2P(LANG_SAVE_SETTINGS),
101 write_settings_file, (void*)SETTINGS_SAVE_ALL, NULL, Icon_NOICON);
102 MENUITEM_FUNCTION_WPARAM(save_theme_item, ID2P(LANG_SAVE_THEME),
103 write_settings_file, (void*)SETTINGS_SAVE_THEME, NULL, Icon_NOICON);
104 MENUITEM_FUNCTION(reset_settings_item,ID2P(LANG_RESET),reset_settings, NULL, Icon_NOICON);
106 MAKE_MENU(manage_settings, ID2P(LANG_MANAGE_MENU), NULL, Icon_Config,
107 &browse_configs, &reset_settings_item,
108 &save_settings_item, &save_theme_item);
109 /* MANAGE SETTINGS MENU */
110 /**********************************/
112 /***********************************/
113 /* INFO MENU */
115 static bool show_credits(void)
117 plugin_load(PLUGIN_DIR "/credits.rock",NULL);
118 return false;
121 #ifdef SIMULATOR
122 extern bool simulate_usb(void);
123 #endif
125 #ifdef HAVE_LCD_CHARCELLS
126 #define SIZE_FMT "%s%s"
127 #else
128 #define SIZE_FMT "%s %s"
129 #endif
131 static bool show_info(void)
133 char s[64], s1[32];
134 unsigned long size, free;
135 long buflen = ((audiobufend - audiobuf) * 2) / 2097; /* avoid overflow */
136 int key;
137 int i;
138 bool done = false;
139 bool new_info = true;
140 #ifdef HAVE_MULTIVOLUME
141 char s2[32];
142 unsigned long size2, free2;
143 #endif
144 #ifdef HAVE_LCD_CHARCELLS
145 int page = 0;
146 #endif
148 const unsigned char *kbyte_units[] = {
149 ID2P(LANG_KILOBYTE),
150 ID2P(LANG_MEGABYTE),
151 ID2P(LANG_GIGABYTE)
153 #if defined(HAVE_LCD_BITMAP)
154 FOR_NB_SCREENS(i)
155 screens[i].setmargins(0, 0);
156 #endif
157 while (!done)
159 int y=0;
161 if (new_info)
163 fat_size( IF_MV2(0,) &size, &free );
164 #ifdef HAVE_MULTIVOLUME
165 if (fat_ismounted(1))
166 fat_size( 1, &size2, &free2 );
167 else
168 size2 = 0;
169 #endif
171 if (global_settings.talk_menu)
172 { /* say whatever is reasonable, no real connection to the screen */
173 bool enqueue = false; /* enqueue all but the first */
174 if (battery_level() >= 0)
176 talk_id(LANG_BATTERY_TIME, enqueue);
177 enqueue = true;
178 talk_value(battery_level(), UNIT_PERCENT, true);
179 #if CONFIG_CHARGING >= CHARGING_MONITOR
180 if (charge_state == CHARGING)
181 talk_id(LANG_BATTERY_CHARGE, true);
182 else if (charge_state == TOPOFF)
183 talk_id(LANG_BATTERY_TOPOFF_CHARGE, true);
184 else if (charge_state == TRICKLE)
185 talk_id(LANG_BATTERY_TRICKLE_CHARGE, true);
186 #endif
189 talk_id(LANG_DISK_FREE_INFO, enqueue);
190 #ifdef HAVE_MULTIVOLUME
191 talk_id(LANG_DISK_NAME_INTERNAL, true);
192 output_dyn_value(NULL, 0, free, kbyte_units, true);
193 if (size2)
195 talk_id(LANG_DISK_NAME_MMC, true);
196 output_dyn_value(NULL, 0, free2, kbyte_units, true);
198 #else
199 output_dyn_value(NULL, 0, free, kbyte_units, true);
200 #endif
202 #ifdef CONFIG_RTC
204 struct tm* tm = get_time();
205 talk_id(VOICE_CURRENT_TIME, true);
206 talk_value(tm->tm_hour, UNIT_HOUR, true);
207 talk_value(tm->tm_min, UNIT_MIN, true);
208 talk_value(tm->tm_sec, UNIT_SEC, true);
209 talk_id(LANG_MONTH_JANUARY + tm->tm_mon, true);
210 talk_number(tm->tm_mday, true);
211 talk_number(1900 + tm->tm_year, true);
213 #endif
215 new_info = false;
218 FOR_NB_SCREENS(i)
220 screens[i].clear_display();
221 #ifdef HAVE_LCD_BITMAP
222 screens[i].puts(0, y, str(LANG_ROCKBOX_INFO));
223 #endif
225 #ifdef HAVE_LCD_BITMAP
226 y += 2;
227 #endif
229 #ifdef HAVE_LCD_CHARCELLS
230 if (page == 0)
231 #endif
233 int integer = buflen / 1000;
234 int decimal = buflen % 1000;
236 #ifdef HAVE_LCD_CHARCELLS
237 snprintf(s, sizeof(s), (char *)str(LANG_BUFFER_STAT_PLAYER),
238 integer, decimal);
239 #else
240 snprintf(s, sizeof(s), (char *)str(LANG_BUFFER_STAT_RECORDER),
241 integer, decimal);
242 #endif
243 FOR_NB_SCREENS(i)
244 screens[i].puts_scroll(0, y, (unsigned char *)s);
245 y++;
246 #if CONFIG_CHARGING == CHARGING_CONTROL
247 if (charge_state == CHARGING)
248 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_CHARGE));
249 else if (charge_state == TOPOFF)
250 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TOPOFF_CHARGE));
251 else if (charge_state == TRICKLE)
252 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TRICKLE_CHARGE));
253 else
254 #endif
255 if (battery_level() >= 0)
256 snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TIME), battery_level(),
257 battery_time() / 60, battery_time() % 60);
258 else
259 strncpy(s, "(n/a)", sizeof(s));
260 FOR_NB_SCREENS(i)
261 screens[i].puts_scroll(0, y, (unsigned char *)s);
262 y++;
265 #ifdef HAVE_LCD_CHARCELLS
266 if (page == 1)
267 #endif
269 #ifdef HAVE_MULTIVOLUME
270 output_dyn_value(s1, sizeof s1, free, kbyte_units, true);
271 output_dyn_value(s2, sizeof s2, size, kbyte_units, true);
272 snprintf(s, sizeof s, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL),
273 s1, s2);
274 FOR_NB_SCREENS(i)
275 screens[i].puts_scroll(0, y, (unsigned char *)s);
276 y++;
278 if (size2) {
279 output_dyn_value(s1, sizeof s1, free2, kbyte_units, true);
280 output_dyn_value(s2, sizeof s2, size2, kbyte_units, true);
281 snprintf(s, sizeof s, "%s %s/%s", str(LANG_DISK_NAME_MMC),
282 s1, s2);
283 FOR_NB_SCREENS(i)
284 screens[i].puts_scroll(0, y, (unsigned char *)s);
285 y++;
287 #else
288 output_dyn_value(s1, sizeof s1, size, kbyte_units, true);
289 snprintf(s, sizeof s, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1);
290 FOR_NB_SCREENS(i)
291 screens[i].puts_scroll(0, y, (unsigned char *)s);
292 y++;
293 output_dyn_value(s1, sizeof s1, free, kbyte_units, true);
294 snprintf(s, sizeof s, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1);
295 FOR_NB_SCREENS(i)
296 screens[i].puts_scroll(0, y, (unsigned char *)s);
297 y++;
298 #endif
301 #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
302 FOR_NB_SCREENS(i)
303 screens[i].update();
304 #endif
306 /* Wait for a key to be pushed */
307 key = get_action(CONTEXT_MAINMENU,HZ*5);
308 switch(key) {
310 case ACTION_STD_CANCEL:
311 done = true;
312 break;
314 #ifdef HAVE_LCD_CHARCELLS
315 case ACTION_STD_NEXT:
316 case ACTION_STD_PREV:
317 page = (page == 0) ? 1 : 0;
318 break;
319 #endif
321 #ifndef SIMULATOR
322 case ACTION_STD_OK:
323 gui_syncsplash(0, str(LANG_DIRCACHE_BUILDING));
324 fat_recalc_free(IF_MV(0));
325 #ifdef HAVE_MULTIVOLUME
326 if (fat_ismounted(1))
327 fat_recalc_free(1);
328 #endif
329 new_info = true;
330 break;
331 #endif
333 default:
334 if (default_event_handler(key) == SYS_USB_CONNECTED)
335 return true;
336 break;
339 action_signalscreenchange();
340 return false;
342 MENUITEM_FUNCTION(show_info_item, ID2P(LANG_INFO_MENU),
343 (menu_function)show_info, NULL, Icon_NOICON);
346 /* sleep Menu */
347 static void sleep_timer_formatter(char* buffer, int buffer_size, int value,
348 const char* unit)
350 int minutes, hours;
352 (void) unit;
354 if (value) {
355 hours = value / 60;
356 minutes = value - (hours * 60);
357 snprintf(buffer, buffer_size, "%d:%02d", hours, minutes);
358 } else {
359 snprintf(buffer, buffer_size, "%s", str(LANG_OFF));
363 static void sleep_timer_set(int minutes)
365 set_sleep_timer(minutes * 60);
368 static int sleep_timer(void)
370 int minutes = (get_sleep_timer() + 59) / 60; /* round up */
371 return (int)set_int(str(LANG_SLEEP_TIMER), "", UNIT_MIN, &minutes,
372 &sleep_timer_set, -5, 300, 0, sleep_timer_formatter);
375 MENUITEM_FUNCTION(sleep_timer_call, ID2P(LANG_SLEEP_TIMER), sleep_timer,
376 NULL, Icon_Menu_setting); /* make it look like a
377 setting to the user */
378 MENUITEM_FUNCTION(show_credits_item, ID2P(LANG_VERSION),
379 (menu_function)show_credits, NULL, Icon_NOICON);
380 MENUITEM_FUNCTION(show_runtime_item, ID2P(LANG_RUNNING_TIME),
381 (menu_function)view_runtime, NULL, Icon_NOICON);
382 MENUITEM_FUNCTION(debug_menu_item, ID2P(LANG_DEBUG),
383 (menu_function)debug_menu, NULL, Icon_NOICON);
384 #ifdef SIMULATOR
385 MENUITEM_FUNCTION(simulate_usb_item, ID2P(LANG_USB),
386 (menu_function)simulate_usb, NULL, Icon_NOICON);
387 #ifdef ROCKBOX_HAS_LOGF
388 MENUITEM_FUNCTION(logfdisplay_item, "logf",(int (*)(void)) logfdisplay, NULL, Icon_NOICON);
389 MENUITEM_FUNCTION(logfdump_item, "logfdump",(int (*)(void)) logfdump, NULL, Icon_NOICON);
390 #endif
391 #endif
393 MAKE_MENU(info_menu, ID2P(LANG_INFO), 0, Icon_Questionmark,
394 &show_info_item, &show_credits_item, &show_runtime_item,
395 &sleep_timer_call, &debug_menu_item
396 #ifdef SIMULATOR
397 ,&simulate_usb_item
398 #ifdef ROCKBOX_HAS_LOGF
399 ,&logfdisplay_item, &logfdump_item
400 #endif
401 #endif
403 /* INFO MENU */
404 /***********************************/
406 /***********************************/
407 /* MAIN MENU */
409 MENUITEM_FUNCTION_WPARAM(browse_themes, ID2P(LANG_CUSTOM_THEME),
410 browse_folder, (void*)&theme, NULL, Icon_Folder);
412 #ifdef HAVE_LCD_CHARCELLS
413 int mainmenu_callback(int action,const struct menu_item_ex *this_item)
415 (void)this_item;
416 switch (action)
418 case ACTION_ENTER_MENUITEM:
419 status_set_param(true);
420 break;
421 case ACTION_EXIT_MENUITEM:
422 status_set_param(false);
423 break;
425 return action;
427 #else
428 #define mainmenu_callback NULL
429 #endif
430 MAKE_MENU(main_menu_, ID2P(LANG_SETTINGS_MENU), mainmenu_callback,
431 Icon_Submenu_Entered,
432 &sound_settings,
433 &settings_menu_item, &manage_settings, &browse_themes,
434 #ifdef HAVE_RECORDING
435 &recording_settings,
436 #endif
438 /* MAIN MENU */
439 /***********************************/