diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2008-12-01 09:28:14 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2008-12-01 09:28:14 +0000 |
commit | c7fec13fd87d80bb38e71e84462f0081b0678db0 (patch) | |
tree | a12ddf829ab3d8167fdd2da9ee74e5988a80eda3 /apps/menus/time_menu.c | |
parent | a783453ff91c19d5d9302a9479363a9a5f985cdf (diff) | |
download | rockbox-c7fec13fd87d80bb38e71e84462f0081b0678db0.tar.gz rockbox-c7fec13fd87d80bb38e71e84462f0081b0678db0.zip |
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
Diffstat (limited to 'apps/menus/time_menu.c')
-rw-r--r-- | apps/menus/time_menu.c | 294 |
1 files changed, 294 insertions, 0 deletions
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: main_menu.c 17985 2008-07-08 02:30:58Z jdgordon $ | ||
9 | * | ||
10 | * Copyright (C) 2007 Jonathan Gordon | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdbool.h> | ||
23 | #include <stddef.h> | ||
24 | #include <limits.h> | ||
25 | #include "config.h" | ||
26 | #include "string.h" | ||
27 | #include "sprintf.h" | ||
28 | #include "lang.h" | ||
29 | #include "action.h" | ||
30 | #include "settings.h" | ||
31 | #include "powermgmt.h" | ||
32 | #include "menu.h" | ||
33 | #include "misc.h" | ||
34 | #include "exported_menus.h" | ||
35 | #include "yesno.h" | ||
36 | #include "keyboard.h" | ||
37 | #include "talk.h" | ||
38 | #include "splash.h" | ||
39 | #include "version.h" | ||
40 | #include "time.h" | ||
41 | #include "viewport.h" | ||
42 | #include "list.h" | ||
43 | #include "alarm_menu.h" | ||
44 | #include "screens.h" | ||
45 | |||
46 | static int timedate_set(void) | ||
47 | { | ||
48 | struct tm tm; | ||
49 | int result; | ||
50 | |||
51 | /* Make a local copy of the time struct */ | ||
52 | memcpy(&tm, get_time(), sizeof(struct tm)); | ||
53 | |||
54 | /* do some range checks */ | ||
55 | /* This prevents problems with time/date setting after a power loss */ | ||
56 | if (!valid_time(&tm)) | ||
57 | { | ||
58 | /* Macros to convert a 2-digit string to a decimal constant. | ||
59 | (YEAR), MONTH and DAY are set by the date command, which outputs | ||
60 | DAY as 00..31 and MONTH as 01..12. The leading zero would lead to | ||
61 | misinterpretation as an octal constant. */ | ||
62 | #define S100(x) 1 ## x | ||
63 | #define C2DIG2DEC(x) (S100(x)-100) | ||
64 | |||
65 | tm.tm_hour = 0; | ||
66 | tm.tm_min = 0; | ||
67 | tm.tm_sec = 0; | ||
68 | tm.tm_mday = C2DIG2DEC(DAY); | ||
69 | tm.tm_mon = C2DIG2DEC(MONTH)-1; | ||
70 | tm.tm_wday = 1; | ||
71 | tm.tm_year = YEAR-1900; | ||
72 | } | ||
73 | |||
74 | result = (int)set_time_screen(str(LANG_SET_TIME), &tm); | ||
75 | |||
76 | if(tm.tm_year != -1) { | ||
77 | set_time(&tm); | ||
78 | } | ||
79 | return result; | ||
80 | } | ||
81 | |||
82 | MENUITEM_FUNCTION(time_set, 0, ID2P(LANG_SET_TIME), | ||
83 | timedate_set, NULL, NULL, Icon_NOICON); | ||
84 | MENUITEM_SETTING(timeformat, &global_settings.timeformat, NULL); | ||
85 | |||
86 | /* in main_menu.c */ | ||
87 | extern const struct menu_item_ex sleep_timer_call; | ||
88 | |||
89 | #ifdef HAVE_RTC_ALARM | ||
90 | MENUITEM_FUNCTION(alarm_screen_call, 0, ID2P(LANG_ALARM_MOD_ALARM_MENU), | ||
91 | (menu_function)alarm_screen, NULL, NULL, Icon_NOICON); | ||
92 | #if CONFIG_TUNER || defined(HAVE_RECORDING) | ||
93 | |||
94 | #if CONFIG_TUNER && !defined(HAVE_RECORDING) | ||
95 | /* This need only be shown if we dont have recording, because if we do | ||
96 | then always show the setting item, because there will always be at least | ||
97 | 2 items */ | ||
98 | static int alarm_callback(int action,const struct menu_item_ex *this_item) | ||
99 | { | ||
100 | (void)this_item; | ||
101 | switch (action) | ||
102 | { | ||
103 | case ACTION_REQUEST_MENUITEM: | ||
104 | if (radio_hardware_present() == 0) | ||
105 | return ACTION_EXIT_MENUITEM; | ||
106 | break; | ||
107 | } | ||
108 | return action; | ||
109 | } | ||
110 | #else | ||
111 | #define alarm_callback NULL | ||
112 | #endif /* CONFIG_TUNER && !HAVE_RECORDING */ | ||
113 | /* have to do this manually because the setting screen | ||
114 | doesnt handle variable item count */ | ||
115 | static int alarm_setting(void) | ||
116 | { | ||
117 | struct opt_items items[ALARM_START_COUNT]; | ||
118 | int i = 0; | ||
119 | items[i].string = str(LANG_RESUME_PLAYBACK); | ||
120 | items[i].voice_id = LANG_RESUME_PLAYBACK; | ||
121 | i++; | ||
122 | #if CONFIG_TUNER | ||
123 | if (radio_hardware_present()) | ||
124 | { | ||
125 | items[i].string = str(LANG_FM_RADIO); | ||
126 | items[i].voice_id = LANG_FM_RADIO; | ||
127 | i++; | ||
128 | } | ||
129 | #endif | ||
130 | #ifdef HAVE_RECORDING | ||
131 | items[i].string = str(LANG_RECORDING); | ||
132 | items[i].voice_id = LANG_RECORDING; | ||
133 | i++; | ||
134 | #endif | ||
135 | return set_option(str(LANG_ALARM_WAKEUP_SCREEN), | ||
136 | &global_settings.alarm_wake_up_screen, | ||
137 | INT, items, i, NULL); | ||
138 | } | ||
139 | |||
140 | MENUITEM_FUNCTION(alarm_wake_up_screen, 0, ID2P(LANG_ALARM_WAKEUP_SCREEN), | ||
141 | alarm_setting, NULL, alarm_callback, Icon_Menu_setting); | ||
142 | #endif /* CONFIG_TUNER || defined(HAVE_RECORDING) */ | ||
143 | |||
144 | #endif /* HAVE_RTC_ALARM */ | ||
145 | static void talk_timedate(void) | ||
146 | { | ||
147 | struct tm *tm = get_time(); | ||
148 | if (!global_settings.talk_menu) | ||
149 | return; | ||
150 | talk_id(VOICE_CURRENT_TIME, false); | ||
151 | if (valid_time(tm)) | ||
152 | { | ||
153 | talk_time(tm, true); | ||
154 | talk_date(get_time(), true); | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | talk_id(LANG_UNKNOWN, true); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static void draw_timedate(struct viewport *vp, struct screen *display) | ||
163 | { | ||
164 | struct tm *tm = get_time(); | ||
165 | int w, line; | ||
166 | char time[16], date[16]; | ||
167 | if (vp->height == 0) | ||
168 | return; | ||
169 | display->set_viewport(vp); | ||
170 | display->clear_viewport(); | ||
171 | if (viewport_get_nb_lines(vp) > 3) | ||
172 | line = 1; | ||
173 | else | ||
174 | line = 0; | ||
175 | |||
176 | if (valid_time(tm)) | ||
177 | { | ||
178 | snprintf(time, 16, "%02d:%02d:%02d %s", | ||
179 | global_settings.timeformat == 0 ? tm->tm_hour : | ||
180 | ((tm->tm_hour + 11) % 12) + 1, | ||
181 | tm->tm_min, | ||
182 | tm->tm_sec, | ||
183 | global_settings.timeformat == 0 ? "" : | ||
184 | tm->tm_hour>11 ? "P" : "A"); | ||
185 | snprintf(date, 16, "%s %d %d", | ||
186 | str(LANG_MONTH_JANUARY + tm->tm_mon), | ||
187 | tm->tm_mday, | ||
188 | tm->tm_year+1900); | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | snprintf(time, 16, "%s", "--:--:--"); | ||
193 | snprintf(date, 16, "%s", str(LANG_UNKNOWN)); | ||
194 | } | ||
195 | display->getstringsize(time, &w, NULL); | ||
196 | if (w > vp->width) | ||
197 | display->puts_scroll(0, line, time); | ||
198 | else | ||
199 | display->putsxy((vp->width - w)/2, line*font_get(vp->font)->height, time); | ||
200 | line++; | ||
201 | |||
202 | display->getstringsize(date, &w, NULL); | ||
203 | if (w > vp->width) | ||
204 | display->puts_scroll(0, line, date); | ||
205 | else | ||
206 | display->putsxy((vp->width - w)/2, line*font_get(vp->font)->height, date); | ||
207 | display->update_viewport(); | ||
208 | } | ||
209 | |||
210 | struct viewport clock[NB_SCREENS], menu[NB_SCREENS]; | ||
211 | int time_menu_callback(int action, | ||
212 | const struct menu_item_ex *this_item) | ||
213 | { | ||
214 | (void)this_item; | ||
215 | int i; | ||
216 | static int last_redraw = 0; | ||
217 | bool redraw = false; | ||
218 | |||
219 | if (TIME_BEFORE(last_redraw+HZ/2, current_tick)) | ||
220 | redraw = true; | ||
221 | switch (action) | ||
222 | { | ||
223 | case ACTION_REDRAW: | ||
224 | redraw = true; | ||
225 | break; | ||
226 | case ACTION_STD_CONTEXT: | ||
227 | talk_timedate(); | ||
228 | action = ACTION_NONE; | ||
229 | break; | ||
230 | } | ||
231 | if (redraw) | ||
232 | { | ||
233 | last_redraw = current_tick; | ||
234 | FOR_NB_SCREENS(i) | ||
235 | draw_timedate(&clock[i], &screens[i]); | ||
236 | } | ||
237 | return action; | ||
238 | } | ||
239 | |||
240 | |||
241 | MAKE_MENU(time_menu, ID2P(LANG_TIME_MENU), time_menu_callback, Icon_NOICON, | ||
242 | &time_set, &sleep_timer_call, | ||
243 | #ifdef HAVE_RTC_ALARM | ||
244 | &alarm_screen_call, | ||
245 | #if defined(HAVE_RECORDING) || CONFIG_TUNER | ||
246 | &alarm_wake_up_screen, | ||
247 | #endif | ||
248 | #endif | ||
249 | &timeformat); | ||
250 | |||
251 | int time_screen(void* ignored) | ||
252 | { | ||
253 | (void)ignored; | ||
254 | int i, nb_lines, font_h; | ||
255 | |||
256 | FOR_NB_SCREENS(i) | ||
257 | { | ||
258 | viewport_set_defaults(&clock[i], i); | ||
259 | #ifdef HAVE_BUTTONBAR | ||
260 | if (global_settings.buttonbar) | ||
261 | { | ||
262 | clock[i].height -= BUTTONBAR_HEIGHT; | ||
263 | } | ||
264 | #endif | ||
265 | nb_lines = viewport_get_nb_lines(&clock[i]); | ||
266 | menu[i] = clock[i]; | ||
267 | font_h = font_get(clock[i].font)->height; | ||
268 | if (nb_lines > 3) | ||
269 | { | ||
270 | if (nb_lines >= 5) | ||
271 | { | ||
272 | clock[i].height = 3*font_h; | ||
273 | if (nb_lines > 5) | ||
274 | clock[i].height += font_h; | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | clock[i].height = 2*font_h; | ||
279 | } | ||
280 | } | ||
281 | else /* disable the clock drawing */ | ||
282 | clock[i].height = 0; | ||
283 | menu[i].y = clock[i].y + clock[i].height; | ||
284 | menu[i].height = screens[i].lcdheight - menu[i].y; | ||
285 | #ifdef HAVE_BUTTONBAR | ||
286 | if (global_settings.buttonbar) | ||
287 | menu[i].height -= BUTTONBAR_HEIGHT; | ||
288 | #endif | ||
289 | screens[i].clear_display(); | ||
290 | draw_timedate(&clock[i], &screens[i]); | ||
291 | screens[i].update(); | ||
292 | } | ||
293 | return do_menu(&time_menu, NULL, menu, false); | ||
294 | } | ||