summaryrefslogtreecommitdiff
path: root/apps/gui/bitmap/list.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-01-17 23:26:37 +0100
committerThomas Martitz <kugel@rockbox.org>2013-01-17 23:29:35 +0100
commit2ffde90c690aa07072bd09bbf9697e2795eee087 (patch)
tree6ec16d29ede31c3ca137951c31ce7fd5b3435b47 /apps/gui/bitmap/list.c
parent9b7edbf6099dfad735c0808768179663f8a38666 (diff)
downloadrockbox-2ffde90c690aa07072bd09bbf9697e2795eee087.tar.gz
rockbox-2ffde90c690aa07072bd09bbf9697e2795eee087.zip
touchscreen: Fix kinetic and swipe scrolling outside of the list viewport.
There were some bugs, especially when the user scrolled above the list viewport. One bug made Rockbox completely unusable once triggered. Change-Id: I9bb4722ff4381db189058e9a19ea30b2c69e87d9
Diffstat (limited to 'apps/gui/bitmap/list.c')
-rw-r--r--apps/gui/bitmap/list.c116
1 files changed, 59 insertions, 57 deletions
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 45e6c03dcf..ae614bf0b6 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -732,7 +732,8 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * list)
732 short x, y; 732 short x, y;
733 int action, adj_x, adj_y, line, line_height, list_start_item; 733 int action, adj_x, adj_y, line, line_height, list_start_item;
734 bool recurse; 734 bool recurse;
735 static int last_y = -1; 735 static bool initial_touch = true;
736 static int last_y;
736 737
737 screen = SCREEN_MAIN; 738 screen = SCREEN_MAIN;
738 parent = list->parent[screen]; 739 parent = list->parent[screen];
@@ -752,67 +753,68 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * list)
752 { 753 {
753 case SCROLL_NONE: 754 case SCROLL_NONE:
754 { 755 {
755 if (last_y == -1) 756 int click_loc;
756 { /* first run. register adj_y and re-run (will then take the else case) */ 757 if (initial_touch)
758 {
759 /* on the first touch last_y has to be reset to avoid
760 * glitches with touches from long ago */
757 last_y = adj_y; 761 last_y = adj_y;
758 recurse = true; 762 initial_touch = false;
759 } 763 }
760 else 764
765 line = 0; /* silence gcc 'used uninitialized' warning */
766 click_loc = get_click_location(list, x, y);
767 if (click_loc & LIST)
761 { 768 {
762 int click_loc = get_click_location(list, x, y); 769 if(!skinlist_get_item(&screens[screen], list, adj_x, adj_y, &line))
763 line = 0; /* silence gcc 'used uninitialized' warning */
764 if (click_loc & LIST)
765 { 770 {
766 if(!skinlist_get_item(&screens[screen], list, adj_x, adj_y, &line)) 771 /* selection needs to be corrected if items are only partially visible */
767 { 772 line = (adj_y - y_offset) / line_height;
768 /* selection needs to be corrected if items are only partially visible */ 773 if (list_display_title(list, screen))
769 line = (adj_y - y_offset) / line_height; 774 line -= 1; /* adjust for the list title */
770 if (list_display_title(list, screen))
771 line -= 1; /* adjust for the list title */
772 }
773 if (line >= list->nb_items)
774 return ACTION_NONE;
775 list->selected_item = list_start_item+line;
776
777 gui_synclist_speak_item(list);
778 } 775 }
779 if (action == BUTTON_TOUCHSCREEN) 776 if (line >= list->nb_items)
777 return ACTION_NONE;
778 list->selected_item = list_start_item+line;
779
780 gui_synclist_speak_item(list);
781 }
782 if (action == BUTTON_TOUCHSCREEN)
783 {
784 /* if not scrolling, the user is trying to select */
785 int diff = adj_y - last_y;
786 if ((click_loc & LIST) && swipe_scroll(list, diff))
787 scroll_mode = SCROLL_SWIPE;
788 else if (click_loc & SCROLLBAR)
789 scroll_mode = SCROLL_BAR;
790 }
791 else if (action == BUTTON_REPEAT)
792 {
793 if (click_loc & LIST)
780 { 794 {
781 /* if not scrolling, the user is trying to select */ 795 /* held a single line for a while, bring up the context menu */
782 int diff = adj_y - last_y; 796 gui_synclist_select_item(list, list_start_item + line);
783 if ((click_loc & LIST) && swipe_scroll(list, diff)) 797 /* don't sent context repeatedly */
784 scroll_mode = SCROLL_SWIPE; 798 action_wait_for_release();
785 else if (click_loc & SCROLLBAR) 799 initial_touch = true;
786 scroll_mode = SCROLL_BAR; 800 return ACTION_STD_CONTEXT;
787 } 801 }
788 else if (action == BUTTON_REPEAT) 802 }
789 { 803 else if (action & BUTTON_REL)
790 if (click_loc & LIST) 804 {
791 { 805 initial_touch = true;
792 /* held a single line for a while, bring up the context menu */ 806 if (click_loc & LIST)
793 gui_synclist_select_item(list, list_start_item + line); 807 { /* release on list item enters it */
794 /* don't sent context repeatedly */ 808 gui_synclist_select_item(list, list_start_item + line);
795 action_wait_for_release(); 809 return ACTION_STD_OK;
796 last_y = -1;
797 return ACTION_STD_CONTEXT;
798 }
799 } 810 }
800 else if (action & BUTTON_REL) 811 else if (click_loc & TITLE_TEXT)
801 { 812 { /* clicking the title goes one level up (cancel) */
802 last_y = -1; 813 return ACTION_STD_CANCEL;
803 if (click_loc & LIST) 814 }
804 { /* release on list item enters it */ 815 else if (click_loc & TITLE_ICON)
805 gui_synclist_select_item(list, list_start_item + line); 816 { /* clicking the title icon goes back to the root */
806 return ACTION_STD_OK; 817 return ACTION_STD_MENU;
807 }
808 else if (click_loc & TITLE_TEXT)
809 { /* clicking the title goes one level up (cancel) */
810 return ACTION_STD_CANCEL;
811 }
812 else if (click_loc & TITLE_ICON)
813 { /* clicking the title icon goes back to the root */
814 return ACTION_STD_MENU;
815 }
816 } 818 }
817 } 819 }
818 break; 820 break;
@@ -842,7 +844,7 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * list)
842 scroll_mode = SCROLL_NONE; 844 scroll_mode = SCROLL_NONE;
843 845
844 if (scroll_mode == SCROLL_NONE) 846 if (scroll_mode == SCROLL_NONE)
845 last_y = -1; 847 initial_touch = true;
846 break; 848 break;
847 } 849 }
848 case SCROLL_KINETIC: 850 case SCROLL_KINETIC:
@@ -879,8 +881,8 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * list)
879 } 881 }
880 } 882 }
881 883
882 /* register y position unless forcefully reset to 1- */ 884 /* register y position unless forcefully reset */
883 if (last_y >= 0) 885 if (!initial_touch)
884 last_y = adj_y; 886 last_y = adj_y;
885 887
886 return recurse ? gui_synclist_do_touchscreen(list) : ACTION_REDRAW; 888 return recurse ? gui_synclist_do_touchscreen(list) : ACTION_REDRAW;