diff options
author | Thomas Martitz <kugel@rockbox.org> | 2013-01-17 23:26:37 +0100 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2013-01-17 23:29:35 +0100 |
commit | 2ffde90c690aa07072bd09bbf9697e2795eee087 (patch) | |
tree | 6ec16d29ede31c3ca137951c31ce7fd5b3435b47 /apps/gui/bitmap/list.c | |
parent | 9b7edbf6099dfad735c0808768179663f8a38666 (diff) | |
download | rockbox-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.c | 116 |
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; |