diff options
Diffstat (limited to 'apps/menus')
-rw-r--r-- | apps/menus/main_menu.c | 321 |
1 files changed, 148 insertions, 173 deletions
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c index 1940c14511..601ecc95b6 100644 --- a/apps/menus/main_menu.c +++ b/apps/menus/main_menu.c | |||
@@ -120,217 +120,192 @@ static bool show_credits(void) | |||
120 | #else | 120 | #else |
121 | #define SIZE_FMT "%s %s" | 121 | #define SIZE_FMT "%s %s" |
122 | #endif | 122 | #endif |
123 | 123 | struct info_data { | |
124 | static bool show_info(void) | 124 | bool new_data; |
125 | { | 125 | unsigned long size; |
126 | char s[64], s1[32]; | 126 | unsigned long free; |
127 | unsigned long size, free; | ||
128 | long buflen = ((audiobufend - audiobuf) * 2) / 2097; /* avoid overflow */ | ||
129 | int key; | ||
130 | int i; | ||
131 | bool done = false; | ||
132 | bool new_info = true; | ||
133 | #ifdef HAVE_MULTIVOLUME | 127 | #ifdef HAVE_MULTIVOLUME |
134 | char s2[32]; | 128 | unsigned long size2; |
135 | unsigned long size2, free2; | 129 | unsigned long free2; |
136 | #endif | 130 | #endif |
137 | #ifdef HAVE_LCD_CHARCELLS | 131 | }; |
138 | int page = 0; | 132 | static char* info_getname(int selected_item, void * data, char *buffer) |
139 | #endif | 133 | { |
140 | 134 | struct info_data *info = (struct info_data*)data; | |
141 | const unsigned char *kbyte_units[] = { | 135 | const unsigned char *kbyte_units[] = { |
142 | ID2P(LANG_KILOBYTE), | 136 | ID2P(LANG_KILOBYTE), |
143 | ID2P(LANG_MEGABYTE), | 137 | ID2P(LANG_MEGABYTE), |
144 | ID2P(LANG_GIGABYTE) | 138 | ID2P(LANG_GIGABYTE) |
145 | }; | 139 | }; |
146 | #if defined(HAVE_LCD_BITMAP) | 140 | char s1[32]; |
147 | FOR_NB_SCREENS(i) | ||
148 | screens[i].setmargins(0, 0); | ||
149 | #endif | ||
150 | while (!done) | ||
151 | { | ||
152 | int y=0; | ||
153 | |||
154 | if (new_info) | ||
155 | { | ||
156 | fat_size( IF_MV2(0,) &size, &free ); | ||
157 | #ifdef HAVE_MULTIVOLUME | 141 | #ifdef HAVE_MULTIVOLUME |
158 | if (fat_ismounted(1)) | 142 | char s2[32]; |
159 | fat_size( 1, &size2, &free2 ); | ||
160 | else | ||
161 | size2 = 0; | ||
162 | #endif | ||
163 | |||
164 | if (global_settings.talk_menu) | ||
165 | { | ||
166 | /* say whatever is reasonable, no real connection to the screen */ | ||
167 | bool enqueue = false; /* enqueue all but the first */ | ||
168 | if (battery_level() >= 0) | ||
169 | { | ||
170 | talk_id(LANG_BATTERY_TIME, enqueue); | ||
171 | enqueue = true; | ||
172 | talk_value(battery_level(), UNIT_PERCENT, true); | ||
173 | #if CONFIG_CHARGING >= CHARGING_MONITOR | ||
174 | if (charge_state == CHARGING) | ||
175 | talk_id(LANG_BATTERY_CHARGE, true); | ||
176 | #if CONFIG_CHARGING == CHARGING_CONTROL | ||
177 | else if (charge_state == TOPOFF) | ||
178 | talk_id(LANG_BATTERY_TOPOFF_CHARGE, true); | ||
179 | #endif | ||
180 | else if (charge_state == TRICKLE) | ||
181 | talk_id(LANG_BATTERY_TRICKLE_CHARGE, true); | ||
182 | #endif | 143 | #endif |
183 | } | 144 | if (info->new_data) |
184 | 145 | { | |
185 | talk_id(LANG_DISK_FREE_INFO, enqueue); | 146 | fat_size( IF_MV2(0,) &info->size, &info->free ); |
186 | #ifdef HAVE_MULTIVOLUME | 147 | #ifdef HAVE_MULTIVOLUME |
187 | talk_id(LANG_DISK_NAME_INTERNAL, true); | 148 | if (fat_ismounted(1)) |
188 | output_dyn_value(NULL, 0, free, kbyte_units, true); | 149 | fat_size( 1, &info->size2, &info->free2 ); |
189 | if (size2) | 150 | else |
190 | { | 151 | info->size2 = 0; |
191 | talk_id(LANG_DISK_NAME_MMC, true); | ||
192 | output_dyn_value(NULL, 0, free2, kbyte_units, true); | ||
193 | } | ||
194 | #else | ||
195 | output_dyn_value(NULL, 0, free, kbyte_units, true); | ||
196 | #endif | ||
197 | #if CONFIG_RTC | ||
198 | talk_date_time(get_time(), true); | ||
199 | #endif | ||
200 | new_info = false; | ||
201 | } | ||
202 | } | ||
203 | FOR_NB_SCREENS(i) | ||
204 | { | ||
205 | screens[i].clear_display(); | ||
206 | #ifdef HAVE_LCD_BITMAP | ||
207 | screens[i].puts(0, y, str(LANG_ROCKBOX_INFO)); | ||
208 | #endif | ||
209 | } | ||
210 | #ifdef HAVE_LCD_BITMAP | ||
211 | y++; | ||
212 | #endif | ||
213 | #ifdef HAVE_LCD_CHARCELLS | ||
214 | if (page == 0) | ||
215 | #endif | ||
216 | { | ||
217 | snprintf(s, sizeof(s), "%s: %s", str(LANG_VERSION), appsversion); | ||
218 | FOR_NB_SCREENS(i) | ||
219 | screens[i].puts_scroll(0, y, (unsigned char *)s); | ||
220 | #ifdef HAVE_LCD_BITMAP | ||
221 | y += 2; | ||
222 | #endif | ||
223 | } | ||
224 | |||
225 | #ifdef HAVE_LCD_CHARCELLS | ||
226 | if (page == 1) | ||
227 | #endif | 152 | #endif |
153 | info->new_data = false; | ||
154 | } | ||
155 | switch (selected_item) | ||
156 | { | ||
157 | case 0: | ||
158 | snprintf(buffer, MAX_PATH, "%s: %s", | ||
159 | str(LANG_VERSION), appsversion); | ||
160 | break; | ||
161 | case 1: | ||
162 | return ""; | ||
163 | case 2: /* buffer */ | ||
228 | { | 164 | { |
165 | long buflen = ((audiobufend - audiobuf) * 2) / 2097; /* avoid overflow */ | ||
229 | int integer = buflen / 1000; | 166 | int integer = buflen / 1000; |
230 | int decimal = buflen % 1000; | 167 | int decimal = buflen % 1000; |
231 | 168 | ||
232 | snprintf(s, sizeof(s), (char *)str(LANG_BUFFER_STAT), | 169 | snprintf(buffer, MAX_PATH, (char *)str(LANG_BUFFER_STAT), |
233 | integer, decimal); | 170 | integer, decimal); |
234 | 171 | } | |
235 | FOR_NB_SCREENS(i) | 172 | break; |
236 | screens[i].puts_scroll(0, y, (unsigned char *)s); | 173 | case 3: /* battery */ |
237 | y++; | ||
238 | #if CONFIG_CHARGING == CHARGING_CONTROL | 174 | #if CONFIG_CHARGING == CHARGING_CONTROL |
239 | if (charge_state == CHARGING) | 175 | if (charge_state == CHARGING) |
240 | snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_CHARGE)); | 176 | snprintf(buffer, MAX_PATH, (char *)str(LANG_BATTERY_CHARGE)); |
241 | else if (charge_state == TOPOFF) | 177 | else if (charge_state == TOPOFF) |
242 | snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TOPOFF_CHARGE)); | 178 | snprintf(buffer, MAX_PATH, (char *)str(LANG_BATTERY_TOPOFF_CHARGE)); |
243 | else if (charge_state == TRICKLE) | 179 | else if (charge_state == TRICKLE) |
244 | snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TRICKLE_CHARGE)); | 180 | snprintf(buffer, MAX_PATH, (char *)str(LANG_BATTERY_TRICKLE_CHARGE)); |
245 | else | 181 | else |
246 | #endif | 182 | #endif |
247 | if (battery_level() >= 0) | 183 | if (battery_level() >= 0) |
248 | snprintf(s, sizeof(s), (char *)str(LANG_BATTERY_TIME), battery_level(), | 184 | snprintf(buffer, MAX_PATH, (char *)str(LANG_BATTERY_TIME), battery_level(), |
249 | battery_time() / 60, battery_time() % 60); | 185 | battery_time() / 60, battery_time() % 60); |
250 | else | 186 | else |
251 | strncpy(s, "(n/a)", sizeof(s)); | 187 | strcpy(buffer, "(n/a)"); |
252 | FOR_NB_SCREENS(i) | 188 | break; |
253 | screens[i].puts_scroll(0, y, (unsigned char *)s); | 189 | case 4: /* disc usage 1 */ |
254 | y++; | ||
255 | } | ||
256 | |||
257 | #ifdef HAVE_LCD_CHARCELLS | ||
258 | if (page == 2) | ||
259 | #endif | ||
260 | { | ||
261 | #ifdef HAVE_MULTIVOLUME | 190 | #ifdef HAVE_MULTIVOLUME |
262 | output_dyn_value(s1, sizeof s1, free, kbyte_units, true); | 191 | output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true); |
263 | output_dyn_value(s2, sizeof s2, size, kbyte_units, true); | 192 | output_dyn_value(s2, sizeof s2, info->size, kbyte_units, true); |
264 | snprintf(s, sizeof s, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL), | 193 | snprintf(buffer, MAX_PATH, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL), |
265 | s1, s2); | 194 | s1, s2); |
266 | FOR_NB_SCREENS(i) | 195 | #else |
267 | screens[i].puts_scroll(0, y, (unsigned char *)s); | 196 | output_dyn_value(s1, sizeof s1, info->size, kbyte_units, true); |
268 | y++; | 197 | snprintf(buffer, MAX_PATH, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1); |
269 | 198 | #endif | |
270 | if (size2) { | 199 | break; |
271 | output_dyn_value(s1, sizeof s1, free2, kbyte_units, true); | 200 | case 5: /* disc usage 2 */ |
272 | output_dyn_value(s2, sizeof s2, size2, kbyte_units, true); | 201 | #ifdef HAVE_MULTIVOLUME |
273 | snprintf(s, sizeof s, "%s %s/%s", str(LANG_DISK_NAME_MMC), | 202 | if (info->size2) |
203 | { | ||
204 | output_dyn_value(s1, sizeof s1, info->free2, kbyte_units, true); | ||
205 | output_dyn_value(s2, sizeof s2, info->size2, kbyte_units, true); | ||
206 | snprintf(buffer, MAX_PATH, "%s %s/%s", str(LANG_DISK_NAME_MMC), | ||
274 | s1, s2); | 207 | s1, s2); |
275 | FOR_NB_SCREENS(i) | ||
276 | screens[i].puts_scroll(0, y, (unsigned char *)s); | ||
277 | y++; | ||
278 | } | 208 | } |
209 | else | ||
210 | return ""; | ||
279 | #else | 211 | #else |
280 | output_dyn_value(s1, sizeof s1, size, kbyte_units, true); | 212 | output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true); |
281 | snprintf(s, sizeof s, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1); | 213 | snprintf(buffer, MAX_PATH, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1); |
282 | FOR_NB_SCREENS(i) | ||
283 | screens[i].puts_scroll(0, y, (unsigned char *)s); | ||
284 | y++; | ||
285 | output_dyn_value(s1, sizeof s1, free, kbyte_units, true); | ||
286 | snprintf(s, sizeof s, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1); | ||
287 | FOR_NB_SCREENS(i) | ||
288 | screens[i].puts_scroll(0, y, (unsigned char *)s); | ||
289 | y++; | ||
290 | #endif | 214 | #endif |
291 | } | 215 | break; |
292 | 216 | } | |
293 | FOR_NB_SCREENS(i) | 217 | return buffer; |
294 | screens[i].update(); | 218 | } |
295 | 219 | static int info_speak_item(int selected_item, void * data) | |
296 | /* Wait for a key to be pushed */ | 220 | { |
297 | key = get_action(CONTEXT_MAINMENU,HZ*5); | 221 | struct info_data *info = (struct info_data*)data; |
298 | switch(key) { | 222 | const unsigned char *kbyte_units[] = { |
299 | 223 | ID2P(LANG_KILOBYTE), | |
300 | case ACTION_STD_CANCEL: | 224 | ID2P(LANG_MEGABYTE), |
301 | done = true; | 225 | ID2P(LANG_GIGABYTE) |
302 | break; | 226 | }; |
303 | 227 | switch (selected_item) | |
304 | #ifdef HAVE_LCD_CHARCELLS | 228 | { |
305 | case ACTION_STD_NEXT: | 229 | case 0:/* version, not voiced, so say the time instead */ |
306 | page = (page+1)%3; | 230 | #if CONFIG_RTC |
307 | break; | 231 | talk_date_time(get_time(), false); |
308 | case ACTION_STD_PREV: | ||
309 | page--; | ||
310 | if (page < 0) | ||
311 | page = 2; | ||
312 | break; | ||
313 | #endif | 232 | #endif |
233 | break; | ||
234 | case 1: /* nothing */ | ||
235 | break; | ||
236 | case 2: /* buffer, not spoken */ | ||
237 | break; | ||
238 | case 3: /* battery */ | ||
239 | if (battery_level() >= 0) | ||
240 | { | ||
241 | talk_id(LANG_BATTERY_TIME, false); | ||
242 | talk_value(battery_level(), UNIT_PERCENT, true); | ||
243 | #if CONFIG_CHARGING >= CHARGING_MONITOR | ||
244 | if (charge_state == CHARGING) | ||
245 | talk_id(LANG_BATTERY_CHARGE, true); | ||
246 | #if CONFIG_CHARGING == CHARGING_CONTROL | ||
247 | else if (charge_state == TOPOFF) | ||
248 | talk_id(LANG_BATTERY_TOPOFF_CHARGE, true); | ||
249 | #endif | ||
250 | else if (charge_state == TRICKLE) | ||
251 | talk_id(LANG_BATTERY_TRICKLE_CHARGE, true); | ||
252 | #endif | ||
253 | } | ||
254 | break; | ||
255 | case 4: /* disk 1 */ | ||
256 | talk_id(LANG_DISK_FREE_INFO, false); | ||
257 | #ifdef HAVE_MULTIVOLUME | ||
258 | talk_id(LANG_DISK_NAME_INTERNAL, true); | ||
259 | #endif | ||
260 | output_dyn_value(NULL, 0, info->free, kbyte_units, true); | ||
261 | break; | ||
262 | case 5: /* disk 2 */ | ||
263 | #ifdef HAVE_MULTIVOLUME | ||
264 | if (info->size2) | ||
265 | { | ||
266 | talk_id(LANG_DISK_NAME_MMC, false); | ||
267 | output_dyn_value(NULL, 0, info->free2, kbyte_units, true); | ||
268 | } | ||
269 | #endif | ||
270 | break; | ||
271 | } | ||
272 | return 0; | ||
273 | } | ||
314 | 274 | ||
275 | static int info_action_callback(int action, struct gui_synclist *lists) | ||
276 | { | ||
277 | (void)lists; | ||
278 | if ((action == ACTION_STD_OK) | ||
279 | #ifdef HAVE_MULTIVOLUME | ||
280 | || action == SYS_HOTSWAP_INSERTED | ||
281 | || action == SYS_HOTSWAP_EXTRACTED | ||
282 | #endif | ||
283 | ) | ||
284 | { | ||
315 | #ifndef SIMULATOR | 285 | #ifndef SIMULATOR |
316 | case ACTION_STD_OK: | 286 | struct info_data *info = (struct info_data *)lists->gui_list[SCREEN_MAIN].data; |
317 | gui_syncsplash(0, str(LANG_SCANNING_DISK)); | 287 | info->new_data = true; |
318 | fat_recalc_free(IF_MV(0)); | 288 | gui_syncsplash(0, ID2P(LANG_SCANNING_DISK)); |
289 | fat_recalc_free(IF_MV(0)); | ||
319 | #ifdef HAVE_MULTIVOLUME | 290 | #ifdef HAVE_MULTIVOLUME |
320 | if (fat_ismounted(1)) | 291 | if (fat_ismounted(1)) |
321 | fat_recalc_free(1); | 292 | fat_recalc_free(1); |
322 | #endif | 293 | #endif |
323 | new_info = true; | ||
324 | break; | ||
325 | #endif | 294 | #endif |
326 | 295 | return ACTION_REDRAW; | |
327 | default: | ||
328 | if (default_event_handler(key) == SYS_USB_CONNECTED) | ||
329 | return true; | ||
330 | break; | ||
331 | } | ||
332 | } | 296 | } |
333 | return false; | 297 | return action; |
298 | } | ||
299 | static bool show_info(void) | ||
300 | { | ||
301 | struct info_data data = {.new_data = true}; | ||
302 | struct simplelist_info info; | ||
303 | simplelist_info_init(&info, str(LANG_ROCKBOX_INFO), 6, (void*)&data); | ||
304 | info.hide_selection = !global_settings.talk_menu; | ||
305 | info.get_name = info_getname; | ||
306 | info.get_talk = info_speak_item; | ||
307 | info.action_callback = info_action_callback; | ||
308 | return simplelist_show_list(&info); | ||
334 | } | 309 | } |
335 | MENUITEM_FUNCTION(show_info_item, 0, ID2P(LANG_ROCKBOX_INFO), | 310 | MENUITEM_FUNCTION(show_info_item, 0, ID2P(LANG_ROCKBOX_INFO), |
336 | (menu_function)show_info, NULL, NULL, Icon_NOICON); | 311 | (menu_function)show_info, NULL, NULL, Icon_NOICON); |