From c7fec13fd87d80bb38e71e84462f0081b0678db0 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Mon, 1 Dec 2008 09:28:14 +0000 Subject: [PATCH] FS#9173 - move all time/clock related settings in the menus into system > "time & date" (this includes sleep timer, alarm settings) The time/date dispaly has been moved out of the "rockbox info" screen and into this screen also (only displayed if there is at least 3 lines of text on the screen though) The time/date is talked in this screen by pressing the usual context-menu button (usually long-select) Targets without a RTC are not changed (i.e sleep timer isnt moved) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19282 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 3 + apps/menu.c | 3 + apps/menus/main_menu.c | 101 +++---------- apps/menus/settings_menu.c | 109 -------------- apps/menus/time_menu.c | 294 +++++++++++++++++++++++++++++++++++++ apps/root_menu.c | 1 + apps/root_menu.h | 1 + 7 files changed, 320 insertions(+), 192 deletions(-) create mode 100644 apps/menus/time_menu.c diff --git a/apps/SOURCES b/apps/SOURCES index 84f2eecbe2..2ea41c290a 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -29,6 +29,9 @@ menus/recording_menu.c #endif menus/settings_menu.c menus/sound_menu.c +#if CONFIG_RTC +menus/time_menu.c +#endif misc.c mp3data.c onplay.c diff --git a/apps/menu.c b/apps/menu.c index 8edec58587..3fb1749073 100644 --- a/apps/menu.c +++ b/apps/menu.c @@ -433,6 +433,9 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, redraw_lists = false; if (!hide_bars) { +#ifdef HAVE_BUTTONBAR + gui_buttonbar_draw(&buttonbar); +#endif gui_syncstatusbar_draw(&statusbars, true); } action = get_action(CONTEXT_MAINMENU, diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c index 77322c6ef4..41e25e30f5 100644 --- a/apps/menus/main_menu.c +++ b/apps/menus/main_menu.c @@ -147,10 +147,6 @@ enum infoscreenorder INFO_ALBUMART, #endif INFO_VERSION, -#if CONFIG_RTC - INFO_DATE, - INFO_TIME, -#endif INFO_COUNT }; @@ -165,9 +161,6 @@ static char* info_getname(int selected_item, void *data, char *buffer, size_t buffer_len) { struct info_data *info = (struct info_data*)data; -#if CONFIG_RTC - struct tm *tm; -#endif char s1[32]; #ifdef HAVE_MULTIVOLUME char s2[32]; @@ -189,39 +182,7 @@ static char* info_getname(int selected_item, void *data, snprintf(buffer, buffer_len, "%s: %s", str(LANG_VERSION), appsversion); break; -#if CONFIG_RTC - case INFO_TIME: - tm = get_time(); - if (valid_time(tm)) - { - snprintf(buffer, buffer_len, "%02d:%02d:%02d %s", - global_settings.timeformat == 0 ? tm->tm_hour : - ((tm->tm_hour + 11) % 12) + 1, - tm->tm_min, - tm->tm_sec, - global_settings.timeformat == 0 ? "" : - tm->tm_hour>11 ? "P" : "A"); - } - else - { - strncpy(buffer, "--:--:--", buffer_len); - } - break; - case INFO_DATE: - tm = get_time(); - if (valid_time(tm)) - { - snprintf(buffer, buffer_len, "%s %d %d", - str(LANG_MONTH_JANUARY + tm->tm_mon), - tm->tm_mday, - tm->tm_year+1900); - } - else - { - strncpy(buffer, str(LANG_UNKNOWN), buffer_len); - } - break; -#endif + case INFO_BUFFER: /* buffer */ { long kib = (audiobufend - audiobuf) / 1024; /* to KiB */ @@ -305,41 +266,13 @@ static int info_speak_item(int selected_item, void * data) { struct info_data *info = (struct info_data*)data; -#if CONFIG_RTC - struct tm *tm; -#endif - switch (selected_item) { case INFO_VERSION: /* version */ talk_id(LANG_VERSION, false); talk_spell(appsversion, true); break; -#if CONFIG_RTC - case INFO_TIME: - tm = get_time(); - talk_id(VOICE_CURRENT_TIME, false); - if (valid_time(tm)) - { - talk_time(tm, true); - } - else - { - talk_id(LANG_UNKNOWN, true); - } - break; - case INFO_DATE: - tm = get_time(); - if (valid_time(tm)) - { - talk_date(get_time(), true); - } - else - { - talk_id(LANG_UNKNOWN, true); - } - break; -#endif + case INFO_BUFFER: /* buffer */ { talk_id(LANG_BUFFER_STAT, false); @@ -447,18 +380,6 @@ static int info_action_callback(int action, struct gui_synclist *lists) gui_synclist_speak_item(lists); return ACTION_REDRAW; } -#if CONFIG_RTC - else if (action == ACTION_NONE) - { - static int last_redraw = 0; - if (gui_synclist_item_is_onscreen(lists, 0, INFO_TIME) - && TIME_AFTER(current_tick, last_redraw + HZ*5)) - { - last_redraw = current_tick; - return ACTION_REDRAW; - } - } -#endif return action; } static bool show_info(void) @@ -501,16 +422,24 @@ static void sleep_timer_set(int minutes) set_sleep_timer(minutes * 60); } -static int sleep_timer(void) +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), @@ -519,8 +448,14 @@ 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, - &sleep_timer_call, &debug_menu_item); +#if CONFIG_RTC == 0 + &sleep_timer_call, +#endif + &debug_menu_item); /* INFO MENU */ /***********************************/ diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c index ebba295570..6bb032d169 100644 --- a/apps/menus/settings_menu.c +++ b/apps/menus/settings_menu.c @@ -212,109 +212,9 @@ MAKE_MENU(disk_menu, ID2P(LANG_DISK_MENU), 0, Icon_NOICON, ); #endif -/* Time & Date */ -#if CONFIG_RTC -static int timedate_set(void) -{ - struct tm tm; - int result; - - /* Make a local copy of the time struct */ - memcpy(&tm, get_time(), sizeof(struct tm)); - - /* do some range checks */ - /* This prevents problems with time/date setting after a power loss */ - if (!valid_time(&tm)) - { -/* Macros to convert a 2-digit string to a decimal constant. - (YEAR), MONTH and DAY are set by the date command, which outputs - DAY as 00..31 and MONTH as 01..12. The leading zero would lead to - misinterpretation as an octal constant. */ -#define S100(x) 1 ## x -#define C2DIG2DEC(x) (S100(x)-100) - - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mday = C2DIG2DEC(DAY); - tm.tm_mon = C2DIG2DEC(MONTH)-1; - tm.tm_wday = 1; - tm.tm_year = YEAR-1900; - } - - result = (int)set_time_screen(str(LANG_SET_TIME), &tm); - - if(tm.tm_year != -1) { - set_time(&tm); - } - return result; -} - -MENUITEM_FUNCTION(time_set, 0, ID2P(LANG_SET_TIME), - timedate_set, NULL, NULL, Icon_NOICON); -MENUITEM_SETTING(timeformat, &global_settings.timeformat, NULL); -MAKE_MENU(time_menu, ID2P(LANG_TIME_MENU), 0, Icon_NOICON, &time_set, &timeformat); -#endif - /* System menu */ MENUITEM_SETTING(poweroff, &global_settings.poweroff, NULL); -#ifdef HAVE_RTC_ALARM -MENUITEM_FUNCTION(alarm_screen_call, 0, ID2P(LANG_ALARM_MOD_ALARM_MENU), - (menu_function)alarm_screen, NULL, NULL, Icon_NOICON); -#if CONFIG_TUNER || defined(HAVE_RECORDING) - -#if CONFIG_TUNER && !defined(HAVE_RECORDING) -/* This need only be shown if we dont have recording, because if we do - then always show the setting item, because there will always be at least - 2 items */ -static int alarm_callback(int action,const struct menu_item_ex *this_item) -{ - (void)this_item; - switch (action) - { - case ACTION_REQUEST_MENUITEM: - if (radio_hardware_present() == 0) - return ACTION_EXIT_MENUITEM; - break; - } - return action; -} -#else -#define alarm_callback NULL -#endif /* CONFIG_TUNER && !HAVE_RECORDING */ -/* have to do this manually because the setting screen - doesnt handle variable item count */ -static int alarm_setting(void) -{ - struct opt_items items[ALARM_START_COUNT]; - int i = 0; - items[i].string = str(LANG_RESUME_PLAYBACK); - items[i].voice_id = LANG_RESUME_PLAYBACK; - i++; -#if CONFIG_TUNER - if (radio_hardware_present()) - { - items[i].string = str(LANG_FM_RADIO); - items[i].voice_id = LANG_FM_RADIO; - i++; - } -#endif -#ifdef HAVE_RECORDING - items[i].string = str(LANG_RECORDING); - items[i].voice_id = LANG_RECORDING; - i++; -#endif - return set_option(str(LANG_ALARM_WAKEUP_SCREEN), - &global_settings.alarm_wake_up_screen, - INT, items, i, NULL); -} - -MENUITEM_FUNCTION(alarm_wake_up_screen, 0, ID2P(LANG_ALARM_WAKEUP_SCREEN), - alarm_setting, NULL, alarm_callback, Icon_Menu_setting); -#endif /* CONFIG_TUNER || defined(HAVE_RECORDING) */ -#endif /* HAVE_RTC_ALARM */ - /* Limits menu */ MENUITEM_SETTING(max_files_in_dir, &global_settings.max_files_in_dir, NULL); MENUITEM_SETTING(max_files_in_playlist, &global_settings.max_files_in_playlist, NULL); @@ -377,17 +277,8 @@ MAKE_MENU(system_menu, ID2P(LANG_SYSTEM), #endif #if defined(HAVE_DIRCACHE) || defined(HAVE_DISK_STORAGE) &disk_menu, -#endif -#if CONFIG_RTC - &time_menu, #endif &poweroff, -#ifdef HAVE_RTC_ALARM - &alarm_screen_call, -#if defined(HAVE_RECORDING) || CONFIG_TUNER - &alarm_wake_up_screen, -#endif -#endif &limits_menu, #if CONFIG_CODEC == MAS3507D &line_in, diff --git a/apps/menus/time_menu.c b/apps/menus/time_menu.c new file mode 100644 index 0000000000..02c6ae4ffe --- /dev/null +++ b/apps/menus/time_menu.c @@ -0,0 +1,294 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: main_menu.c 17985 2008-07-08 02:30:58Z jdgordon $ + * + * 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 +#include +#include +#include "config.h" +#include "string.h" +#include "sprintf.h" +#include "lang.h" +#include "action.h" +#include "settings.h" +#include "powermgmt.h" +#include "menu.h" +#include "misc.h" +#include "exported_menus.h" +#include "yesno.h" +#include "keyboard.h" +#include "talk.h" +#include "splash.h" +#include "version.h" +#include "time.h" +#include "viewport.h" +#include "list.h" +#include "alarm_menu.h" +#include "screens.h" + +static int timedate_set(void) +{ + struct tm tm; + int result; + + /* Make a local copy of the time struct */ + memcpy(&tm, get_time(), sizeof(struct tm)); + + /* do some range checks */ + /* This prevents problems with time/date setting after a power loss */ + if (!valid_time(&tm)) + { +/* Macros to convert a 2-digit string to a decimal constant. + (YEAR), MONTH and DAY are set by the date command, which outputs + DAY as 00..31 and MONTH as 01..12. The leading zero would lead to + misinterpretation as an octal constant. */ +#define S100(x) 1 ## x +#define C2DIG2DEC(x) (S100(x)-100) + + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_mday = C2DIG2DEC(DAY); + tm.tm_mon = C2DIG2DEC(MONTH)-1; + tm.tm_wday = 1; + tm.tm_year = YEAR-1900; + } + + result = (int)set_time_screen(str(LANG_SET_TIME), &tm); + + if(tm.tm_year != -1) { + set_time(&tm); + } + return result; +} + +MENUITEM_FUNCTION(time_set, 0, ID2P(LANG_SET_TIME), + timedate_set, NULL, NULL, Icon_NOICON); +MENUITEM_SETTING(timeformat, &global_settings.timeformat, NULL); + +/* in main_menu.c */ +extern const struct menu_item_ex sleep_timer_call; + +#ifdef HAVE_RTC_ALARM +MENUITEM_FUNCTION(alarm_screen_call, 0, ID2P(LANG_ALARM_MOD_ALARM_MENU), + (menu_function)alarm_screen, NULL, NULL, Icon_NOICON); +#if CONFIG_TUNER || defined(HAVE_RECORDING) + +#if CONFIG_TUNER && !defined(HAVE_RECORDING) +/* This need only be shown if we dont have recording, because if we do + then always show the setting item, because there will always be at least + 2 items */ +static int alarm_callback(int action,const struct menu_item_ex *this_item) +{ + (void)this_item; + switch (action) + { + case ACTION_REQUEST_MENUITEM: + if (radio_hardware_present() == 0) + return ACTION_EXIT_MENUITEM; + break; + } + return action; +} +#else +#define alarm_callback NULL +#endif /* CONFIG_TUNER && !HAVE_RECORDING */ +/* have to do this manually because the setting screen + doesnt handle variable item count */ +static int alarm_setting(void) +{ + struct opt_items items[ALARM_START_COUNT]; + int i = 0; + items[i].string = str(LANG_RESUME_PLAYBACK); + items[i].voice_id = LANG_RESUME_PLAYBACK; + i++; +#if CONFIG_TUNER + if (radio_hardware_present()) + { + items[i].string = str(LANG_FM_RADIO); + items[i].voice_id = LANG_FM_RADIO; + i++; + } +#endif +#ifdef HAVE_RECORDING + items[i].string = str(LANG_RECORDING); + items[i].voice_id = LANG_RECORDING; + i++; +#endif + return set_option(str(LANG_ALARM_WAKEUP_SCREEN), + &global_settings.alarm_wake_up_screen, + INT, items, i, NULL); +} + +MENUITEM_FUNCTION(alarm_wake_up_screen, 0, ID2P(LANG_ALARM_WAKEUP_SCREEN), + alarm_setting, NULL, alarm_callback, Icon_Menu_setting); +#endif /* CONFIG_TUNER || defined(HAVE_RECORDING) */ + +#endif /* HAVE_RTC_ALARM */ +static void talk_timedate(void) +{ + struct tm *tm = get_time(); + if (!global_settings.talk_menu) + return; + talk_id(VOICE_CURRENT_TIME, false); + if (valid_time(tm)) + { + talk_time(tm, true); + talk_date(get_time(), true); + } + else + { + talk_id(LANG_UNKNOWN, true); + } +} + +static void draw_timedate(struct viewport *vp, struct screen *display) +{ + struct tm *tm = get_time(); + int w, line; + char time[16], date[16]; + if (vp->height == 0) + return; + display->set_viewport(vp); + display->clear_viewport(); + if (viewport_get_nb_lines(vp) > 3) + line = 1; + else + line = 0; + + if (valid_time(tm)) + { + snprintf(time, 16, "%02d:%02d:%02d %s", + global_settings.timeformat == 0 ? tm->tm_hour : + ((tm->tm_hour + 11) % 12) + 1, + tm->tm_min, + tm->tm_sec, + global_settings.timeformat == 0 ? "" : + tm->tm_hour>11 ? "P" : "A"); + snprintf(date, 16, "%s %d %d", + str(LANG_MONTH_JANUARY + tm->tm_mon), + tm->tm_mday, + tm->tm_year+1900); + } + else + { + snprintf(time, 16, "%s", "--:--:--"); + snprintf(date, 16, "%s", str(LANG_UNKNOWN)); + } + display->getstringsize(time, &w, NULL); + if (w > vp->width) + display->puts_scroll(0, line, time); + else + display->putsxy((vp->width - w)/2, line*font_get(vp->font)->height, time); + line++; + + display->getstringsize(date, &w, NULL); + if (w > vp->width) + display->puts_scroll(0, line, date); + else + display->putsxy((vp->width - w)/2, line*font_get(vp->font)->height, date); + display->update_viewport(); +} + +struct viewport clock[NB_SCREENS], menu[NB_SCREENS]; +int time_menu_callback(int action, + const struct menu_item_ex *this_item) +{ + (void)this_item; + int i; + static int last_redraw = 0; + bool redraw = false; + + if (TIME_BEFORE(last_redraw+HZ/2, current_tick)) + redraw = true; + switch (action) + { + case ACTION_REDRAW: + redraw = true; + break; + case ACTION_STD_CONTEXT: + talk_timedate(); + action = ACTION_NONE; + break; + } + if (redraw) + { + last_redraw = current_tick; + FOR_NB_SCREENS(i) + draw_timedate(&clock[i], &screens[i]); + } + return action; +} + + +MAKE_MENU(time_menu, ID2P(LANG_TIME_MENU), time_menu_callback, Icon_NOICON, + &time_set, &sleep_timer_call, +#ifdef HAVE_RTC_ALARM + &alarm_screen_call, +#if defined(HAVE_RECORDING) || CONFIG_TUNER + &alarm_wake_up_screen, +#endif +#endif + &timeformat); + +int time_screen(void* ignored) +{ + (void)ignored; + int i, nb_lines, font_h; + + FOR_NB_SCREENS(i) + { + viewport_set_defaults(&clock[i], i); +#ifdef HAVE_BUTTONBAR + if (global_settings.buttonbar) + { + clock[i].height -= BUTTONBAR_HEIGHT; + } +#endif + nb_lines = viewport_get_nb_lines(&clock[i]); + menu[i] = clock[i]; + font_h = font_get(clock[i].font)->height; + if (nb_lines > 3) + { + if (nb_lines >= 5) + { + clock[i].height = 3*font_h; + if (nb_lines > 5) + clock[i].height += font_h; + } + else + { + clock[i].height = 2*font_h; + } + } + else /* disable the clock drawing */ + clock[i].height = 0; + menu[i].y = clock[i].y + clock[i].height; + menu[i].height = screens[i].lcdheight - menu[i].y; +#ifdef HAVE_BUTTONBAR + if (global_settings.buttonbar) + menu[i].height -= BUTTONBAR_HEIGHT; +#endif + screens[i].clear_display(); + draw_timedate(&clock[i], &screens[i]); + screens[i].update(); + } + return do_menu(&time_menu, NULL, menu, false); +} diff --git a/apps/root_menu.c b/apps/root_menu.c index 4b9be39a8c..9d4f256370 100644 --- a/apps/root_menu.c +++ b/apps/root_menu.c @@ -310,6 +310,7 @@ static int plugins_menu(void* param) } return retval; } +int time_screen(void* ignored); /* These are all static const'd from apps/menus/ *.c so little hack so we can use them */ diff --git a/apps/root_menu.h b/apps/root_menu.h index c4cb466c99..dbc75efbca 100644 --- a/apps/root_menu.h +++ b/apps/root_menu.h @@ -49,6 +49,7 @@ enum { be the "start screen" after a boot up. The setting in settings_list.c will need editing if this is the case. */ GO_TO_BROWSEPLUGINS, + GO_TO_TIMESCREEN, }; extern const struct menu_item_ex root_menu_;