Merge lp:~tpeeters/ubuntu-ui-toolkit/75-sectionsScroll into lp:ubuntu-ui-toolkit/staging

Proposed by Tim Peeters on 2016-03-01
Status: Merged
Approved by: Andrea Bernabei on 2016-03-02
Approved revision: 1884
Merged at revision: 1879
Proposed branch: lp:~tpeeters/ubuntu-ui-toolkit/75-sectionsScroll
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 202 lines (+90/-29)
2 files modified
src/Ubuntu/Components/Themes/Ambiance/1.3/SectionsStyle.qml (+34/-28)
tests/unit_x11/tst_components/tst_sections.qml (+56/-1)
To merge this branch: bzr merge lp:~tpeeters/ubuntu-ui-toolkit/75-sectionsScroll
Reviewer Review Type Date Requested Status
ubuntu-sdk-build-bot continuous-integration Approve on 2016-03-02
Ubuntu SDK team 2016-03-01 Pending
Review via email: mp+287620@code.launchpad.net

Commit Message

Properly disable left/right arrows on sections when at the beginning/end of the list.

To post a comment you must log in.
Andrea Bernabei (faenil) wrote :

just a quick comment, but I'd have to read the logic again to see if the change makes sense.

Andrea Bernabei (faenil) wrote :

I left more comments.

- you can avoid setting "enabled" as Icon is not a component with an active input handler anyway.

- I vote against changing the hovering logic, hoveringLeft should be true when the mouse hovers over the left arrow, even if the arrow is currently disabled, because the mouse is effectively hovering over it.

- instead of changing the semantics of hoveringLeft/Right, I think it would be better to handle this in onPressed, where you can check for hoveringLeft/Right and atXBeginning/End

Tim Peeters (tpeeters) wrote :

> I left more comments.

I replied to the inline comments inline.
>
> - you can avoid setting "enabled" as Icon is not a component with an active
> input handler anyway.
>
> - I vote against changing the hovering logic, hoveringLeft should be true when
> the mouse hovers over the left arrow, even if the arrow is currently disabled,
> because the mouse is effectively hovering over it.

I will change the logic to only check the mouse position when the mouse is pressed. It is not needed to check it whenever the mouse moves.

>
> - instead of changing the semantics of hoveringLeft/Right, I think it would be
> better to handle this in onPressed, where you can check for hoveringLeft/Right
> and atXBeginning/End

Right :) That's what I commented below (I didn't read this yet).

1875. By Tim Peeters on 2016-03-01

improve left/right button hover detection and action

1876. By Tim Peeters on 2016-03-01

remove enabled binding

1877. By Tim Peeters on 2016-03-01

clean

1878. By Tim Peeters on 2016-03-01

comment

Andrea Bernabei (faenil) wrote :

thanks.

I liked the hovering logic more, but it's your choice ;)

Maybe rename pressed(mouse) to "contains(mouse)"?

Andrea Bernabei (faenil) wrote :

also, it's missing unit tests

Andrea Bernabei (faenil) wrote :

actually, no, I think the logic you changed is broken.

Not updating onPositionChanged means that you can press on right arrow, then move your mouse to the left arrow, then release, and that will trigger a click on the *right* arrow

1879. By Tim Peeters on 2016-03-01

rename pressed() to contains()

1880. By Tim Peeters on 2016-03-01

fix logic

1881. By Tim Peeters on 2016-03-01

update comment

1882. By Tim Peeters on 2016-03-02

add unit test

Andrea Bernabei (faenil) wrote :

commented, it would be good to also have a test for press + release on the other icon, since that was a bug that was about to get released :)

1883. By Tim Peeters on 2016-03-02

add unit test

1884. By Tim Peeters on 2016-03-02

add another unit test

Andrea Bernabei (faenil) wrote :

lgtm! thanks :)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/SectionsStyle.qml'
2--- src/Ubuntu/Components/Themes/Ambiance/1.3/SectionsStyle.qml 2016-02-29 16:02:50 +0000
3+++ src/Ubuntu/Components/Themes/Ambiance/1.3/SectionsStyle.qml 2016-03-02 16:09:27 +0000
4@@ -236,6 +236,7 @@
5 }
6
7 SmoothedAnimation {
8+ objectName: "sections_scroll_animation"
9 id: contentXAnim
10 target: sectionsListView
11 property: "contentX"
12@@ -251,48 +252,47 @@
13
14 property real iconsDisabledOpacity: 0.3
15
16- property bool hoveringLeft: false
17- property bool hoveringRight: false
18-
19- function checkHovering(mouse) {
20- if (mouse.x < listViewContainer.listViewMargins) {
21- if (!hoveringLeft) hoveringLeft = true;
22- } else if (mouse.x > width - listViewContainer.listViewMargins) {
23- if (!hoveringRight) hoveringRight = true;
24- } else {
25- hoveringLeft = false;
26- hoveringRight = false;
27- }
28- }
29-
30 anchors.fill: parent
31 hoverEnabled: true
32
33- onPositionChanged: checkHovering(mouse)
34- onExited: {
35- hoveringLeft = false;
36- hoveringRight = false;
37- }
38+ property bool pressedLeft: false
39+ property bool pressedRight: false
40 onPressed: {
41- if (!hoveringLeft && !hoveringRight) {
42- mouse.accepted = false;
43- }
44+ pressedLeft = leftIcon.contains(mouse);
45+ pressedRight = rightIcon.contains(mouse);
46+ mouse.accepted = pressedLeft || pressedRight;
47 }
48 onClicked: {
49 // positionViewAtIndex() does not provide animation
50+ var scrollDirection = 0;
51+ if (pressedLeft && leftIcon.contains(mouse)) {
52+ scrollDirection = -1;
53+ } else if (pressedRight && rightIcon.contains(mouse)) {
54+ scrollDirection = 1;
55+ } else {
56+ // User pressed on the left or right icon, and then released inside of the
57+ // MouseArea but outside of the icon that was pressed.
58+ return;
59+ }
60 if (contentXAnim.running) contentXAnim.stop();
61- var newContentX = sectionsListView.contentX + (sectionsListView.width * (hoveringLeft ? -1 : 1));
62+ var newContentX = sectionsListView.contentX + (sectionsListView.width * scrollDirection);
63 contentXAnim.from = sectionsListView.contentX;
64 // make sure we don't overshoot bounds
65 contentXAnim.to = MathUtils.clamp(
66 newContentX,
67- sectionsListView.originX,
68+ 0.0, // estimation of originX is some times wrong when scrolling towards the beginning
69 sectionsListView.originX + sectionsListView.contentWidth - sectionsListView.width);
70 contentXAnim.start();
71 }
72
73 Icon {
74- id: leftHoveringIcon
75+ id: leftIcon
76+ objectName: "left_scroll_icon"
77+ // return whether the pressed event was done inside the area of the icon
78+ function contains(mouse) {
79+ return (mouse.x < listViewContainer.listViewMargins &&
80+ !sectionsListView.atXBeginning);
81+ }
82 anchors {
83 left: parent.left
84 leftMargin: (listViewContainer.listViewMargins - width) / 2
85@@ -315,7 +315,13 @@
86 }
87
88 Icon {
89- id: rightHoveringIcon
90+ id: rightIcon
91+ objectName: "right_scroll_icon"
92+ // return whether the pressed event was done inside the area of the icon
93+ function contains(mouse) {
94+ return (mouse.x > (hoveringArea.width - listViewContainer.listViewMargins) &&
95+ !sectionsListView.atXEnd);
96+ }
97 anchors {
98 right: parent.right
99 rightMargin: (listViewContainer.listViewMargins - width) / 2
100@@ -387,8 +393,8 @@
101 when: hoveringArea.containsMouse
102 PropertyChanges { target: mask; visible: true }
103 PropertyChanges { target: listViewContainer; opacity: 0.0 }
104- PropertyChanges { target: leftHoveringIcon; visible: true; }
105- PropertyChanges { target: rightHoveringIcon; visible: true; }
106+ PropertyChanges { target: leftIcon; visible: true; }
107+ PropertyChanges { target: rightIcon; visible: true; }
108 }
109 ]
110 }
111
112=== modified file 'tests/unit_x11/tst_components/tst_sections.qml'
113--- tests/unit_x11/tst_components/tst_sections.qml 2016-02-19 11:18:51 +0000
114+++ tests/unit_x11/tst_components/tst_sections.qml 2016-03-02 16:09:27 +0000
115@@ -15,6 +15,7 @@
116 */
117
118 import QtQuick 2.4
119+import QtTest 1.0
120 import Ubuntu.Test 1.0
121 import Ubuntu.Components 1.3
122
123@@ -88,6 +89,7 @@
124 Sections {
125 id: enabledSections
126 actions: root.actionList
127+ width: parent.width // set width > implicitWidth to test for bug 1551356 below.
128 }
129 Sections {
130 id: disabledSections
131@@ -158,10 +160,16 @@
132 enabledStringSections.selectedIndex = 0;
133 disabledStringSections.selectedIndex = 0;
134 label.text = "No action triggered."
135+ wait_for_animation(enabledSections);
136 }
137
138 function wait_for_animation(sections) {
139- // TODO when animations are added
140+ var listView = findChild(sections, "sections_listview");
141+ if (!listView.moving) {
142+ // wait for potential animation to start
143+ wait(100);
144+ }
145+ tryCompare(listView, "moving", false, 2000);
146 }
147
148 function get_number_of_section_buttons(sections) {
149@@ -364,6 +372,53 @@
150 wait_for_animation(selectedIndexSections);
151 }
152
153+ SignalSpy {
154+ id: contentXChangedSpy
155+ signalName: "contentXChanged"
156+ }
157+ function test_click_disabled_scroll_button_bug1551356() {
158+ var listView = findChild(enabledSections, "sections_listview");
159+ var icon = findChild(enabledSections, "left_scroll_icon");
160+ contentXChangedSpy.target = listView;
161+ contentXChangedSpy.clear();
162+ compare(listView.contentX, 0.0, "listView is not at the leftmost position initially.");
163+ mouseClick(icon, icon.width/2, icon.height/2);
164+ wait(200); // give the listview ample time to scroll
165+ compare(contentXChangedSpy.count, 0,
166+ "listView moved when clicking disabled scroll button.");
167+ contentXChangedSpy.clear();
168+ contentXChangedSpy.target = null;
169+ }
170+
171+ SignalSpy {
172+ id: animationStartedSpy
173+ signalName: "started"
174+ }
175+ function test_press_release_on_different_icons() {
176+ var leftIcon = findChild(scrollingSections, "left_scroll_icon");
177+ var rightIcon = findChild(scrollingSections, "right_scroll_icon");
178+ var animation = findInvisibleChild(scrollingSections, "sections_scroll_animation");
179+ animationStartedSpy.target = animation;
180+ compare(leftIcon.width, rightIcon.width, "Scroll icons are not the same width.");
181+ compare(leftIcon.height, rightIcon.height, "Scroll icons are not the same height.");
182+ var w = leftIcon.width / 2;
183+ var h = leftIcon.height / 2;
184+ mouseMove(leftIcon, w, h);
185+ mousePress(leftIcon, w, h);
186+ mouseMove(rightIcon, w, h);
187+ mouseRelease(rightIcon, w, h);
188+ wait(200);
189+ compare(animationStartedSpy.count, 0,
190+ "Clicked signal came after pressing left icon and releasing on right icon.");
191+ mousePress(rightIcon, w, h);
192+ mouseMove(leftIcon, w, h);
193+ mouseRelease(leftIcon, w, h);
194+ wait(200);
195+ compare(animationStartedSpy.count, 0,
196+ "Clicked signal came after pressing right icon and releasing on left icon.");
197+ animationStartedSpy.target = null;
198+ }
199+
200 function test_keyboard_navigation_data() {
201 return [
202 { tag: "actions",

Subscribers

People subscribed via source and target branches