diff options
author | Teruaki Kawashima <teru@rockbox.org> | 2010-11-03 13:34:58 +0000 |
---|---|---|
committer | Teruaki Kawashima <teru@rockbox.org> | 2010-11-03 13:34:58 +0000 |
commit | 45fa8245eaf3f8d8a2ff95eae7509a9d3af26c3d (patch) | |
tree | 0da768b27148b60a1fdc6494c2601ea68b8e2ee6 /apps/plugins/pictureflow | |
parent | f6cf295dd3c79eb26842c54e22007ded8e226023 (diff) | |
download | rockbox-45fa8245eaf3f8d8a2ff95eae7509a9d3af26c3d.tar.gz rockbox-45fa8245eaf3f8d8a2ff95eae7509a9d3af26c3d.zip |
FS#11673: picture flow: improve scrolling text, by myself.
implement scroll engine in the plugin similar to the one in core.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28474 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pictureflow')
-rw-r--r-- | apps/plugins/pictureflow/pictureflow.c | 144 |
1 files changed, 108 insertions, 36 deletions
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index 9fb2bd4a76..2ee318ba6a 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c | |||
@@ -294,6 +294,25 @@ struct load_slide_event_data { | |||
294 | int cache_index; | 294 | int cache_index; |
295 | }; | 295 | }; |
296 | 296 | ||
297 | enum pf_scroll_line_type { | ||
298 | PF_SCROLL_TRACK = 0, | ||
299 | PF_SCROLL_ALBUM, | ||
300 | PF_MAX_SCROLL_LINES | ||
301 | }; | ||
302 | |||
303 | struct pf_scroll_line_info { | ||
304 | long ticks; /* number of ticks between each move */ | ||
305 | long delay; /* number of ticks to delay starting scrolling */ | ||
306 | int step; /* pixels to move */ | ||
307 | long next_scroll; /* tick of the next move */ | ||
308 | }; | ||
309 | |||
310 | struct pf_scroll_line { | ||
311 | int width; /* width of the string */ | ||
312 | int offset; /* x coordinate of the string */ | ||
313 | int step; /* 0 if scroll is disabled. otherwise, pixels to move */ | ||
314 | long start_tick; /* tick when to start scrolling */ | ||
315 | }; | ||
297 | 316 | ||
298 | struct pfraw_header { | 317 | struct pfraw_header { |
299 | int32_t width; /* bmap width in pixels */ | 318 | int32_t width; /* bmap width in pixels */ |
@@ -408,17 +427,15 @@ static bool thread_is_running; | |||
408 | static int cover_animation_keyframe; | 427 | static int cover_animation_keyframe; |
409 | static int extra_fade; | 428 | static int extra_fade; |
410 | 429 | ||
411 | static int albumtxt_x = 0; | 430 | static struct pf_scroll_line_info scroll_line_info; |
412 | static int albumtxt_dir = -1; | 431 | static struct pf_scroll_line scroll_lines[PF_MAX_SCROLL_LINES]; |
413 | static int prev_albumtxt_index = -1; | 432 | static int prev_albumtxt_index = -1; |
433 | static int last_selected_track = -1; | ||
414 | 434 | ||
415 | static int start_index_track_list = 0; | 435 | static int start_index_track_list = 0; |
416 | static int track_list_visible_entries = 0; | 436 | static int track_list_visible_entries = 0; |
417 | static int track_list_y; | 437 | static int track_list_y; |
418 | static int track_list_h; | 438 | static int track_list_h; |
419 | static int track_scroll_x = 0; | ||
420 | static int track_scroll_dir = 1; | ||
421 | static int last_selected_track; | ||
422 | 439 | ||
423 | /* | 440 | /* |
424 | Proposals for transitions: | 441 | Proposals for transitions: |
@@ -721,6 +738,74 @@ static const struct button_mapping* get_context_map(int context) | |||
721 | return pf_contexts[context & ~CONTEXT_PLUGIN]; | 738 | return pf_contexts[context & ~CONTEXT_PLUGIN]; |
722 | } | 739 | } |
723 | 740 | ||
741 | /* scrolling */ | ||
742 | static void init_scroll_lines(void) | ||
743 | { | ||
744 | int i; | ||
745 | static const char scroll_tick_table[16] = { | ||
746 | /* Hz values: | ||
747 | 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ | ||
748 | 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 | ||
749 | }; | ||
750 | |||
751 | scroll_line_info.ticks = scroll_tick_table[rb->global_settings->scroll_speed]; | ||
752 | scroll_line_info.step = rb->global_settings->scroll_step; | ||
753 | scroll_line_info.delay = rb->global_settings->scroll_delay / (HZ / 10); | ||
754 | scroll_line_info.next_scroll = *rb->current_tick; | ||
755 | for (i = 0; i < PF_MAX_SCROLL_LINES; i++) | ||
756 | scroll_lines[i].step = 0; | ||
757 | } | ||
758 | |||
759 | static void set_scroll_line(const char *str, enum pf_scroll_line_type type) | ||
760 | { | ||
761 | struct pf_scroll_line *s = &scroll_lines[type]; | ||
762 | s->width = mylcd_getstringsize(str, NULL, NULL); | ||
763 | s->step = 0; | ||
764 | s->offset = 0; | ||
765 | s->start_tick = *rb->current_tick + scroll_line_info.delay; | ||
766 | if (LCD_WIDTH - s->width < 0) | ||
767 | s->step = scroll_line_info.step; | ||
768 | else | ||
769 | s->offset = (LCD_WIDTH - s->width) / 2; | ||
770 | } | ||
771 | |||
772 | static int get_scroll_line_offset(enum pf_scroll_line_type type) | ||
773 | { | ||
774 | return scroll_lines[type].offset; | ||
775 | } | ||
776 | |||
777 | static void update_scroll_lines(void) | ||
778 | { | ||
779 | int i; | ||
780 | |||
781 | if (TIME_BEFORE(*rb->current_tick, scroll_line_info.next_scroll)) | ||
782 | return; | ||
783 | |||
784 | scroll_line_info.next_scroll = *rb->current_tick + scroll_line_info.ticks; | ||
785 | |||
786 | for (i = 0; i < PF_MAX_SCROLL_LINES; i++) | ||
787 | { | ||
788 | struct pf_scroll_line *s = &scroll_lines[i]; | ||
789 | if (s->step && TIME_BEFORE(s->start_tick, *rb->current_tick)) | ||
790 | { | ||
791 | s->offset -= s->step; | ||
792 | |||
793 | if (s->offset >= 0) { | ||
794 | /* at beginning of line */ | ||
795 | s->offset = 0; | ||
796 | s->step = scroll_line_info.step; | ||
797 | s->start_tick = *rb->current_tick + scroll_line_info.delay * 2; | ||
798 | } | ||
799 | if (s->offset <= LCD_WIDTH - s->width) { | ||
800 | /* at end of line */ | ||
801 | s->offset = LCD_WIDTH - s->width; | ||
802 | s->step = -scroll_line_info.step; | ||
803 | s->start_tick = *rb->current_tick + scroll_line_info.delay * 2; | ||
804 | } | ||
805 | } | ||
806 | } | ||
807 | } | ||
808 | |||
724 | /* Create the lookup table with the scaling values for the reflections */ | 809 | /* Create the lookup table with the scaling values for the reflections */ |
725 | void init_reflect_table(void) | 810 | void init_reflect_table(void) |
726 | { | 811 | { |
@@ -2408,29 +2493,23 @@ void show_track_list(void) | |||
2408 | for (;track_i < track_list_visible_entries+start_index_track_list; | 2493 | for (;track_i < track_list_visible_entries+start_index_track_list; |
2409 | track_i++) | 2494 | track_i++) |
2410 | { | 2495 | { |
2411 | mylcd_getstringsize(get_track_name(track_i), &titletxt_w, NULL); | 2496 | char *trackname = get_track_name(track_i); |
2412 | titletxt_x = (LCD_WIDTH-titletxt_w)/2; | ||
2413 | if ( track_i == selected_track ) { | 2497 | if ( track_i == selected_track ) { |
2414 | if (selected_track != last_selected_track) { | 2498 | if (selected_track != last_selected_track) { |
2499 | set_scroll_line(trackname, PF_SCROLL_TRACK); | ||
2415 | last_selected_track = selected_track; | 2500 | last_selected_track = selected_track; |
2416 | track_scroll_x = 0; | ||
2417 | track_scroll_dir = -1; | ||
2418 | } | 2501 | } |
2419 | draw_gradient(titletxt_y, titletxt_h); | 2502 | draw_gradient(titletxt_y, titletxt_h); |
2420 | if (titletxt_w > LCD_WIDTH ) { | 2503 | titletxt_x = get_scroll_line_offset(PF_SCROLL_TRACK); |
2421 | if ( titletxt_w + track_scroll_x <= LCD_WIDTH ) | ||
2422 | track_scroll_dir = 1; | ||
2423 | else if ( track_scroll_x >= 0 ) track_scroll_dir = -1; | ||
2424 | track_scroll_x += track_scroll_dir*2; | ||
2425 | titletxt_x = track_scroll_x; | ||
2426 | } | ||
2427 | color = 255; | 2504 | color = 255; |
2428 | } | 2505 | } |
2429 | else { | 2506 | else { |
2507 | titletxt_w = mylcd_getstringsize(trackname, NULL, NULL); | ||
2508 | titletxt_x = (LCD_WIDTH-titletxt_w)/2; | ||
2430 | color = 250 - (abs(selected_track - track_i) * 200 / track_count); | 2509 | color = 250 - (abs(selected_track - track_i) * 200 / track_count); |
2431 | } | 2510 | } |
2432 | mylcd_set_foreground(G_BRIGHT(color)); | 2511 | mylcd_set_foreground(G_BRIGHT(color)); |
2433 | mylcd_putsxy(titletxt_x,titletxt_y,get_track_name(track_i)); | 2512 | mylcd_putsxy(titletxt_x,titletxt_y,trackname); |
2434 | titletxt_y += titletxt_h; | 2513 | titletxt_y += titletxt_h; |
2435 | } | 2514 | } |
2436 | } | 2515 | } |
@@ -2507,8 +2586,8 @@ void draw_album_text(void) | |||
2507 | return; | 2586 | return; |
2508 | 2587 | ||
2509 | int albumtxt_index; | 2588 | int albumtxt_index; |
2510 | int albumtxt_w, albumtxt_h; | 2589 | int char_height; |
2511 | int albumtxt_y = 0; | 2590 | int albumtxt_x, albumtxt_y; |
2512 | 2591 | ||
2513 | char *albumtxt; | 2592 | char *albumtxt; |
2514 | int c; | 2593 | int c; |
@@ -2532,29 +2611,19 @@ void draw_album_text(void) | |||
2532 | albumtxt = get_album_name(albumtxt_index); | 2611 | albumtxt = get_album_name(albumtxt_index); |
2533 | 2612 | ||
2534 | mylcd_set_foreground(G_BRIGHT(c)); | 2613 | mylcd_set_foreground(G_BRIGHT(c)); |
2535 | mylcd_getstringsize(albumtxt, &albumtxt_w, &albumtxt_h); | ||
2536 | if (albumtxt_index != prev_albumtxt_index) { | 2614 | if (albumtxt_index != prev_albumtxt_index) { |
2537 | albumtxt_x = 0; | 2615 | set_scroll_line(albumtxt, PF_SCROLL_ALBUM); |
2538 | albumtxt_dir = -1; | ||
2539 | prev_albumtxt_index = albumtxt_index; | 2616 | prev_albumtxt_index = albumtxt_index; |
2540 | } | 2617 | } |
2541 | 2618 | ||
2619 | char_height = rb->screens[SCREEN_MAIN]->getcharheight(); | ||
2542 | if (show_album_name == ALBUM_NAME_TOP) | 2620 | if (show_album_name == ALBUM_NAME_TOP) |
2543 | albumtxt_y = albumtxt_h / 2; | 2621 | albumtxt_y = char_height / 2; |
2544 | else | 2622 | else |
2545 | albumtxt_y = LCD_HEIGHT - albumtxt_h - albumtxt_h/2; | 2623 | albumtxt_y = LCD_HEIGHT - char_height - char_height/2; |
2546 | 2624 | ||
2547 | if (albumtxt_w > LCD_WIDTH ) { | 2625 | albumtxt_x = get_scroll_line_offset(PF_SCROLL_ALBUM); |
2548 | mylcd_putsxy(albumtxt_x, albumtxt_y , albumtxt); | 2626 | mylcd_putsxy(albumtxt_x, albumtxt_y, albumtxt); |
2549 | if ( pf_state == pf_idle || pf_state == pf_show_tracks ) { | ||
2550 | if ( albumtxt_w + albumtxt_x <= LCD_WIDTH ) albumtxt_dir = 1; | ||
2551 | else if ( albumtxt_x >= 0 ) albumtxt_dir = -1; | ||
2552 | albumtxt_x += albumtxt_dir; | ||
2553 | } | ||
2554 | } | ||
2555 | else { | ||
2556 | mylcd_putsxy((LCD_WIDTH - albumtxt_w) /2, albumtxt_y , albumtxt); | ||
2557 | } | ||
2558 | } | 2627 | } |
2559 | 2628 | ||
2560 | /** | 2629 | /** |
@@ -2593,6 +2662,7 @@ int main(void) | |||
2593 | backlight_force_on(); /* backlight control in lib/helper.c */ | 2662 | backlight_force_on(); /* backlight control in lib/helper.c */ |
2594 | } | 2663 | } |
2595 | 2664 | ||
2665 | init_scroll_lines(); | ||
2596 | init_reflect_table(); | 2666 | init_reflect_table(); |
2597 | 2667 | ||
2598 | ALIGN_BUFFER(buf, buf_size, 4); | 2668 | ALIGN_BUFFER(buf, buf_size, 4); |
@@ -2682,6 +2752,8 @@ int main(void) | |||
2682 | /* Initial rendering */ | 2752 | /* Initial rendering */ |
2683 | instant_update = false; | 2753 | instant_update = false; |
2684 | 2754 | ||
2755 | update_scroll_lines(); | ||
2756 | |||
2685 | /* Handle states */ | 2757 | /* Handle states */ |
2686 | switch ( pf_state ) { | 2758 | switch ( pf_state ) { |
2687 | case pf_scrolling: | 2759 | case pf_scrolling: |