summaryrefslogtreecommitdiff
path: root/apps/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tree.c')
-rw-r--r--apps/tree.c942
1 files changed, 322 insertions, 620 deletions
diff --git a/apps/tree.c b/apps/tree.c
index 8d68814315..7d4ee7f703 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -63,6 +63,12 @@
63#include "rtc.h" 63#include "rtc.h"
64#include "dircache.h" 64#include "dircache.h"
65 65
66/* gui api */
67#include "list.h"
68#include "statusbar.h"
69#include "splash.h"
70#include "buttonbar.h"
71
66#ifdef HAVE_LCD_BITMAP 72#ifdef HAVE_LCD_BITMAP
67#include "widgets.h" 73#include "widgets.h"
68#endif 74#endif
@@ -99,6 +105,14 @@ const struct filetype filetypes[] = {
99#endif /* #ifndef SIMULATOR */ 105#endif /* #ifndef SIMULATOR */
100}; 106};
101 107
108struct gui_synclist tree_lists;
109
110/* I put it here because other files doesn't use it yet,
111 * but should be elsewhere since it will be used mostly everywhere */
112struct gui_syncstatusbar statusbars;
113#ifdef HAS_BUTTONBAR
114struct gui_buttonbar tree_buttonbar;
115#endif
102static struct tree_context tc; 116static struct tree_context tc;
103 117
104bool boot_changed = false; 118bool boot_changed = false;
@@ -112,17 +126,77 @@ static bool reload_dir = false;
112 126
113static bool start_wps = false; 127static bool start_wps = false;
114static bool dirbrowse(void); 128static bool dirbrowse(void);
115static int curr_context = false; 129static int curr_context = false;/* id3db or tree*/
130
131/*
132 * removes the extension of filename (if it doesn't start with a .)
133 * puts the result in buffer
134 */
135char * strip_extension(char * filename, char * buffer)
136{
137 int dotpos;
138 char * dot=strrchr(filename, '.');
139 if(dot!=0 && filename[0]!='.')
140 {
141 dotpos = dot-filename;
142 strncpy(buffer, filename, dotpos);
143 buffer[dotpos]='\0';
144 return(buffer);
145 }
146 else
147 return(filename);
148}
149char * tree_get_filename(int selected_item, char *buffer)
150{
151 char *name;
152 int attr=0;
153 bool id3db = *tc.dirfilter == SHOW_ID3DB;
154 if (id3db) {
155 name = ((char**)tc.dircache)[selected_item * tc.dentry_size];
156 }
157 else {
158 struct entry* dc = tc.dircache;
159 struct entry* e = &dc[selected_item];
160 name = e->name;
161 attr = e->attr;
162 }
163 /* if any file filter is on, and if it's not a directory,
164 * strip the extension */
165
166 if ( (*tc.dirfilter != SHOW_ID3DB) && !(attr & ATTR_DIRECTORY)
167 && (*tc.dirfilter != SHOW_ALL) )
168 {
169 return(strip_extension(name, buffer));
170 }
171 return(name);
172}
173
174
175void tree_get_fileicon(int selected_item, ICON * icon)
176{
177 bool id3db = *tc.dirfilter == SHOW_ID3DB;
178 if (id3db) {
179 *icon = db_get_icon(&tc);
180 }
181 else {
182 struct entry* dc = tc.dircache;
183 struct entry* e = &dc[selected_item];
184 *icon = filetype_get_icon(e->attr);
185 }
186}
116 187
117bool check_rockboxdir(void) 188bool check_rockboxdir(void)
118{ 189{
119 DIR *dir = opendir(ROCKBOX_DIR); 190 DIR *dir = opendir(ROCKBOX_DIR);
120 if(!dir) 191 if(!dir)
121 { 192 {
122 lcd_clear_display(); 193 int i;
123 splash(HZ*2, true, str(LANG_NO_ROCKBOX_DIR)); 194 for(i = 0;i < NB_SCREENS;++i)
124 lcd_clear_display(); 195 screens[i].clear_display();
125 splash(HZ*2, true, str(LANG_INSTALLATION_INCOMPLETE)); 196 gui_syncsplash(HZ*2, true, str(LANG_NO_ROCKBOX_DIR));
197 for(i = 0;i < NB_SCREENS;++i)
198 screens[i].clear_display();
199 gui_syncsplash(HZ*2, true, str(LANG_INSTALLATION_INCOMPLETE));
126 return false; 200 return false;
127 } 201 }
128 closedir(dir); 202 closedir(dir);
@@ -131,16 +205,28 @@ bool check_rockboxdir(void)
131 205
132void browse_root(void) 206void browse_root(void)
133{ 207{
208 /* essential to all programs that wants to display things */
209 screen_access_init();
210
134 filetype_init(); 211 filetype_init();
135 check_rockboxdir(); 212 check_rockboxdir();
136 213
137 strcpy(tc.currdir, "/"); 214 strcpy(tc.currdir, "/");
215
138#ifdef HAVE_LCD_CHARCELLS 216#ifdef HAVE_LCD_CHARCELLS
139 lcd_double_height(false); 217 int i;
218 for(i = 0;i < NB_SCREENS;++i)
219 screens[i].double_height(false);
140#endif 220#endif
221#ifdef HAS_BUTTONBAR
222 gui_buttonbar_init(&tree_buttonbar);
223 /* since archos only have one screen, no need to create more than that */
224 gui_buttonbar_set_display(&tree_buttonbar, &(screens[SCREEN_MAIN]) );
225#endif
226 gui_syncstatusbar_init(&statusbars);
227 gui_synclist_init(&tree_lists, &tree_get_fileicon, &tree_get_filename);
141#ifndef SIMULATOR 228#ifndef SIMULATOR
142 dirbrowse(); 229 dirbrowse();
143
144#else 230#else
145 if (!dirbrowse()) { 231 if (!dirbrowse()) {
146 DEBUGF("No filesystem found. Have you forgotten to create it?\n"); 232 DEBUGF("No filesystem found. Have you forgotten to create it?\n");
@@ -159,126 +245,35 @@ struct tree_context* tree_get_context(void)
159 return &tc; 245 return &tc;
160} 246}
161 247
162#ifdef HAVE_LCD_BITMAP
163
164/* pixel margins */
165#define MARGIN_X (global_settings.scrollbar && \
166 tc.filesindir > tree_max_on_screen ? SCROLLBAR_WIDTH : 0) + \
167 CURSOR_WIDTH + (global_settings.show_icons && ICON_WIDTH > 0 ? ICON_WIDTH :0)
168#define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0)
169
170/* position the entry-list starts at */
171#define LINE_X 0
172#define LINE_Y (global_settings.statusbar ? 1 : 0)
173
174#define CURSOR_X (global_settings.scrollbar && \
175 tc.filesindir > tree_max_on_screen ? 1 : 0)
176#define CURSOR_Y 0 /* the cursor is not positioned in regard to
177 the margins, so this is the amount of lines
178 we add to the cursor Y position to position
179 it on a line */
180#define CURSOR_WIDTH (global_settings.invert_cursor ? 0 : 4)
181
182#define ICON_WIDTH 6
183
184#define SCROLLBAR_X 0
185#define SCROLLBAR_Y lcd_getymargin()
186#define SCROLLBAR_WIDTH 6
187
188#else /* HAVE_LCD_BITMAP */
189
190#define TREE_MAX_ON_SCREEN 2
191#define TREE_MAX_LEN_DISPLAY 11 /* max length that fits on screen */
192#define LINE_X 2 /* X position the entry-list starts at */
193#define LINE_Y 0 /* Y position the entry-list starts at */
194
195#define CURSOR_X 0
196#define CURSOR_Y 0 /* not really used for players */
197
198#endif /* HAVE_LCD_BITMAP */
199
200/* talkbox hovering delay, to avoid immediate disk activity */ 248/* talkbox hovering delay, to avoid immediate disk activity */
201#define HOVER_DELAY (HZ/2) 249#define HOVER_DELAY (HZ/2)
202 250/*
203static void showfileline(int line, char* name, int attr, bool scroll) 251 * Returns the position of a given file in the current directory
252 * returns -1 if not found
253 */
254int tree_get_file_position(char * filename)
204{ 255{
205 int xpos = LINE_X; 256 int i;
206 char* dotpos = NULL; 257 /* use lastfile to determine the selected item (default=0) */
207 258 for (i=0; i < tc.filesindir; i++)
208#ifdef HAVE_LCD_CHARCELLS
209 if (!global_settings.show_icons)
210 xpos--;
211#endif
212
213 /* if any file filter is on, strip the extension */
214 if (*tc.dirfilter != SHOW_ID3DB &&
215 *tc.dirfilter != SHOW_ALL &&
216 !(attr & ATTR_DIRECTORY))
217 { 259 {
218 dotpos = strrchr(name, '.'); 260 struct entry* dc = tc.dircache;
219 if (dotpos) { 261 struct entry* e = &dc[i];
220 *dotpos = 0; 262 if (!strcasecmp(e->name, filename))
221 } 263 return(i);
222 } 264 }
223 265 return(-1);/* no file can match, returns undefined */
224 if(scroll) {
225#ifdef HAVE_LCD_BITMAP
226 lcd_setfont(FONT_UI);
227 if (global_settings.invert_cursor)
228 lcd_puts_scroll_style(xpos, line, name, STYLE_INVERT);
229 else
230#endif
231 lcd_puts_scroll(xpos, line, name);
232 } else
233 lcd_puts(xpos, line, name);
234
235 /* Restore the dot before the extension if it was removed */
236 if (dotpos)
237 *dotpos = '.';
238}
239
240#ifdef HAVE_LCD_BITMAP
241static int recalc_screen_height(void)
242{
243 int fw, fh;
244 int height = LCD_HEIGHT;
245
246 lcd_setfont(FONT_UI);
247 lcd_getstringsize("A", &fw, &fh);
248 if(global_settings.statusbar)
249 height -= STATUSBAR_HEIGHT;
250
251#if CONFIG_KEYPAD == RECORDER_PAD
252 if(global_settings.buttonbar)
253 height -= BUTTONBAR_HEIGHT;
254#endif
255
256 return height / fh;
257} 266}
258#endif
259 267
260static int showdir(void) 268/*
269 * Called when a new dir is loaded (for example when returning from other apps ...)
270 * also completely redraws the tree
271 */
272static int update_dir(void)
261{ 273{
262 struct entry *dircache = tc.dircache;
263 int i;
264 int tree_max_on_screen;
265 int start = tc.dirstart;
266 bool id3db = *tc.dirfilter == SHOW_ID3DB; 274 bool id3db = *tc.dirfilter == SHOW_ID3DB;
267 bool newdir = false; 275 bool changed = false;
268#ifdef HAVE_LCD_BITMAP 276 /* Checks for changes */
269 const char* icon;
270 int line_height;
271 int fw, fh;
272 lcd_setfont(FONT_UI);
273 lcd_getstringsize("A", &fw, &fh);
274 tree_max_on_screen = recalc_screen_height();
275 line_height = fh;
276#else
277 int icon;
278 tree_max_on_screen = TREE_MAX_ON_SCREEN;
279#endif
280
281 /* new file dir? load it */
282 if (id3db) { 277 if (id3db) {
283 if (tc.currtable != lasttable || 278 if (tc.currtable != lasttable ||
284 tc.currextra != lastextra || 279 tc.currextra != lastextra ||
@@ -286,151 +281,73 @@ static int showdir(void)
286 { 281 {
287 if (db_load(&tc) < 0) 282 if (db_load(&tc) < 0)
288 return -1; 283 return -1;
284
289 lasttable = tc.currtable; 285 lasttable = tc.currtable;
290 lastextra = tc.currextra; 286 lastextra = tc.currextra;
291 lastfirstpos = tc.firstpos; 287 lastfirstpos = tc.firstpos;
292 newdir = true; 288 changed = true;
293 } 289 }
294 } 290 }
295 else { 291 else {
292 /* if the tc.currdir has been changed, reload it ...*/
296 if (strncmp(tc.currdir, lastdir, sizeof(lastdir)) || reload_dir) { 293 if (strncmp(tc.currdir, lastdir, sizeof(lastdir)) || reload_dir) {
297 if (ft_load(&tc, NULL) < 0) 294
295 if (ft_load(&tc, NULL) < 0)
298 return -1; 296 return -1;
299 strcpy(lastdir, tc.currdir); 297 strcpy(lastdir, tc.currdir);
300 newdir = true; 298 changed = true;
301 } 299 }
302 } 300 }
303 301 /* if selected item is undefined */
304 if (newdir && !id3db && 302 if (tc.selected_item == -1)
305 (tc.dirfull || tc.filesindir == global_settings.max_files_in_dir) )
306 { 303 {
307#ifdef HAVE_LCD_CHARCELLS 304 /* use lastfile to determine the selected item */
308 lcd_double_height(false); 305 tc.selected_item = tree_get_file_position(lastfile);
309#endif
310 lcd_clear_display();
311 lcd_puts(0,0,str(LANG_SHOWDIR_ERROR_BUFFER));
312 lcd_puts(0,1,str(LANG_SHOWDIR_ERROR_FULL));
313 lcd_update();
314 sleep(HZ*2);
315 lcd_clear_display();
316 }
317
318 if (start == -1)
319 {
320 int diff_files;
321
322 /* use lastfile to determine start (default=0) */
323 start = 0;
324
325 for (i=0; i < tc.filesindir; i++)
326 {
327 struct entry *dircache = tc.dircache;
328
329 if (!strcasecmp(dircache[i].name, lastfile))
330 {
331 start = i;
332 break;
333 }
334 }
335
336 diff_files = tc.filesindir - start;
337 if (diff_files < tree_max_on_screen)
338 {
339 int oldstart = start;
340
341 start -= (tree_max_on_screen - diff_files);
342 if (start < 0)
343 start = 0;
344 306
345 tc.dircursor = oldstart - start; 307 /* If the file doesn't exists, select the first one (default) */
346 } 308 if(tc.selected_item < 0)
347 309 tc.selected_item = 0;
348 tc.dirstart = start; 310 changed = true;
349 } 311 }
350 312 if (changed)
351 /* The cursor might point to an invalid line, for example if someone
352 deleted the last file in the dir */
353 if (tc.filesindir)
354 { 313 {
355 while (start + tc.dircursor >= tc.filesindir) 314 if(!id3db && (tc.dirfull ||
315 tc.filesindir == global_settings.max_files_in_dir) )
356 { 316 {
357 if (start) 317 /* dir full */
358 start--; 318 int i;
359 else 319 for(i = 0;i < NB_SCREENS;++i)
360 if (tc.dircursor) 320 {
361 tc.dircursor--;
362 }
363 tc.dirstart = start;
364 }
365
366#ifdef HAVE_LCD_CHARCELLS 321#ifdef HAVE_LCD_CHARCELLS
367 lcd_stop_scroll(); 322 screens[i].double_height(false);
368 lcd_double_height(false);
369#endif
370 lcd_clear_display();
371#ifdef HAVE_LCD_BITMAP
372 lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and icon */
373 lcd_setfont(FONT_UI);
374#endif 323#endif
375 324 screens[i].clear_display();
376 325 screens[i].puts(0,0,str(LANG_SHOWDIR_ERROR_BUFFER));
377 for ( i=start; i < start+tree_max_on_screen && i < tc.filesindir; i++ ) { 326 screens[i].puts(0,1,str(LANG_SHOWDIR_ERROR_FULL));
378 int line = i - start; 327#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
379 char* name; 328 screens[i].update();
380 int attr = 0;
381
382 if (id3db) {
383 name = ((char**)tc.dircache)[i * tc.dentry_size];
384 icon = db_get_icon(&tc);
385 }
386 else {
387 struct entry* dc = tc.dircache;
388 struct entry* e = &dc[i];
389 name = e->name;
390 attr = e->attr;
391 icon = filetype_get_icon(dircache[i].attr);
392 }
393
394
395 if (icon && global_settings.show_icons) {
396#ifdef HAVE_LCD_BITMAP
397 int offset=0;
398 if ( line_height > 8 )
399 offset = (line_height - 8) / 2;
400 lcd_mono_bitmap(icon,
401 CURSOR_X * 6 + CURSOR_WIDTH,
402 MARGIN_Y+(i-start)*line_height + offset, 6, 8);
403#else
404 if (icon < 0 )
405 icon = Icon_Unknown;
406 lcd_putc(LINE_X-1, i-start, icon);
407#endif 329#endif
330 }
331 sleep(HZ*2);
332 for(i = 0;i < NB_SCREENS;++i)
333 screens[i].clear_display();
408 } 334 }
409
410 showfileline(line, name, attr, false); /* no scroll */
411 } 335 }
412 336 gui_synclist_set_nb_items(&tree_lists, tc.filesindir);
413#ifdef HAVE_LCD_BITMAP 337 gui_synclist_select_item(&tree_lists, tc.selected_item);
414 if (global_settings.scrollbar && (tc.dirlength > tree_max_on_screen)) 338 gui_synclist_draw(&tree_lists);
415 scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1, 339 gui_syncstatusbar_draw(&statusbars, true);
416 tree_max_on_screen * line_height, tc.dirlength, 340#ifdef HAS_BUTTONBAR
417 start + tc.firstpos,
418 start + tc.firstpos + tree_max_on_screen, VERTICAL);
419
420#if CONFIG_KEYPAD == RECORDER_PAD
421 if (global_settings.buttonbar) { 341 if (global_settings.buttonbar) {
422 if (*tc.dirfilter < NUM_FILTER_MODES) 342 if (*tc.dirfilter < NUM_FILTER_MODES)
423 buttonbar_set(str(LANG_DIRBROWSE_F1), 343 gui_buttonbar_set(&tree_buttonbar, str(LANG_DIRBROWSE_F1),
424 str(LANG_DIRBROWSE_F2), 344 str(LANG_DIRBROWSE_F2),
425 str(LANG_DIRBROWSE_F3)); 345 str(LANG_DIRBROWSE_F3));
426 else 346 else
427 buttonbar_set("<<<", "", ""); 347 gui_buttonbar_set(&tree_buttonbar, "<<<", "", "");
428 buttonbar_draw(); 348 gui_buttonbar_draw(&tree_buttonbar);
429 } 349 }
430#endif 350#endif
431#endif
432 status_draw(true);
433
434 return tc.filesindir; 351 return tc.filesindir;
435} 352}
436 353
@@ -468,7 +385,6 @@ void reload_directory(void)
468static void start_resume(bool just_powered_on) 385static void start_resume(bool just_powered_on)
469{ 386{
470 bool do_resume = false; 387 bool do_resume = false;
471
472 if ( global_settings.resume_index != -1 ) { 388 if ( global_settings.resume_index != -1 ) {
473 DEBUGF("Resume index %X offset %X\n", 389 DEBUGF("Resume index %X offset %X\n",
474 global_settings.resume_index, 390 global_settings.resume_index,
@@ -486,7 +402,7 @@ static void start_resume(bool just_powered_on)
486 do_resume = true; 402 do_resume = true;
487 403
488 if (! do_resume) return; 404 if (! do_resume) return;
489 405
490 if (playlist_resume() != -1) 406 if (playlist_resume() != -1)
491 { 407 {
492 playlist_start(global_settings.resume_index, 408 playlist_start(global_settings.resume_index,
@@ -496,23 +412,23 @@ static void start_resume(bool just_powered_on)
496 } 412 }
497 else return; 413 else return;
498 } else if (! just_powered_on) { 414 } else if (! just_powered_on) {
499 splash(HZ*2, true, str(LANG_NOTHING_TO_RESUME)); 415 gui_syncsplash(HZ*2, true, str(LANG_NOTHING_TO_RESUME));
500 } 416 }
501} 417}
502 418
419/* Selects a file and update tree context properly */
503void set_current_file(char *path) 420void set_current_file(char *path)
504{ 421{
505 char *name; 422 char *name;
506 unsigned int i; 423 int i;
507 424
508 /* in ID3DB mode it is a bad idea to call this function */ 425 /* in ID3DB mode it is a bad idea to call this function */
509 /* (only happens with `follow playlist') */ 426 /* (only happens with `follow playlist') */
510 if( *tc.dirfilter == SHOW_ID3DB ) 427 if( *tc.dirfilter == SHOW_ID3DB )
511 {
512 return; 428 return;
513 }
514 429
515 /* separate directory from filename */ 430 /* separate directory from filename */
431 /* gets the directory's name and put it into tc.currdir */
516 name = strrchr(path+1,'/'); 432 name = strrchr(path+1,'/');
517 if (name) 433 if (name)
518 { 434 {
@@ -528,24 +444,27 @@ void set_current_file(char *path)
528 } 444 }
529 445
530 strcpy(lastfile, name); 446 strcpy(lastfile, name);
447
448 /* undefined item selected */
449 tc.selected_item = -1;
531 450
532 tc.dircursor = 0; 451 /* If we changed dir we must recalculate the dirlevel
533 tc.dirstart = -1; 452 and adjust the selected history properly */
534
535 if (strncmp(tc.currdir,lastdir,sizeof(lastdir))) 453 if (strncmp(tc.currdir,lastdir,sizeof(lastdir)))
536 { 454 {
537 tc.dirlevel = 0; 455 tc.dirlevel = 0;
538 tc.dirpos[tc.dirlevel] = -1; 456 tc.selected_item_history[tc.dirlevel] = -1;
539 tc.cursorpos[tc.dirlevel] = 0;
540 457
541 /* use '/' to calculate dirlevel */ 458 /* use '/' to calculate dirlevel */
542 for (i=1; i<strlen(path)+1; i++) 459 /* FIXME : strlen(path) : crazy oO better to store it at
460 the beginning */
461 int path_len = strlen(path) + 1;
462 for (i = 1; i < path_len; i++)
543 { 463 {
544 if (path[i] == '/') 464 if (path[i] == '/')
545 { 465 {
546 tc.dirlevel++; 466 tc.dirlevel++;
547 tc.dirpos[tc.dirlevel] = -1; 467 tc.selected_item_history[tc.dirlevel] = -1;
548 tc.cursorpos[tc.dirlevel] = 0;
549 } 468 }
550 } 469 }
551 } 470 }
@@ -567,24 +486,20 @@ static bool check_changed_id3mode(bool currmode)
567 } 486 }
568 return currmode; 487 return currmode;
569} 488}
570 489/* main loop, handles key events */
571static bool dirbrowse(void) 490static bool dirbrowse(void)
572{ 491{
573 int numentries=0; 492 int numentries=0;
574 char buf[MAX_PATH]; 493 char buf[MAX_PATH];
575 int i; 494 int lasti = -1;
576 int lasti=-1;
577 unsigned button; 495 unsigned button;
578 int tree_max_on_screen;
579 bool reload_root = false; 496 bool reload_root = false;
580 int lastfilter = *tc.dirfilter; 497 int lastfilter = *tc.dirfilter;
581 bool lastsortcase = global_settings.sort_case; 498 bool lastsortcase = global_settings.sort_case;
582 int lastdircursor=-1;
583 bool need_update = true; 499 bool need_update = true;
584 bool exit_func = false; 500 bool exit_func = false;
585 long thumbnail_time = -1; /* for delaying a thumbnail */ 501 long thumbnail_time = -1; /* for delaying a thumbnail */
586 bool update_all = false; /* set this to true when the whole file list 502
587 has been refreshed on screen */
588 unsigned lastbutton = 0; 503 unsigned lastbutton = 0;
589 char* currdir = tc.currdir; /* just a shortcut */ 504 char* currdir = tc.currdir; /* just a shortcut */
590 bool id3db = *tc.dirfilter == SHOW_ID3DB; 505 bool id3db = *tc.dirfilter == SHOW_ID3DB;
@@ -593,15 +508,10 @@ static bool dirbrowse(void)
593 curr_context=CONTEXT_ID3DB; 508 curr_context=CONTEXT_ID3DB;
594 else 509 else
595 curr_context=CONTEXT_TREE; 510 curr_context=CONTEXT_TREE;
596
597#ifdef HAVE_LCD_BITMAP 511#ifdef HAVE_LCD_BITMAP
598 tree_max_on_screen = recalc_screen_height(); 512 screen_access_update_nb_lines();
599#else
600 tree_max_on_screen = TREE_MAX_ON_SCREEN;
601#endif 513#endif
602 514 tc.selected_item = 0;
603 tc.dircursor=0;
604 tc.dirstart=0;
605 tc.dirlevel=0; 515 tc.dirlevel=0;
606 tc.firstpos=0; 516 tc.firstpos=0;
607 lasttable = -1; 517 lasttable = -1;
@@ -624,25 +534,21 @@ static bool dirbrowse(void)
624 start_resume(true); 534 start_resume(true);
625 535
626 } 536 }
627 537 /* If we don't need to show the wps, draw the dir */
628 if (!start_wps) { 538 if (!start_wps) {
629 numentries = showdir(); 539 numentries = update_dir();
630 if (numentries == -1) 540 if (numentries == -1)
631 return false; /* currdir is not a directory */ 541 return false; /* currdir is not a directory */
632 542
633 if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0) 543 if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0)
634 { 544 {
635 splash(HZ*2, true, str(LANG_NO_FILES)); 545 gui_syncsplash(HZ*2, true, str(LANG_NO_FILES));
636 return false; /* No files found for rockbox_browser() */ 546 return false; /* No files found for rockbox_browser() */
637 } 547 }
638 update_all = true;
639
640 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
641 } 548 }
642 549
643 while(1) { 550 while(1) {
644 struct entry *dircache = tc.dircache; 551 struct entry *dircache = tc.dircache;
645
646 bool restore = false; 552 bool restore = false;
647 553
648 button = button_get_w_tmo(HZ/5); 554 button = button_get_w_tmo(HZ/5);
@@ -651,15 +557,18 @@ static bool dirbrowse(void)
651 if (boot_changed) { 557 if (boot_changed) {
652 bool stop = false; 558 bool stop = false;
653 unsigned int button; 559 unsigned int button;
654 560 int i;
655 lcd_clear_display(); 561 for(i = 0;i < NB_SCREENS;++i)
656 lcd_puts(0,0,str(LANG_BOOT_CHANGED)); 562 {
657 lcd_puts(0,1,str(LANG_REBOOT_NOW)); 563 screens[i].clear_display();
564 screens[i].puts(0,0,str(LANG_BOOT_CHANGED));
565 screens[i].puts(0,1,str(LANG_REBOOT_NOW));
658#ifdef HAVE_LCD_BITMAP 566#ifdef HAVE_LCD_BITMAP
659 lcd_puts(0,3,str(LANG_CONFIRM_WITH_PLAY_RECORDER)); 567 screens[i].puts(0,3,str(LANG_CONFIRM_WITH_PLAY_RECORDER));
660 lcd_puts(0,4,str(LANG_CANCEL_WITH_ANY_RECORDER)); 568 screens[i].puts(0,4,str(LANG_CANCEL_WITH_ANY_RECORDER));
661 lcd_update(); 569 screens[i].update();
662#endif 570#endif
571 }
663 while (!stop) { 572 while (!stop) {
664 button = button_get(true); 573 button = button_get(true);
665 switch (button) { 574 switch (button) {
@@ -683,6 +592,7 @@ static bool dirbrowse(void)
683 boot_changed = false; 592 boot_changed = false;
684 } 593 }
685#endif 594#endif
595 need_update = gui_synclist_do_button(&tree_lists, button);
686 596
687 switch ( button ) { 597 switch ( button ) {
688#ifdef TREE_ENTER 598#ifdef TREE_ENTER
@@ -702,33 +612,17 @@ static bool dirbrowse(void)
702 && (lastbutton != TREE_RUN_PRE))) 612 && (lastbutton != TREE_RUN_PRE)))
703 break; 613 break;
704#endif 614#endif
705 if ( !numentries ) 615 /* nothing to do if no files to display */
616 if ( numentries == 0 )
706 break; 617 break;
707 618
708 if (id3db) 619 switch (id3db?db_enter(&tc):ft_enter(&tc))
709 i = db_enter(&tc);
710 else
711 i = ft_enter(&tc);
712
713 switch (i)
714 { 620 {
715 case 1: reload_dir = true; break; 621 case 1: reload_dir = true; break;
716 case 2: start_wps = true; break; 622 case 2: start_wps = true; break;
717 case 3: exit_func = true; break; 623 case 3: exit_func = true; break;
718 default: break; 624 default: break;
719 } 625 }
720
721#ifdef HAVE_LCD_BITMAP
722 /* maybe we have a new font */
723 tree_max_on_screen = recalc_screen_height();
724#endif
725 /* make sure cursor is on screen */
726 while ( tc.dircursor > tree_max_on_screen )
727 {
728 tc.dircursor--;
729 tc.dirstart++;
730 }
731
732 restore = true; 626 restore = true;
733 break; 627 break;
734 628
@@ -741,8 +635,8 @@ static bool dirbrowse(void)
741 exit_func = true; 635 exit_func = true;
742 break; 636 break;
743 } 637 }
744 638 /* if we are in /, nothing to do */
745 if (!tc.dirlevel) 639 if (tc.dirlevel == 0)
746 break; 640 break;
747 641
748 if (id3db) 642 if (id3db)
@@ -783,169 +677,6 @@ static bool dirbrowse(void)
783 break; 677 break;
784#endif 678#endif
785#endif 679#endif
786
787 case TREE_PREV:
788 case TREE_PREV | BUTTON_REPEAT:
789#ifdef TREE_RC_PREV
790 case TREE_RC_PREV:
791 case TREE_RC_PREV | BUTTON_REPEAT:
792#endif
793 if (!tc.filesindir)
794 break;
795
796 /* start scrolling when at 1/3 of the screen */
797 if (tc.dircursor >=
798 tree_max_on_screen - (2 * tree_max_on_screen) / 3
799 || (tc.dirstart == 0 && tc.dircursor > 0)) {
800 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
801 tc.dircursor--;
802 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
803 }
804 else {
805 if (tc.dirstart || tc.firstpos) {
806 if (tc.dirstart)
807 tc.dirstart--;
808 else {
809 if (tc.firstpos > max_files/2) {
810 tc.firstpos -= max_files/2;
811 tc.dirstart += max_files/2;
812 tc.dirstart--;
813 }
814 else {
815 tc.dirstart = tc.firstpos - 1;
816 tc.firstpos = 0;
817 }
818 }
819 restore = true;
820 }
821 else {
822 if (button & BUTTON_REPEAT)
823 break;
824 if (numentries < tree_max_on_screen) {
825 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
826 false);
827 tc.dircursor = numentries - 1;
828 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
829 true);
830 }
831 else if (id3db && tc.dirfull) {
832 /* load last dir segment */
833 /* use max_files/2 in case names are longer than
834 AVERAGE_FILE_LENGTH */
835 tc.firstpos = tc.dirlength - max_files/2;
836 tc.dirstart = tc.firstpos;
837 tc.dircursor = tree_max_on_screen - 1;
838 numentries = showdir();
839 update_all = true;
840 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
841 true);
842 }
843 else {
844 tc.dirstart = numentries - tree_max_on_screen;
845 tc.dircursor = tree_max_on_screen - 1;
846 restore = true;
847 }
848 }
849 }
850 need_update = true;
851 break;
852
853 case TREE_NEXT:
854 case TREE_NEXT | BUTTON_REPEAT:
855#ifdef TREE_RC_NEXT
856 case TREE_RC_NEXT:
857 case TREE_RC_NEXT | BUTTON_REPEAT:
858#endif
859 if (!tc.filesindir)
860 break;
861
862 if (tc.dircursor + tc.dirstart + 1 < numentries ) {
863 /* start scrolling when at 2/3 of the screen */
864 if(tc.dircursor < (2 * tree_max_on_screen) / 3 ||
865 numentries - tc.dirstart <= tree_max_on_screen) {
866 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
867 tc.dircursor++;
868 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
869 }
870 else {
871 tc.dirstart++;
872 restore = true;
873 }
874 }
875 else if (id3db && (tc.firstpos || tc.dirfull)) {
876 if (tc.dircursor + tc.dirstart + tc.firstpos + 1 >= tc.dirlength) {
877 /* wrap and load first dir segment */
878 if (button & BUTTON_REPEAT)
879 break;
880 tc.firstpos = tc.dirstart = tc.dircursor = 0;
881 }
882 else {
883 /* load next dir segment */
884 tc.firstpos += tc.dirstart;
885 tc.dirstart = 0;
886 }
887 restore = true;
888 }
889 else {
890 if (button & BUTTON_REPEAT)
891 break;
892 if(numentries < tree_max_on_screen) {
893 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
894 tc.dirstart = tc.dircursor = 0;
895 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
896 }
897 else {
898 tc.dirstart = tc.dircursor = 0;
899 numentries = showdir();
900 update_all=true;
901 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
902 }
903 }
904 need_update = true;
905 break;
906
907#ifdef TREE_PGUP
908 case TREE_PGUP:
909 case TREE_PGUP | BUTTON_REPEAT:
910 if (tc.dirstart) {
911 tc.dirstart -= tree_max_on_screen;
912 if ( tc.dirstart < 0 )
913 tc.dirstart = 0;
914 }
915 else if (tc.firstpos) {
916 if (tc.firstpos > max_files/2) {
917 tc.firstpos -= max_files/2;
918 tc.dirstart += max_files/2;
919 tc.dirstart -= tree_max_on_screen;
920 }
921 else {
922 tc.dirstart = tc.firstpos - tree_max_on_screen;
923 tc.firstpos = 0;
924 }
925 }
926 else
927 tc.dircursor = 0;
928 restore = true;
929 break;
930
931 case TREE_PGDN:
932 case TREE_PGDN | BUTTON_REPEAT:
933 if ( tc.dirstart < numentries - tree_max_on_screen ) {
934 tc.dirstart += tree_max_on_screen;
935 if ( tc.dirstart > numentries - tree_max_on_screen )
936 tc.dirstart = numentries - tree_max_on_screen;
937 }
938 else if (id3db && tc.dirfull) {
939 /* load next dir segment */
940 tc.firstpos += tc.dirstart;
941 tc.dirstart = 0;
942 }
943 else
944 tc.dircursor = numentries - tc.dirstart - 1;
945 restore = true;
946 break;
947#endif
948
949 case TREE_MENU: 680 case TREE_MENU:
950#ifdef TREE_RC_MENU 681#ifdef TREE_RC_MENU
951 case TREE_RC_MENU: 682 case TREE_RC_MENU:
@@ -957,7 +688,9 @@ static bool dirbrowse(void)
957 /* don't enter menu from plugin browser */ 688 /* don't enter menu from plugin browser */
958 if (*tc.dirfilter < NUM_FILTER_MODES) 689 if (*tc.dirfilter < NUM_FILTER_MODES)
959 { 690 {
960 lcd_stop_scroll(); 691 int i;
692 for(i = 0;i < NB_SCREENS;++i)
693 screens[i].stop_scroll();
961 if (main_menu()) 694 if (main_menu())
962 reload_dir = true; 695 reload_dir = true;
963 restore = true; 696 restore = true;
@@ -1017,7 +750,7 @@ static bool dirbrowse(void)
1017 { 750 {
1018 if (quick_screen(curr_context, BUTTON_F3)) 751 if (quick_screen(curr_context, BUTTON_F3))
1019 reload_dir = true; 752 reload_dir = true;
1020 tree_max_on_screen = recalc_screen_height(); 753 screen_access_update_nb_lines();
1021 restore = true; 754 restore = true;
1022 } 755 }
1023 break; 756 break;
@@ -1052,20 +785,19 @@ static bool dirbrowse(void)
1052 } 785 }
1053 else 786 else
1054 { 787 {
1055 attr = dircache[tc.dircursor+tc.dirstart].attr; 788 attr = dircache[tc.selected_item].attr;
1056 789
1057 if (currdir[1]) 790 if (currdir[1]) /* Not in / */
1058 snprintf(buf, sizeof buf, "%s/%s", 791 snprintf(buf, sizeof buf, "%s/%s",
1059 currdir, 792 currdir,
1060 dircache[tc.dircursor+tc.dirstart].name); 793 dircache[tc.selected_item].name);
1061 else 794 else /* In / */
1062 snprintf(buf, sizeof buf, "/%s", 795 snprintf(buf, sizeof buf, "/%s",
1063 dircache[tc.dircursor+tc.dirstart].name); 796 dircache[tc.selected_item].name);
1064 } 797 }
1065
1066 onplay_result = onplay(buf, attr, curr_context); 798 onplay_result = onplay(buf, attr, curr_context);
1067 } 799 }
1068 800
1069 switch (onplay_result) 801 switch (onplay_result)
1070 { 802 {
1071 case ONPLAY_OK: 803 case ONPLAY_OK:
@@ -1099,22 +831,22 @@ static bool dirbrowse(void)
1099 } 831 }
1100 } 832 }
1101 else 833 else
1102 { 834 {
1103 DEBUGF("Playing file thumbnail: %s/%s%s\n", 835 DEBUGF("Playing file thumbnail: %s/%s%s\n",
1104 currdir, dircache[lasti].name, file_thumbnail_ext); 836 currdir, dircache[lasti].name, file_thumbnail_ext);
1105 /* no fallback necessary, we knew in advance 837 /* no fallback necessary, we knew in advance
1106 that the file exists */ 838 that the file exists */
1107 ft_play_filename(currdir, dircache[lasti].name); 839 ft_play_filename(currdir, dircache[lasti].name);
1108 } 840 }
1109 thumbnail_time = -1; /* job done */ 841 thumbnail_time = -1; /* job done */
1110 } 842 }
1111 status_draw(false); 843 gui_syncstatusbar_draw(&statusbars, false);
1112 break; 844 break;
1113 845
1114#ifdef HAVE_HOTSWAP 846#ifdef HAVE_HOTSWAP
1115 case SYS_FS_CHANGED: 847 case SYS_FS_CHANGED:
1116 if (!id3db) 848 if (!id3db)
1117 reload_dir = true; 849 reload_dir = true;
1118 /* The 'dir no longer valid' situation will be caught later 850 /* The 'dir no longer valid' situation will be caught later
1119 * by checking the showdir() result. */ 851 * by checking the showdir() result. */
1120 break; 852 break;
@@ -1139,18 +871,20 @@ static bool dirbrowse(void)
1139 lastbutton = button; 871 lastbutton = button;
1140 } 872 }
1141 873
1142 if (start_wps) 874 if (start_wps && audio_status() )
1143 { 875 {
1144 lcd_stop_scroll(); 876 int i;
877 for(i = 0;i < NB_SCREENS;++i)
878 screens[i].stop_scroll();
1145 if (wps_show() == SYS_USB_CONNECTED) 879 if (wps_show() == SYS_USB_CONNECTED)
1146 reload_dir = true; 880 reload_dir = true;
1147#ifdef HAVE_HOTSWAP 881#ifdef HAVE_HOTSWAP
1148 else 882 else
1149 if (!id3db) /* Try reload to catch 'no longer valid' case. */ 883 if (!id3db) /* Try reload to catch 'no longer valid' case. */
1150 reload_dir = true; 884 reload_dir = true;
1151#endif 885#endif
1152#ifdef HAVE_LCD_BITMAP 886#ifdef HAVE_LCD_BITMAP
1153 tree_max_on_screen = recalc_screen_height(); 887 screen_access_update_nb_lines();
1154#endif 888#endif
1155 id3db = check_changed_id3mode(id3db); 889 id3db = check_changed_id3mode(id3db);
1156 restore = true; 890 restore = true;
@@ -1174,8 +908,9 @@ static bool dirbrowse(void)
1174 } 908 }
1175 if (! reload_dir ) 909 if (! reload_dir )
1176 { 910 {
1177 tc.dircursor = 0; 911 gui_synclist_select_item(&tree_lists, 0);
1178 tc.dirstart = 0; 912 gui_synclist_draw(&tree_lists);
913 tc.selected_item = 0;
1179 lastdir[0] = 0; 914 lastdir[0] = 0;
1180 } 915 }
1181 916
@@ -1190,132 +925,88 @@ static bool dirbrowse(void)
1190 925
1191 if (restore || reload_dir) { 926 if (restore || reload_dir) {
1192 /* restore display */ 927 /* restore display */
1193
1194#ifdef HAVE_LCD_BITMAP 928#ifdef HAVE_LCD_BITMAP
1195 tree_max_on_screen = recalc_screen_height(); 929 screen_access_update_nb_lines();
1196#endif 930#endif
1197 931 numentries = update_dir();
1198 /* We need to adjust if the number of lines on screen have
1199 changed because of a status bar change */
1200 if(CURSOR_Y+LINE_Y+tc.dircursor>tree_max_on_screen) {
1201 tc.dirstart++;
1202 tc.dircursor--;
1203 }
1204#ifdef HAVE_LCD_BITMAP
1205 /* the sub-screen might've ruined the margins */
1206 lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and
1207 icon */
1208 lcd_setfont(FONT_UI);
1209#endif
1210 numentries = showdir();
1211 if (currdir[1] && (numentries < 0)) 932 if (currdir[1] && (numentries < 0))
1212 { /* not in root and reload failed */ 933 { /* not in root and reload failed */
1213 reload_root = true; /* try root */ 934 reload_root = true; /* try root */
1214 reload_dir = false; 935 reload_dir = false;
1215 goto check_rescan; 936 goto check_rescan;
1216 } 937 }
1217 update_all = true;
1218 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
1219
1220 need_update = true; 938 need_update = true;
1221 reload_dir = false; 939 reload_dir = false;
1222 } 940 }
941 if(need_update) {
942 tc.selected_item = gui_synclist_get_selected_item_position(&tree_lists);
943 need_update=false;
944 if ( numentries > 0 ) {
945 /* Voice the file if changed */
946 if(lasti != tc.selected_item || restore) {
947 lasti = tc.selected_item;
948 thumbnail_time = -1; /* Cancel whatever we were
949 about to say */
950
951 /* Directory? */
952 if (dircache[tc.selected_item].attr & ATTR_DIRECTORY)
953 {
954 /* play directory thumbnail */
955 switch (global_settings.talk_dir) {
956 case 1: /* dirs as numbers */
957 talk_id(VOICE_DIR, false);
958 talk_number(tc.selected_item+1, true);
959 break;
1223 960
1224 if ( (numentries > 0) && need_update) { 961 case 2: /* dirs spelled */
1225 i = tc.dirstart+tc.dircursor; 962 talk_spell(dircache[tc.selected_item].name,
1226 963 false);
1227 /* if MP3 filter is on, cut off the extension */ 964 break;
1228 if(lasti!=i || restore) {
1229 char* name;
1230 int attr = 0;
1231
1232 if (id3db)
1233 name = ((char**)tc.dircache)[lasti * tc.dentry_size];
1234 else {
1235 struct entry* dc = tc.dircache;
1236 struct entry* e = &dc[lasti];
1237 name = e->name;
1238 attr = e->attr;
1239 }
1240
1241 lcd_stop_scroll();
1242
1243 /* So if lastdircursor and dircursor differ, and then full
1244 screen was not refreshed, restore the previous line */
1245 if ((lastdircursor != tc.dircursor) && !update_all ) {
1246 showfileline(lastdircursor, name, attr, false); /* no scroll */
1247 }
1248 lasti=i;
1249 lastdircursor=tc.dircursor;
1250 thumbnail_time = -1; /* cancel whatever we were about to say */
1251
1252 if (id3db)
1253 name = ((char**)tc.dircache)[lasti * tc.dentry_size];
1254 else {
1255 struct entry* dc = tc.dircache;
1256 struct entry* e = &dc[lasti];
1257 name = e->name;
1258 attr = e->attr;
1259 }
1260 showfileline(tc.dircursor, name, attr, true); /* scroll please */
1261 need_update = true;
1262
1263 if (dircache[i].attr & ATTR_DIRECTORY) /* directory? */
1264 {
1265 /* play directory thumbnail */
1266 switch (global_settings.talk_dir) {
1267 case 1: /* dirs as numbers */
1268 talk_id(VOICE_DIR, false);
1269 talk_number(i+1, true);
1270 break;
1271
1272 case 2: /* dirs spelled */
1273 talk_spell(dircache[i].name, false);
1274 break;
1275 965
1276 case 3: /* thumbnail clip */ 966 case 3: /* thumbnail clip */
1277 /* "schedule" a thumbnail, to have a little dalay */ 967 /* "schedule" a thumbnail, to have a little
1278 thumbnail_time = current_tick + HOVER_DELAY; 968 delay */
1279 break; 969 thumbnail_time = current_tick + HOVER_DELAY;
970 break;
1280 971
1281 default: 972 default:
1282 break; 973 break;
974 }
1283 } 975 }
1284 } 976 else /* file */
1285 else /* file */ 977 {
1286 { 978 switch (global_settings.talk_file) {
1287 switch (global_settings.talk_file) { 979 case 1: /* files as numbers */
1288 case 1: /* files as numbers */ 980 ft_play_filenumber(
1289 ft_play_filenumber(i-tc.dirsindir+1, 981 tc.selected_item-tc.dirsindir+1,
1290 dircache[i].attr & TREE_ATTR_MASK); 982 dircache[tc.selected_item].attr &
1291 break; 983 TREE_ATTR_MASK);
984 break;
1292 985
1293 case 2: /* files spelled */ 986 case 2: /* files spelled */
1294 talk_spell(dircache[i].name, false); 987 talk_spell(dircache[tc.selected_item].name,
1295 break; 988 false);
989 break;
1296 990
1297 case 3: /* thumbnail clip */ 991 case 3: /* thumbnail clip */
1298 /* "schedule" a thumbnail, to have a little delay */ 992 /* "schedule" a thumbnail, to have a little
1299 if (dircache[i].attr & TREE_ATTR_THUMBNAIL) 993 delay */
1300 thumbnail_time = current_tick + HOVER_DELAY; 994 if (dircache[tc.selected_item].attr &
1301 else 995 TREE_ATTR_THUMBNAIL)
1302 /* spell the number as fallback */ 996 thumbnail_time = current_tick + HOVER_DELAY;
1303 talk_spell(dircache[i].name, false); 997 else
1304 break; 998 /* spell the number as fallback */
999 talk_spell(dircache[tc.selected_item].name,
1000 false);
1001 break;
1305 1002
1306 default: 1003 default:
1307 break; 1004 break;
1005 }
1308 } 1006 }
1309 } 1007 }
1310 } 1008 }
1311 } 1009 }
1312
1313 if(need_update) {
1314 lcd_update();
1315
1316 need_update = false;
1317 update_all = false;
1318 }
1319 } 1010 }
1320 1011
1321 return true; 1012 return true;
@@ -1369,7 +1060,7 @@ static bool add_dir(char* dirname, int len, int fd)
1369 int x = strlen(entry->d_name); 1060 int x = strlen(entry->d_name);
1370 unsigned int i; 1061 unsigned int i;
1371 char *cp = strrchr(entry->d_name,'.'); 1062 char *cp = strrchr(entry->d_name,'.');
1372 1063
1373 if (cp) { 1064 if (cp) {
1374 cp++; 1065 cp++;
1375 1066
@@ -1379,6 +1070,7 @@ static bool add_dir(char* dirname, int len, int fd)
1379 if (!strcasecmp(cp, filetypes[i].extension)) 1070 if (!strcasecmp(cp, filetypes[i].extension))
1380 { 1071 {
1381 char buf[8]; 1072 char buf[8];
1073 int i;
1382 write(fd, dirname, strlen(dirname)); 1074 write(fd, dirname, strlen(dirname));
1383 write(fd, "/", 1); 1075 write(fd, "/", 1);
1384 write(fd, entry->d_name, x); 1076 write(fd, entry->d_name, x);
@@ -1387,8 +1079,11 @@ static bool add_dir(char* dirname, int len, int fd)
1387 plsize++; 1079 plsize++;
1388 snprintf(buf, sizeof buf, "%d", plsize); 1080 snprintf(buf, sizeof buf, "%d", plsize);
1389#ifdef HAVE_LCD_BITMAP 1081#ifdef HAVE_LCD_BITMAP
1390 lcd_puts(0,4,buf); 1082 for(i = 0;i < NB_SCREENS;++i)
1391 lcd_update(); 1083 {
1084 screens[i].puts(0,4,buf);
1085 screens[i].update();
1086 }
1392#else 1087#else
1393 x = 10; 1088 x = 10;
1394 if (plsize > 999) 1089 if (plsize > 999)
@@ -1401,7 +1096,8 @@ static bool add_dir(char* dirname, int len, int fd)
1401 x=9; 1096 x=9;
1402 } 1097 }
1403 } 1098 }
1404 lcd_puts(x,0,buf); 1099 for(i = 0;i < NB_SCREENS;++i)
1100 screens[i].puts(x,0,buf);
1405#endif 1101#endif
1406 break; 1102 break;
1407 } 1103 }
@@ -1418,16 +1114,20 @@ static bool add_dir(char* dirname, int len, int fd)
1418bool create_playlist(void) 1114bool create_playlist(void)
1419{ 1115{
1420 int fd; 1116 int fd;
1117 int i;
1421 char filename[MAX_PATH]; 1118 char filename[MAX_PATH];
1422 1119
1423 snprintf(filename, sizeof filename, "%s.m3u", 1120 snprintf(filename, sizeof filename, "%s.m3u",
1424 tc.currdir[1] ? tc.currdir : "/root"); 1121 tc.currdir[1] ? tc.currdir : "/root");
1425 1122 for(i = 0;i < NB_SCREENS;++i)
1426 lcd_clear_display(); 1123 {
1427 lcd_puts(0,0,str(LANG_CREATING)); 1124 screens[i].clear_display();
1428 lcd_puts_scroll(0,1,filename); 1125 screens[i].puts(0,0,str(LANG_CREATING));
1429 lcd_update(); 1126 screens[i].puts_scroll(0,1,filename);
1430 1127#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
1128 screens[i].update();
1129#endif
1130 }
1431 fd = creat(filename,0); 1131 fd = creat(filename,0);
1432 if (fd < 0) 1132 if (fd < 0)
1433 return false; 1133 return false;
@@ -1435,7 +1135,7 @@ bool create_playlist(void)
1435#ifdef HAVE_ADJUSTABLE_CPU_FREQ 1135#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1436 cpu_boost(true); 1136 cpu_boost(true);
1437#endif 1137#endif
1438 1138
1439 snprintf(filename, sizeof(filename), "%s", 1139 snprintf(filename, sizeof(filename), "%s",
1440 tc.currdir[1] ? tc.currdir : "/"); 1140 tc.currdir[1] ? tc.currdir : "/");
1441 plsize = 0; 1141 plsize = 0;
@@ -1445,7 +1145,7 @@ bool create_playlist(void)
1445#ifdef HAVE_ADJUSTABLE_CPU_FREQ 1145#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1446 cpu_boost(false); 1146 cpu_boost(false);
1447#endif 1147#endif
1448 1148
1449 sleep(HZ); 1149 sleep(HZ);
1450 1150
1451 return true; 1151 return true;
@@ -1460,12 +1160,10 @@ bool rockbox_browse(const char *root, int dirfilter)
1460 memcpy(tc.currdir, root, sizeof(tc.currdir)); 1160 memcpy(tc.currdir, root, sizeof(tc.currdir));
1461 start_wps = false; 1161 start_wps = false;
1462 tc.dirfilter = &dirfilter; 1162 tc.dirfilter = &dirfilter;
1463 1163
1464 dirbrowse(); 1164 dirbrowse();
1465 1165
1466 tc = backup; 1166 tc = backup;
1467 reload_dir = true;
1468
1469 return false; 1167 return false;
1470} 1168}
1471 1169
@@ -1474,7 +1172,7 @@ void tree_init(void)
1474 /* We copy the settings value in case it is changed by the user. We can't 1172 /* We copy the settings value in case it is changed by the user. We can't
1475 use it until the next reboot. */ 1173 use it until the next reboot. */
1476 max_files = global_settings.max_files_in_dir; 1174 max_files = global_settings.max_files_in_dir;
1477 1175
1478 /* initialize tree context struct */ 1176 /* initialize tree context struct */
1479 memset(&tc, 0, sizeof(tc)); 1177 memset(&tc, 0, sizeof(tc));
1480 tc.dirfilter = &global_settings.dirfilter; 1178 tc.dirfilter = &global_settings.dirfilter;
@@ -1498,7 +1196,7 @@ void bookmark_play(char *resume_file, int index, int offset, int seed,
1498 { 1196 {
1499 /* Playlist playback */ 1197 /* Playlist playback */
1500 char* slash; 1198 char* slash;
1501 // check that the file exists 1199 /* check that the file exists */
1502 int fd = open(resume_file, O_RDONLY); 1200 int fd = open(resume_file, O_RDONLY);
1503 if(fd<0) 1201 if(fd<0)
1504 return; 1202 return;
@@ -1538,7 +1236,7 @@ void bookmark_play(char *resume_file, int index, int offset, int seed,
1538 if ((strcmp(strrchr(playlist_peek(index) + 1,'/') + 1, 1236 if ((strcmp(strrchr(playlist_peek(index) + 1,'/') + 1,
1539 filename))) 1237 filename)))
1540 { 1238 {
1541 for ( i=0; i < playlist_amount(); i++ ) 1239 for ( i=0; i < playlist_amount(); i++ )
1542 { 1240 {
1543 if ((strcmp(strrchr(playlist_peek(i) + 1,'/') + 1, 1241 if ((strcmp(strrchr(playlist_peek(i) + 1,'/') + 1,
1544 filename)) == 0) 1242 filename)) == 0)
@@ -1599,7 +1297,7 @@ int ft_play_dirname(int start_index)
1599 } 1297 }
1600 1298
1601 close(fd); 1299 close(fd);
1602 1300
1603 DEBUGF("Found: %s\n", dirname_mp3_filename); 1301 DEBUGF("Found: %s\n", dirname_mp3_filename);
1604 1302
1605 talk_file(dirname_mp3_filename, false); 1303 talk_file(dirname_mp3_filename, false);
@@ -1639,9 +1337,7 @@ void tree_flush(void)
1639 if (global_settings.dircache) 1337 if (global_settings.dircache)
1640 { 1338 {
1641 if (dircache_is_enabled()) 1339 if (dircache_is_enabled())
1642 {
1643 global_settings.dircache_size = dircache_get_cache_size(); 1340 global_settings.dircache_size = dircache_get_cache_size();
1644 }
1645 dircache_disable(); 1341 dircache_disable();
1646 } 1342 }
1647 else 1343 else
@@ -1659,21 +1355,27 @@ void tree_restore(void)
1659#ifdef HAVE_DIRCACHE 1355#ifdef HAVE_DIRCACHE
1660 if (global_settings.dircache) 1356 if (global_settings.dircache)
1661 { 1357 {
1662 int font_w, font_h;
1663
1664 /* Print "Scanning disk..." to the display. */ 1358 /* Print "Scanning disk..." to the display. */
1665 lcd_getstringsize("A", &font_w, &font_h); 1359 int i;
1666 lcd_putsxy((LCD_WIDTH/2) - ((strlen(str(LANG_DIRCACHE_BUILDING))*font_w)/2), 1360 for(i = 0;i < NB_SCREENS;++i)
1667 LCD_HEIGHT-font_h*3, str(LANG_DIRCACHE_BUILDING)); 1361 {
1668 lcd_update(); 1362 screens[i].putsxy((LCD_WIDTH/2) -
1669 1363 ((strlen(str(LANG_DIRCACHE_BUILDING)) *
1364 screens[i].char_width)/2),
1365 LCD_HEIGHT-screens[i].char_height*3,
1366 str(LANG_DIRCACHE_BUILDING));
1367 screens[i].update();
1368 }
1670 dircache_build(global_settings.dircache_size); 1369 dircache_build(global_settings.dircache_size);
1671
1672 /* Clean the text when we are done. */ 1370 /* Clean the text when we are done. */
1673 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 1371 for(i=0;i<NB_SCREENS;++i)
1674 lcd_fillrect(0, LCD_HEIGHT-font_h*3, LCD_WIDTH, font_h); 1372 {
1675 lcd_set_drawmode(DRMODE_SOLID); 1373 screens[i].set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1676 lcd_update(); 1374 screens[i].fillrect(0, LCD_HEIGHT-screens[i].char_height*3,
1375 LCD_WIDTH, screens[i].char_height);
1376 screens[i].set_drawmode(DRMODE_SOLID);
1377 screens[i].update();
1378 }
1677 } 1379 }
1678#endif 1380#endif
1679} 1381}