1
0
Fork 0
forked from len0rd/rockbox
foxbox/apps/menus/main_menu.c
Jonathan Gordon e385ee18ce Decouple the statusbar drawing from the rest of the screen drawing. it is not drawn roughly 4x per second automatically.
viewport_Set_defaults() will setup the given viewport with the correct "full screen" dimensions (so start at 0,0 if statusbars are disabled or 0,8 if they are enabled.)
All screens should keep the statusbar enabled, but if you really want to ignore the user setting you can disbaled it with viewportmanager_set_statusbar(false).

This commit also includes some menu/list viewport cleanups from kugel in FS#9603


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19622 a1c6a512-1295-4272-9138-f99709370657
2008-12-31 05:59:26 +00:00

496 lines
16 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Jonathan Gordon
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdbool.h>
#include <stddef.h>
#include <limits.h>
#include "config.h"
#include "string.h"
#include "lang.h"
#include "action.h"
#include "settings.h"
#include "power.h"
#include "powermgmt.h"
#include "menu.h"
#include "misc.h"
#include "exported_menus.h"
#include "tree.h"
#ifdef HAVE_RECORDING
#include "recording.h"
#endif
#include "bookmark.h"
#include "yesno.h"
#include "keyboard.h"
#include "screens.h"
#include "plugin.h"
#include "talk.h"
#include "buffer.h"
#include "splash.h"
#include "debug_menu.h"
#if defined(SIMULATOR) && defined(ROCKBOX_HAS_LOGF)
#include "logfdisp.h"
#endif
#include "version.h"
#include "time.h"
#include "gwps.h"
static const struct browse_folder_info config = {ROCKBOX_DIR, SHOW_CFG};
/***********************************/
/* MANAGE SETTINGS MENU */
static int reset_settings(void)
{
static const char *lines[]={ID2P(LANG_RESET_ASK)};
static const char *yes_lines[]={
ID2P(LANG_SETTINGS),
ID2P(LANG_RESET_DONE_CLEAR)
};
static const char *no_lines[]={
ID2P(LANG_SETTINGS),
ID2P(LANG_CANCEL)
};
static const struct text_message message={lines, 1};
static const struct text_message yes_message={yes_lines, 2};
static const struct text_message no_message={no_lines, 2};
switch(gui_syncyesno_run(&message, &yes_message, &no_message))
{
case YESNO_YES:
settings_reset();
settings_apply(true);
settings_save();
break;
case YESNO_NO:
break;
case YESNO_USB:
return 1;
}
return 0;
}
static int write_settings_file(void* param)
{
return settings_save_config((intptr_t)param);
}
MENUITEM_FUNCTION(browse_configs, MENU_FUNC_USEPARAM, ID2P(LANG_CUSTOM_CFG),
browse_folder, (void*)&config, NULL, Icon_NOICON);
MENUITEM_FUNCTION(save_settings_item, MENU_FUNC_USEPARAM, ID2P(LANG_SAVE_SETTINGS),
write_settings_file, (void*)SETTINGS_SAVE_ALL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(save_theme_item, MENU_FUNC_USEPARAM, ID2P(LANG_SAVE_THEME),
write_settings_file, (void*)SETTINGS_SAVE_THEME, NULL, Icon_NOICON);
MENUITEM_FUNCTION(save_sound_item, MENU_FUNC_USEPARAM, ID2P(LANG_SAVE_SOUND),
write_settings_file, (void*)SETTINGS_SAVE_SOUND, NULL, Icon_NOICON);
MENUITEM_FUNCTION(reset_settings_item, 0, ID2P(LANG_RESET),
reset_settings, NULL, NULL, Icon_NOICON);
MAKE_MENU(manage_settings, ID2P(LANG_MANAGE_MENU), NULL, Icon_Config,
&browse_configs, &reset_settings_item,
&save_settings_item, &save_sound_item, &save_theme_item);
/* MANAGE SETTINGS MENU */
/**********************************/
/***********************************/
/* INFO MENU */
static bool show_credits(void)
{
if (plugin_load(VIEWERS_DIR "/credits.rock",NULL) != PLUGIN_OK)
{
/* show the rockbox logo and version untill a button is pressed */
show_logo();
while (IS_SYSEVENT(get_action(CONTEXT_STD, TIMEOUT_BLOCK)))
;
}
return false;
}
#ifdef HAVE_LCD_CHARCELLS
#define SIZE_FMT "%s%s"
#else
#define SIZE_FMT "%s %s"
#endif
struct info_data
{
bool new_data;
unsigned long size;
unsigned long free;
#ifdef HAVE_MULTIVOLUME
unsigned long size2;
unsigned long free2;
#endif
};
enum infoscreenorder
{
INFO_BATTERY = 0,
INFO_DISK1, /* capacity or internal capacity/free on hotswap */
INFO_DISK2, /* free space or external capacity/free on hotswap */
INFO_BUFFER,
#ifdef HAVE_ALBUMART
INFO_ALBUMART,
#endif
INFO_VERSION,
INFO_COUNT
};
static const unsigned char *kbyte_units[] =
{
ID2P(LANG_KILOBYTE),
ID2P(LANG_MEGABYTE),
ID2P(LANG_GIGABYTE)
};
static char* info_getname(int selected_item, void *data,
char *buffer, size_t buffer_len)
{
struct info_data *info = (struct info_data*)data;
char s1[32];
#ifdef HAVE_MULTIVOLUME
char s2[32];
#endif
if (info->new_data)
{
fat_size(IF_MV2(0,) &info->size, &info->free);
#ifdef HAVE_MULTIVOLUME
if (fat_ismounted(1))
fat_size(1, &info->size2, &info->free2);
else
info->size2 = 0;
#endif
info->new_data = false;
}
switch (selected_item)
{
case INFO_VERSION:
snprintf(buffer, buffer_len, "%s: %s",
str(LANG_VERSION), appsversion);
break;
case INFO_BUFFER: /* buffer */
{
long kib = (audiobufend - audiobuf) / 1024; /* to KiB */
output_dyn_value(s1, sizeof(s1), kib, kbyte_units, true);
snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1);
}
break;
case INFO_BATTERY: /* battery */
#if CONFIG_CHARGING == CHARGING_SIMPLE
if (charger_input_state == CHARGER)
return (char *)str(LANG_BATTERY_CHARGE);
else
#elif CONFIG_CHARGING >= CHARGING_MONITOR
if (charge_state == CHARGING)
return (char *)str(LANG_BATTERY_CHARGE);
else
#ifdef ARCHOS_RECORDER
if (charge_state == TOPOFF)
return (char *)str(LANG_BATTERY_TOPOFF_CHARGE);
else if (charge_state == TRICKLE)
return (char *)str(LANG_BATTERY_TRICKLE_CHARGE);
else
#endif /* ARCHOS_RECORDER */
#endif /* CONFIG_CHARGING = */
if (battery_level() >= 0)
snprintf(buffer, buffer_len, (char *)str(LANG_BATTERY_TIME),
battery_level(), battery_time() / 60, battery_time() % 60);
else
return "(n/a)";
break;
case INFO_DISK1: /* disk usage 1 */
#ifdef HAVE_MULTIVOLUME
output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true);
output_dyn_value(s2, sizeof s2, info->size, kbyte_units, true);
snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL),
s1, s2);
#else
output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true);
snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1);
#endif
break;
case INFO_DISK2: /* disk usage 2 */
#ifdef HAVE_MULTIVOLUME
if (info->size2)
{
output_dyn_value(s1, sizeof s1, info->free2, kbyte_units, true);
output_dyn_value(s2, sizeof s2, info->size2, kbyte_units, true);
snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_MMC),
s1, s2);
}
else
{
snprintf(buffer, buffer_len, "%s %s", str(LANG_DISK_NAME_MMC),
str(LANG_NOT_PRESENT));
}
#else
output_dyn_value(s1, sizeof s1, info->size, kbyte_units, true);
snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1);
#endif
break;
#ifdef HAVE_ALBUMART
case INFO_ALBUMART: /* album art dimenstions */
if (gui_sync_wps_uses_albumart())
{
snprintf(buffer, buffer_len, "%s %dx%d", str(LANG_ALBUMART),
gui_wps[0].data->albumart_max_width,
gui_wps[0].data->albumart_max_height);
}
else
{
snprintf(buffer, buffer_len, "%s %s", str(LANG_ALBUMART),
str(LANG_SET_BOOL_NO));
}
#endif
}
return buffer;
}
static int info_speak_item(int selected_item, void * data)
{
struct info_data *info = (struct info_data*)data;
switch (selected_item)
{
case INFO_VERSION: /* version */
talk_id(LANG_VERSION, false);
talk_spell(appsversion, true);
break;
case INFO_BUFFER: /* buffer */
{
talk_id(LANG_BUFFER_STAT, false);
long kib = (audiobufend - audiobuf) / 1024; /* to KiB */
output_dyn_value(NULL, 0, kib, kbyte_units, true);
break;
}
case INFO_BATTERY: /* battery */
#if CONFIG_CHARGING == CHARGING_SIMPLE
if (charger_inserted())
talk_id(LANG_BATTERY_CHARGE, true);
else
#elif CONFIG_CHARGING >= CHARGING_MONITOR
if (charge_state == CHARGING)
talk_id(LANG_BATTERY_CHARGE, true);
else
#ifdef ARCHOS_RECORDER
if (charge_state == TOPOFF)
talk_id(LANG_BATTERY_TOPOFF_CHARGE, true);
else if (charge_state == TRICKLE)
talk_id(LANG_BATTERY_TRICKLE_CHARGE, true);
else
#endif /* ARCHOS_RECORDER */
#endif /* CONFIG_CHARGING = */
if (battery_level() >= 0)
{
talk_id(LANG_BATTERY_TIME, false);
talk_value(battery_level(), UNIT_PERCENT, true);
talk_value(battery_time() *60, UNIT_TIME, true);
}
else talk_id(VOICE_BLANK, false);
break;
case INFO_DISK1: /* disk 1 */
#ifdef HAVE_MULTIVOLUME
talk_id(LANG_DISK_NAME_INTERNAL, false);
talk_id(LANG_DISK_FREE_INFO, true);
output_dyn_value(NULL, 0, info->free, kbyte_units, true);
talk_id(LANG_DISK_SIZE_INFO, true);
output_dyn_value(NULL, 0, info->size, kbyte_units, true);
#else
talk_id(LANG_DISK_FREE_INFO, false);
output_dyn_value(NULL, 0, info->free, kbyte_units, true);
#endif
break;
case INFO_DISK2: /* disk 2 */
#ifdef HAVE_MULTIVOLUME
talk_id(LANG_DISK_NAME_MMC, false);
if (info->size2)
{
talk_id(LANG_DISK_FREE_INFO, true);
output_dyn_value(NULL, 0, info->free2, kbyte_units, true);
talk_id(LANG_DISK_SIZE_INFO, true);
output_dyn_value(NULL, 0, info->size2, kbyte_units, true);
}
else talk_id(LANG_NOT_PRESENT, true);
#else
talk_id(LANG_DISK_SIZE_INFO, false);
output_dyn_value(NULL, 0, info->size, kbyte_units, true);
#endif
break;
#ifdef HAVE_ALBUMART
case INFO_ALBUMART: /* album art dimenstions */
if (gui_sync_wps_uses_albumart())
{
talk_id(LANG_ALBUMART, false);
talk_value(gui_wps[0].data->albumart_max_width, UNIT_PIXEL, true);
talk_value(gui_wps[0].data->albumart_max_height, UNIT_PIXEL, true);
}
else
{
talk_id(LANG_ALBUMART, false);
talk_id(LANG_SET_BOOL_NO, true);
}
#endif
}
return 0;
}
static int info_action_callback(int action, struct gui_synclist *lists)
{
if (action == ACTION_STD_CANCEL)
return action;
else if ((action == ACTION_STD_OK)
#ifdef HAVE_MULTIVOLUME
|| action == SYS_HOTSWAP_INSERTED
|| action == SYS_HOTSWAP_EXTRACTED
#endif
)
{
#ifndef SIMULATOR
struct info_data *info = (struct info_data *)lists->data;
info->new_data = true;
splash(0, ID2P(LANG_SCANNING_DISK));
fat_recalc_free(IF_MV(0));
#ifdef HAVE_MULTIVOLUME
if (fat_ismounted(1))
fat_recalc_free(1);
#endif
#else
(void) lists;
#endif
gui_synclist_speak_item(lists);
return ACTION_REDRAW;
}
return action;
}
static bool show_info(void)
{
struct info_data data = {.new_data = true };
struct simplelist_info info;
simplelist_info_init(&info, str(LANG_ROCKBOX_INFO), INFO_COUNT, (void*)&data);
info.hide_selection = !global_settings.talk_menu;
if (info.hide_selection)
info.scroll_all = true;
info.get_name = info_getname;
if(global_settings.talk_menu)
info.get_talk = info_speak_item;
info.action_callback = info_action_callback;
return simplelist_show_list(&info);
}
MENUITEM_FUNCTION(show_info_item, 0, ID2P(LANG_ROCKBOX_INFO),
(menu_function)show_info, NULL, NULL, Icon_NOICON);
/* sleep Menu */
static void sleep_timer_formatter(char* buffer, size_t buffer_size, int value,
const char* unit)
{
int minutes, hours;
(void) unit;
if (value) {
hours = value / 60;
minutes = value - (hours * 60);
snprintf(buffer, buffer_size, "%d:%02d", hours, minutes);
} else {
strncpy(buffer, str(LANG_OFF), buffer_size);
}
}
static void sleep_timer_set(int minutes)
{
set_sleep_timer(minutes * 60);
}
static int sleep_timer(void)
{
int minutes = (get_sleep_timer() + 59) / 60; /* round up */
return (int)set_int(str(LANG_SLEEP_TIMER), "", UNIT_MIN, &minutes,
&sleep_timer_set, -5, 300, 0, sleep_timer_formatter);
}
#if CONFIG_RTC
int time_screen(void* ignored);
MENUITEM_FUNCTION(timedate_item, MENU_FUNC_CHECK_RETVAL, ID2P(LANG_TIME_MENU), time_screen,
NULL, NULL, Icon_Menu_setting );
#endif
/* This item is in the time/date screen if there is a RTC */
MENUITEM_FUNCTION(sleep_timer_call, 0, ID2P(LANG_SLEEP_TIMER), sleep_timer,
NULL, NULL, Icon_Menu_setting); /* make it look like a
setting to the user */
MENUITEM_FUNCTION(show_credits_item, 0, ID2P(LANG_VERSION),
(menu_function)show_credits, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(show_runtime_item, 0, ID2P(LANG_RUNNING_TIME),
(menu_function)view_runtime, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(debug_menu_item, 0, ID2P(LANG_DEBUG),
(menu_function)debug_menu, NULL, NULL, Icon_NOICON);
MAKE_MENU(info_menu, ID2P(LANG_SYSTEM), 0, Icon_Questionmark,
#if CONFIG_RTC
&timedate_item,
#endif
&show_info_item, &show_credits_item, &show_runtime_item,
#if CONFIG_RTC == 0
&sleep_timer_call,
#endif
&debug_menu_item);
/* INFO MENU */
/***********************************/
/***********************************/
/* MAIN MENU */
#ifdef HAVE_LCD_CHARCELLS
static int mainmenu_callback(int action,const struct menu_item_ex *this_item)
{
(void)this_item;
switch (action)
{
case ACTION_ENTER_MENUITEM:
status_set_param(true);
break;
case ACTION_EXIT_MENUITEM:
status_set_param(false);
break;
}
return action;
}
#else
#define mainmenu_callback NULL
#endif
MAKE_MENU(main_menu_, ID2P(LANG_SETTINGS), mainmenu_callback,
Icon_Submenu_Entered,
&sound_settings,
&playback_settings,
&settings_menu_item, &theme_menu,
#ifdef HAVE_RECORDING
&recording_settings,
#endif
&manage_settings,
);
/* MAIN MENU */
/***********************************/