Merge lp:~aacid/unity8/drag_with_quicklist into lp:unity8

Proposed by Albert Astals Cid
Status: Merged
Approved by: Michael Zanetti
Approved revision: 2075
Merged at revision: 2093
Proposed branch: lp:~aacid/unity8/drag_with_quicklist
Merge into: lp:unity8
Diff against target: 308 lines (+173/-26)
2 files modified
qml/Launcher/LauncherPanel.qml (+57/-21)
tests/qmltests/Launcher/tst_Launcher.qml (+116/-5)
To merge this branch: bzr merge lp:~aacid/unity8/drag_with_quicklist
Reviewer Review Type Date Requested Status
Michał Sawicz Abstain
PS Jenkins bot (community) continuous-integration Needs Fixing
Michael Zanetti (community) Approve
Review via email: mp+279420@code.launchpad.net

Commit message

Allow dragging launcher items with the quicklist open

Description of the change

 * Are there any related MPs required for this MP to build/function as expected?
No

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * Did you make sure that your branch does not contain spurious tags?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
N/A

To post a comment you must log in.
Revision history for this message
Michael Zanetti (mzanetti) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?

yes

 * Did CI run pass? If not, please explain why.

 not yet. waiting with top approval

 * Did you make sure that the branch does not contain spurious tags?

yes

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2075
http://jenkins.qa.ubuntu.com/job/unity8-ci/6873/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5567
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/288/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1584
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/287
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1479
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1479
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/286
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/285
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4361
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5581
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5581/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25765
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/105/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/287
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/287/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25764

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6873/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Steps:
* long-press on icon a)
* long-press on icon b)

Expected:
* there's an animation when quicklist closes on a) and opens on b)

Current:
* quicklist moves from a) to b) abruptly

review: Needs Information
Revision history for this message
Albert Astals Cid (aacid) wrote :

> Steps:
> * long-press on icon a)
> * long-press on icon b)
>
> Expected:
> * there's an animation when quicklist closes on a) and opens on b)
>
> Current:
> * quicklist moves from a) to b) abruptly

That's the same behaviour that happens when right clicking on the launcher when the quicklist is open nowadays. I agree probably the animation looks nicer but not sure it should be part of this bugfix since what I'm doing here is just bring the "pressandhold" behaviour to be the same as the "right click" behaviour.

What do you think, should I try fix both scenarios so that the animations takes place as part of this MR or open a bug about it for the future?

Revision history for this message
Michał Sawicz (saviq) wrote :

Fine with me.

review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/Launcher/LauncherPanel.qml'
2--- qml/Launcher/LauncherPanel.qml 2015-11-26 13:51:53 +0000
3+++ qml/Launcher/LauncherPanel.qml 2015-12-03 10:50:28 +0000
4@@ -384,7 +384,11 @@
5 property int startY
6
7 onPressed: {
8- selectedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY)
9+ processPress(mouse);
10+ }
11+
12+ function processPress(mouse) {
13+ selectedItem = launcherListView.itemAt(mouse.x, mouse.y + launcherListView.realContentY)
14 }
15
16 onClicked: {
17@@ -429,14 +433,14 @@
18 }
19
20 onCanceled: {
21- endDrag();
22+ endDrag(drag);
23 }
24
25 onReleased: {
26- endDrag();
27+ endDrag(drag);
28 }
29
30- function endDrag() {
31+ function endDrag(dragItem) {
32 var droppedIndex = draggedIndex;
33 if (dragging) {
34 postDragging = true;
35@@ -452,7 +456,7 @@
36 selectedItem = undefined;
37 preDragging = false;
38
39- drag.target = undefined
40+ dragItem.target = undefined
41
42 progressiveScrollingTimer.stop();
43 launcherListView.interactive = true;
44@@ -464,13 +468,17 @@
45 }
46
47 onPressAndHold: {
48+ processPressAndHold(mouse, drag);
49+ }
50+
51+ function processPressAndHold(mouse, dragItem) {
52 if (Math.abs(selectedItem.angle) > 30) {
53 return;
54 }
55
56 Haptics.play();
57
58- draggedIndex = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
59+ draggedIndex = Math.floor((mouse.y + launcherListView.realContentY) / launcherListView.realItemHeight);
60
61 // Opening QuickList
62 quickList.item = selectedItem;
63@@ -480,26 +488,30 @@
64
65 launcherListView.interactive = false
66
67- var yOffset = draggedIndex > 0 ? (mouseY + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouseY + launcherListView.realContentY
68+ var yOffset = draggedIndex > 0 ? (mouse.y + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouse.y + launcherListView.realContentY
69
70 fakeDragItem.iconName = launcherListView.model.get(draggedIndex).icon
71 fakeDragItem.x = units.gu(0.5)
72- fakeDragItem.y = mouseY - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin
73+ fakeDragItem.y = mouse.y - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin
74 fakeDragItem.angle = selectedItem.angle * (root.inverted ? -1 : 1)
75 fakeDragItem.offset = selectedItem.offset * (root.inverted ? -1 : 1)
76 fakeDragItem.count = LauncherModel.get(draggedIndex).count
77 fakeDragItem.progress = LauncherModel.get(draggedIndex).progress
78 fakeDragItem.flatten()
79- drag.target = fakeDragItem
80+ dragItem.target = fakeDragItem
81
82- startX = mouseX
83- startY = mouseY
84+ startX = mouse.x
85+ startY = mouse.y
86 }
87
88 onPositionChanged: {
89+ processPositionChanged(mouse)
90+ }
91+
92+ function processPositionChanged(mouse) {
93 if (draggedIndex >= 0) {
94 if (!selectedItem.dragging) {
95- var distance = Math.max(Math.abs(mouseX - startX), Math.abs(mouseY - startY))
96+ var distance = Math.max(Math.abs(mouse.x - startX), Math.abs(mouse.y - startY))
97 if (!preDragging && distance > units.gu(1.5)) {
98 preDragging = true;
99 quickList.state = "";
100@@ -623,15 +635,39 @@
101 source: "graphics/quicklist_tooltip.png"
102 rotation: 90
103 }
104-
105- InverseMouseArea {
106- anchors.fill: parent
107- enabled: quickList.state == "open"
108- onClicked: {
109- quickList.state = ""
110- }
111- }
112-
113+ }
114+ InverseMouseArea {
115+ anchors.fill: quickListShape
116+ enabled: quickList.state == "open" || pressed
117+
118+ onClicked: {
119+ quickList.state = ""
120+ }
121+
122+ // Forward for dragging to work when quickList is open
123+
124+ onPressed: {
125+ var m = mapToItem(dndArea, mouseX, mouseY)
126+ dndArea.processPress(m)
127+ }
128+
129+ onPressAndHold: {
130+ var m = mapToItem(dndArea, mouseX, mouseY)
131+ dndArea.processPressAndHold(m, drag)
132+ }
133+
134+ onPositionChanged: {
135+ var m = mapToItem(dndArea, mouseX, mouseY)
136+ dndArea.processPositionChanged(m)
137+ }
138+
139+ onCanceled: {
140+ dndArea.endDrag(drag);
141+ }
142+
143+ onReleased: {
144+ dndArea.endDrag(drag);
145+ }
146 }
147
148 Rectangle {
149
150=== modified file 'tests/qmltests/Launcher/tst_Launcher.qml'
151--- tests/qmltests/Launcher/tst_Launcher.qml 2015-11-24 17:44:18 +0000
152+++ tests/qmltests/Launcher/tst_Launcher.qml 2015-12-03 10:50:28 +0000
153@@ -467,9 +467,12 @@
154
155 function test_dragndrop_data() {
156 return [
157- {tag: "startDrag", fullDrag: false },
158- {tag: "fullDrag horizontal", fullDrag: true, orientation: ListView.Horizontal },
159- {tag: "fullDrag vertical", fullDrag: true, orientation: ListView.Vertical },
160+ {tag: "startDrag", fullDrag: false, releaseBeforeDrag: false },
161+ {tag: "fullDrag horizontal", fullDrag: true, releaseBeforeDrag: false, orientation: ListView.Horizontal },
162+ {tag: "fullDrag vertical", fullDrag: true, releaseBeforeDrag: false, orientation: ListView.Vertical },
163+ {tag: "startDrag with quicklist open", fullDrag: false, releaseBeforeDrag: true },
164+ {tag: "fullDrag horizontal with quicklist open", fullDrag: true, releaseBeforeDrag: true, orientation: ListView.Horizontal },
165+ {tag: "fullDrag vertical with quicklist open", fullDrag: true, releaseBeforeDrag: true, orientation: ListView.Vertical },
166 ];
167 }
168
169@@ -502,6 +505,15 @@
170 tryCompare(draggedItem, "itemOpacity", 0)
171 tryCompare(fakeDragItem, "visible", true)
172
173+ if (data.releaseBeforeDrag) {
174+ mouseRelease(launcher);
175+ tryCompare(fakeDragItem, "visible", false)
176+
177+ mousePress(launcher, currentMouseX, currentMouseY);
178+ // DraggedItem needs to hide and fakeDragItem become visible
179+ tryCompare(fakeDragItem, "visible", true);
180+ }
181+
182 // Dragging a bit (> 1.5 gu)
183 newMouseX -= units.gu(2)
184 mouseFlick(launcher, currentMouseX, currentMouseY, newMouseX, newMouseY, false, false, 100)
185@@ -552,8 +564,10 @@
186
187 function test_dragndrop_cancel_data() {
188 return [
189- {tag: "by mouse", mouse: true},
190- {tag: "by touch", mouse: false}
191+ {tag: "by mouse", mouse: true, releaseBeforeDrag: false},
192+ {tag: "by touch", mouse: false, releaseBeforeDrag: false},
193+ {tag: "by mouse with quicklist open", mouse: true, releaseBeforeDrag: true},
194+ {tag: "by touch with quicklist open", mouse: false, releaseBeforeDrag: true}
195 ]
196 }
197
198@@ -577,6 +591,22 @@
199 tryCompare(draggedItem, "itemOpacity", 0)
200 tryCompare(fakeDragItem, "visible", true)
201
202+ if (data.releaseBeforeDrag) {
203+ if(data.mouse) {
204+ mouseRelease(draggedItem)
205+ } else {
206+ touchRelease(draggedItem)
207+ }
208+ tryCompare(fakeDragItem, "visible", false)
209+
210+ if(data.mouse) {
211+ mousePress(draggedItem, currentMouseX, currentMouseY)
212+ } else {
213+ touchPress(draggedItem, currentMouseX, currentMouseY)
214+ }
215+ tryCompare(fakeDragItem, "visible", true);
216+ }
217+
218 // Dragging
219 currentMouseX -= units.gu(20)
220
221@@ -604,6 +634,87 @@
222 tryCompare(dndArea, "drag.target", undefined)
223 }
224
225+ function test_dragndrop_with_other_quicklist_open() {
226+ dragLauncherIntoView();
227+ var draggedItem = findChild(launcher, "launcherDelegate4")
228+ var item0 = findChild(launcher, "launcherDelegate0")
229+ var fakeDragItem = findChild(launcher, "fakeDragItem")
230+ var initialItemHeight = draggedItem.height
231+ var item4 = LauncherModel.get(4).appId
232+ var item3 = LauncherModel.get(3).appId
233+
234+ var listView = findChild(launcher, "launcherListView");
235+ listView.flick(0, units.gu(200));
236+ tryCompare(listView, "flicking", false);
237+
238+ // Initial state
239+ compare(draggedItem.itemOpacity, 1, "Item's opacity is not 1 at beginning")
240+ compare(fakeDragItem.visible, false, "FakeDragItem isn't invisible at the beginning")
241+ tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 0)
242+
243+ // Doing longpress
244+ var mouseOnLauncher = launcher.mapFromItem(draggedItem, draggedItem.width / 2, draggedItem.height / 2)
245+ var currentMouseX = mouseOnLauncher.x
246+ var currentMouseY = mouseOnLauncher.y
247+ var newMouseX = currentMouseX
248+ var newMouseY = currentMouseY
249+ mousePress(launcher, currentMouseX, currentMouseY)
250+ // DraggedItem needs to hide and fakeDragItem become visible
251+ tryCompare(draggedItem, "itemOpacity", 0)
252+ tryCompare(fakeDragItem, "visible", true)
253+
254+ mouseRelease(launcher);
255+ tryCompare(fakeDragItem, "visible", false)
256+
257+ // Now let's longpress and drag a different item
258+
259+ var draggedItem = findChild(launcher, "launcherDelegate3")
260+ compare(draggedItem.itemOpacity, 1, "Item's opacity is not 1 at beginning")
261+ tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 0)
262+
263+ // Doing longpress
264+ var mouseOnLauncher = launcher.mapFromItem(draggedItem, draggedItem.width / 2, draggedItem.height / 2)
265+ var currentMouseX = mouseOnLauncher.x
266+ var currentMouseY = mouseOnLauncher.y
267+ var newMouseX = currentMouseX
268+ var newMouseY = currentMouseY
269+ mousePress(launcher, currentMouseX, currentMouseY)
270+ // DraggedItem needs to hide and fakeDragItem become visible
271+ tryCompare(draggedItem, "itemOpacity", 0)
272+ tryCompare(fakeDragItem, "visible", true)
273+
274+ // Dragging a bit (> 1.5 gu)
275+ newMouseX -= units.gu(2)
276+ mouseFlick(launcher, currentMouseX, currentMouseY, newMouseX, newMouseY, false, false, 100)
277+ currentMouseX = newMouseX
278+
279+ // Other items need to expand and become 0.6 opaque
280+ tryCompare(item0, "angle", 0)
281+ tryCompare(item0, "itemOpacity", 0.6)
282+
283+ // Dragging a bit more
284+ newMouseY += initialItemHeight * 1.5
285+ mouseFlick(launcher, currentMouseX, currentMouseY, newMouseX, newMouseY, false, false, 100)
286+ currentMouseY = newMouseY
287+
288+ tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 1)
289+ tryCompare(draggedItem, "height", units.gu(1))
290+
291+ waitForRendering(draggedItem)
292+ compare(LauncherModel.get(4).appId, item3)
293+ compare(LauncherModel.get(3).appId, item4)
294+
295+ // Releasing and checking if initial values are restored
296+ mouseRelease(launcher)
297+ tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 0)
298+ tryCompare(draggedItem, "itemOpacity", 1)
299+ tryCompare(fakeDragItem, "visible", false)
300+
301+ // Click somewhere in the empty space to make it hide in case it isn't
302+ mouseClick(launcher, launcher.width - units.gu(1), units.gu(1));
303+ waitUntilLauncherDisappears();
304+ }
305+
306 function test_quicklist_dismiss() {
307 dragLauncherIntoView();
308 var draggedItem = findChild(launcher, "launcherDelegate5")

Subscribers

People subscribed via source and target branches