summaryrefslogtreecommitdiff
path: root/apps/gui/bitmap/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/bitmap/list.c')
-rw-r--r--apps/gui/bitmap/list.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index db8e0504d7..ff0f5a29c1 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -50,7 +50,6 @@
50static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS]; 50static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS];
51 51
52#ifdef HAVE_TOUCHSCREEN 52#ifdef HAVE_TOUCHSCREEN
53static int y_offset;
54static bool hide_selection; 53static bool hide_selection;
55#endif 54#endif
56 55
@@ -170,12 +169,9 @@ void list_draw(struct screen *display, struct gui_synclist *list)
170 end = start + nb_lines; 169 end = start + nb_lines;
171 170
172#ifdef HAVE_TOUCHSCREEN 171#ifdef HAVE_TOUCHSCREEN
173 if (list->selected_item == 0 || (list->nb_items < nb_lines)) 172 int draw_offset = list_start_item * linedes.height - list->y_pos;
174 y_offset = 0; /* reset in case it's a new list */
175
176 int draw_offset = y_offset;
177 /* draw some extra items to not have empty lines at the top and bottom */ 173 /* draw some extra items to not have empty lines at the top and bottom */
178 if (y_offset > 0) 174 if (draw_offset > 0)
179 { 175 {
180 /* make it negative for more consistent apparence when switching 176 /* make it negative for more consistent apparence when switching
181 * directions */ 177 * directions */
@@ -183,7 +179,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
183 if (start > 0) 179 if (start > 0)
184 start--; 180 start--;
185 } 181 }
186 else if (y_offset < 0) 182 else if (draw_offset < 0)
187 end++; 183 end++;
188#else 184#else
189 #define draw_offset 0 185 #define draw_offset 0
@@ -367,7 +363,6 @@ static int scrollbar_scroll(struct gui_synclist * gui_list, int y)
367 if (nb_lines < gui_list->nb_items) 363 if (nb_lines < gui_list->nb_items)
368 { 364 {
369 /* scrollbar scrolling is still line based */ 365 /* scrollbar scrolling is still line based */
370 y_offset = 0;
371 int scrollbar_size = nb_lines * gui_list->line_height[screen]; 366 int scrollbar_size = nb_lines * gui_list->line_height[screen];
372 int actual_y = y - list_text[screen].y; 367 int actual_y = y - list_text[screen].y;
373 int new_selection = (actual_y * gui_list->nb_items) / scrollbar_size; 368 int new_selection = (actual_y * gui_list->nb_items) / scrollbar_size;
@@ -379,6 +374,7 @@ static int scrollbar_scroll(struct gui_synclist * gui_list, int y)
379 start_item = gui_list->nb_items - nb_lines; 374 start_item = gui_list->nb_items - nb_lines;
380 375
381 gui_list->start_item[screen] = start_item; 376 gui_list->start_item[screen] = start_item;
377 gui_list->y_pos = start_item * gui_list->line_height[screen];
382 378
383 return ACTION_REDRAW; 379 return ACTION_REDRAW;
384 } 380 }
@@ -468,9 +464,11 @@ static void kinetic_force_stop(void)
468 464
469/* helper for gui/list.c to cancel scrolling if a normal button event comes 465/* helper for gui/list.c to cancel scrolling if a normal button event comes
470 * through dpad or keyboard or whatever */ 466 * through dpad or keyboard or whatever */
471void _gui_synclist_stop_kinetic_scrolling(void) 467void _gui_synclist_stop_kinetic_scrolling(struct gui_synclist * gui_list)
472{ 468{
473 y_offset = 0; 469 const enum screen_type screen = screens[SCREEN_MAIN].screen_type;
470 gui_list->y_pos = gui_list->start_item[screen] * gui_list->line_height[screen];
471
474 if (scroll_mode == SCROLL_KINETIC) 472 if (scroll_mode == SCROLL_KINETIC)
475 kinetic_force_stop(); 473 kinetic_force_stop();
476 scroll_mode = SCROLL_NONE; 474 scroll_mode = SCROLL_NONE;
@@ -512,22 +510,25 @@ static bool swipe_scroll(struct gui_synclist * gui_list, int difference)
512 int new_start_item = -1; 510 int new_start_item = -1;
513 int line_diff = 0; 511 int line_diff = 0;
514 512
515 /* don't scroll at the edges of the list */ 513 /* Track whether we hit the end of the list for sake of kinetic scroll */
516 if ((old_start == 0 && difference > 0) 514 bool hit_end = true;
517 || (old_start == (gui_list->nb_items - nb_lines) && difference < 0))
518 {
519 y_offset = 0;
520 gui_list->start_item[screen] = old_start;
521 return scroll_mode != SCROLL_KINETIC; /* stop kinetic at the edges */
522 }
523 515
524 /* add up y_offset over time and translate to lines 516 /* Move the y position and clamp it (funny things happen otherwise...) */
525 * if scrolled enough */ 517 gui_list->y_pos -= difference;
526 y_offset += difference; 518 if(gui_list->y_pos < 0)
527 if (abs(y_offset) > line_height) 519 gui_list->y_pos = 0;
520 else if(gui_list->y_pos > (gui_list->nb_items - nb_lines) * line_height)
521 gui_list->y_pos = (gui_list->nb_items - nb_lines) * line_height;
522 else
523 hit_end = false;
524
525 /* Get the list y position. When pos_y differs by a line height or more,
526 * we need to scroll the list by adjusting the start item accordingly */
527 int cur_y = gui_list->start_item[screen] * line_height;
528 int diff_y = cur_y - gui_list->y_pos;
529 if (abs(diff_y) >= line_height)
528 { 530 {
529 line_diff = y_offset/line_height; 531 line_diff = diff_y/line_height;
530 y_offset -= line_diff * line_height;
531 } 532 }
532 533
533 if(line_diff != 0) 534 if(line_diff != 0)
@@ -548,7 +549,10 @@ static bool swipe_scroll(struct gui_synclist * gui_list, int difference)
548 gui_list->selected_item -= (gui_list->selected_item % gui_list->selected_size); 549 gui_list->selected_item -= (gui_list->selected_item % gui_list->selected_size);
549 } 550 }
550 551
551 return true; 552 if(hit_end)
553 return scroll_mode != SCROLL_KINETIC;
554 else
555 return true;
552} 556}
553 557
554static int kinetic_callback(struct timeout *tmo) 558static int kinetic_callback(struct timeout *tmo)
@@ -729,7 +733,8 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * list)
729 if(!skinlist_get_item(&screens[screen], list, adj_x, adj_y, &line)) 733 if(!skinlist_get_item(&screens[screen], list, adj_x, adj_y, &line))
730 { 734 {
731 /* selection needs to be corrected if items are only partially visible */ 735 /* selection needs to be corrected if items are only partially visible */
732 line = (adj_y - y_offset) / line_height; 736 int cur_y = list->start_item[screen] * line_height;
737 line = (adj_y - (cur_y - list->y_pos)) / line_height;
733 if (list_display_title(list, screen)) 738 if (list_display_title(list, screen))
734 line -= 1; /* adjust for the list title */ 739 line -= 1; /* adjust for the list title */
735 } 740 }