Merge lp:~aacid/unity8/drag_with_quicklist into lp:unity8
- drag_with_quicklist
- Merge into trunk
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 |
Related bugs: |
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
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2075
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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
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?
Preview Diff
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 | 384 | property int startY | 384 | property int startY |
6 | 385 | 385 | ||
7 | 386 | onPressed: { | 386 | onPressed: { |
9 | 387 | selectedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY) | 387 | processPress(mouse); |
10 | 388 | } | ||
11 | 389 | |||
12 | 390 | function processPress(mouse) { | ||
13 | 391 | selectedItem = launcherListView.itemAt(mouse.x, mouse.y + launcherListView.realContentY) | ||
14 | 388 | } | 392 | } |
15 | 389 | 393 | ||
16 | 390 | onClicked: { | 394 | onClicked: { |
17 | @@ -429,14 +433,14 @@ | |||
18 | 429 | } | 433 | } |
19 | 430 | 434 | ||
20 | 431 | onCanceled: { | 435 | onCanceled: { |
22 | 432 | endDrag(); | 436 | endDrag(drag); |
23 | 433 | } | 437 | } |
24 | 434 | 438 | ||
25 | 435 | onReleased: { | 439 | onReleased: { |
27 | 436 | endDrag(); | 440 | endDrag(drag); |
28 | 437 | } | 441 | } |
29 | 438 | 442 | ||
31 | 439 | function endDrag() { | 443 | function endDrag(dragItem) { |
32 | 440 | var droppedIndex = draggedIndex; | 444 | var droppedIndex = draggedIndex; |
33 | 441 | if (dragging) { | 445 | if (dragging) { |
34 | 442 | postDragging = true; | 446 | postDragging = true; |
35 | @@ -452,7 +456,7 @@ | |||
36 | 452 | selectedItem = undefined; | 456 | selectedItem = undefined; |
37 | 453 | preDragging = false; | 457 | preDragging = false; |
38 | 454 | 458 | ||
40 | 455 | drag.target = undefined | 459 | dragItem.target = undefined |
41 | 456 | 460 | ||
42 | 457 | progressiveScrollingTimer.stop(); | 461 | progressiveScrollingTimer.stop(); |
43 | 458 | launcherListView.interactive = true; | 462 | launcherListView.interactive = true; |
44 | @@ -464,13 +468,17 @@ | |||
45 | 464 | } | 468 | } |
46 | 465 | 469 | ||
47 | 466 | onPressAndHold: { | 470 | onPressAndHold: { |
48 | 471 | processPressAndHold(mouse, drag); | ||
49 | 472 | } | ||
50 | 473 | |||
51 | 474 | function processPressAndHold(mouse, dragItem) { | ||
52 | 467 | if (Math.abs(selectedItem.angle) > 30) { | 475 | if (Math.abs(selectedItem.angle) > 30) { |
53 | 468 | return; | 476 | return; |
54 | 469 | } | 477 | } |
55 | 470 | 478 | ||
56 | 471 | Haptics.play(); | 479 | Haptics.play(); |
57 | 472 | 480 | ||
59 | 473 | draggedIndex = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight); | 481 | draggedIndex = Math.floor((mouse.y + launcherListView.realContentY) / launcherListView.realItemHeight); |
60 | 474 | 482 | ||
61 | 475 | // Opening QuickList | 483 | // Opening QuickList |
62 | 476 | quickList.item = selectedItem; | 484 | quickList.item = selectedItem; |
63 | @@ -480,26 +488,30 @@ | |||
64 | 480 | 488 | ||
65 | 481 | launcherListView.interactive = false | 489 | launcherListView.interactive = false |
66 | 482 | 490 | ||
68 | 483 | var yOffset = draggedIndex > 0 ? (mouseY + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouseY + launcherListView.realContentY | 491 | var yOffset = draggedIndex > 0 ? (mouse.y + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouse.y + launcherListView.realContentY |
69 | 484 | 492 | ||
70 | 485 | fakeDragItem.iconName = launcherListView.model.get(draggedIndex).icon | 493 | fakeDragItem.iconName = launcherListView.model.get(draggedIndex).icon |
71 | 486 | fakeDragItem.x = units.gu(0.5) | 494 | fakeDragItem.x = units.gu(0.5) |
73 | 487 | fakeDragItem.y = mouseY - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin | 495 | fakeDragItem.y = mouse.y - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin |
74 | 488 | fakeDragItem.angle = selectedItem.angle * (root.inverted ? -1 : 1) | 496 | fakeDragItem.angle = selectedItem.angle * (root.inverted ? -1 : 1) |
75 | 489 | fakeDragItem.offset = selectedItem.offset * (root.inverted ? -1 : 1) | 497 | fakeDragItem.offset = selectedItem.offset * (root.inverted ? -1 : 1) |
76 | 490 | fakeDragItem.count = LauncherModel.get(draggedIndex).count | 498 | fakeDragItem.count = LauncherModel.get(draggedIndex).count |
77 | 491 | fakeDragItem.progress = LauncherModel.get(draggedIndex).progress | 499 | fakeDragItem.progress = LauncherModel.get(draggedIndex).progress |
78 | 492 | fakeDragItem.flatten() | 500 | fakeDragItem.flatten() |
80 | 493 | drag.target = fakeDragItem | 501 | dragItem.target = fakeDragItem |
81 | 494 | 502 | ||
84 | 495 | startX = mouseX | 503 | startX = mouse.x |
85 | 496 | startY = mouseY | 504 | startY = mouse.y |
86 | 497 | } | 505 | } |
87 | 498 | 506 | ||
88 | 499 | onPositionChanged: { | 507 | onPositionChanged: { |
89 | 508 | processPositionChanged(mouse) | ||
90 | 509 | } | ||
91 | 510 | |||
92 | 511 | function processPositionChanged(mouse) { | ||
93 | 500 | if (draggedIndex >= 0) { | 512 | if (draggedIndex >= 0) { |
94 | 501 | if (!selectedItem.dragging) { | 513 | if (!selectedItem.dragging) { |
96 | 502 | var distance = Math.max(Math.abs(mouseX - startX), Math.abs(mouseY - startY)) | 514 | var distance = Math.max(Math.abs(mouse.x - startX), Math.abs(mouse.y - startY)) |
97 | 503 | if (!preDragging && distance > units.gu(1.5)) { | 515 | if (!preDragging && distance > units.gu(1.5)) { |
98 | 504 | preDragging = true; | 516 | preDragging = true; |
99 | 505 | quickList.state = ""; | 517 | quickList.state = ""; |
100 | @@ -623,15 +635,39 @@ | |||
101 | 623 | source: "graphics/quicklist_tooltip.png" | 635 | source: "graphics/quicklist_tooltip.png" |
102 | 624 | rotation: 90 | 636 | rotation: 90 |
103 | 625 | } | 637 | } |
113 | 626 | 638 | } | |
114 | 627 | InverseMouseArea { | 639 | InverseMouseArea { |
115 | 628 | anchors.fill: parent | 640 | anchors.fill: quickListShape |
116 | 629 | enabled: quickList.state == "open" | 641 | enabled: quickList.state == "open" || pressed |
117 | 630 | onClicked: { | 642 | |
118 | 631 | quickList.state = "" | 643 | onClicked: { |
119 | 632 | } | 644 | quickList.state = "" |
120 | 633 | } | 645 | } |
121 | 634 | 646 | ||
122 | 647 | // Forward for dragging to work when quickList is open | ||
123 | 648 | |||
124 | 649 | onPressed: { | ||
125 | 650 | var m = mapToItem(dndArea, mouseX, mouseY) | ||
126 | 651 | dndArea.processPress(m) | ||
127 | 652 | } | ||
128 | 653 | |||
129 | 654 | onPressAndHold: { | ||
130 | 655 | var m = mapToItem(dndArea, mouseX, mouseY) | ||
131 | 656 | dndArea.processPressAndHold(m, drag) | ||
132 | 657 | } | ||
133 | 658 | |||
134 | 659 | onPositionChanged: { | ||
135 | 660 | var m = mapToItem(dndArea, mouseX, mouseY) | ||
136 | 661 | dndArea.processPositionChanged(m) | ||
137 | 662 | } | ||
138 | 663 | |||
139 | 664 | onCanceled: { | ||
140 | 665 | dndArea.endDrag(drag); | ||
141 | 666 | } | ||
142 | 667 | |||
143 | 668 | onReleased: { | ||
144 | 669 | dndArea.endDrag(drag); | ||
145 | 670 | } | ||
146 | 635 | } | 671 | } |
147 | 636 | 672 | ||
148 | 637 | Rectangle { | 673 | Rectangle { |
149 | 638 | 674 | ||
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 | 467 | 467 | ||
155 | 468 | function test_dragndrop_data() { | 468 | function test_dragndrop_data() { |
156 | 469 | return [ | 469 | return [ |
160 | 470 | {tag: "startDrag", fullDrag: false }, | 470 | {tag: "startDrag", fullDrag: false, releaseBeforeDrag: false }, |
161 | 471 | {tag: "fullDrag horizontal", fullDrag: true, orientation: ListView.Horizontal }, | 471 | {tag: "fullDrag horizontal", fullDrag: true, releaseBeforeDrag: false, orientation: ListView.Horizontal }, |
162 | 472 | {tag: "fullDrag vertical", fullDrag: true, orientation: ListView.Vertical }, | 472 | {tag: "fullDrag vertical", fullDrag: true, releaseBeforeDrag: false, orientation: ListView.Vertical }, |
163 | 473 | {tag: "startDrag with quicklist open", fullDrag: false, releaseBeforeDrag: true }, | ||
164 | 474 | {tag: "fullDrag horizontal with quicklist open", fullDrag: true, releaseBeforeDrag: true, orientation: ListView.Horizontal }, | ||
165 | 475 | {tag: "fullDrag vertical with quicklist open", fullDrag: true, releaseBeforeDrag: true, orientation: ListView.Vertical }, | ||
166 | 473 | ]; | 476 | ]; |
167 | 474 | } | 477 | } |
168 | 475 | 478 | ||
169 | @@ -502,6 +505,15 @@ | |||
170 | 502 | tryCompare(draggedItem, "itemOpacity", 0) | 505 | tryCompare(draggedItem, "itemOpacity", 0) |
171 | 503 | tryCompare(fakeDragItem, "visible", true) | 506 | tryCompare(fakeDragItem, "visible", true) |
172 | 504 | 507 | ||
173 | 508 | if (data.releaseBeforeDrag) { | ||
174 | 509 | mouseRelease(launcher); | ||
175 | 510 | tryCompare(fakeDragItem, "visible", false) | ||
176 | 511 | |||
177 | 512 | mousePress(launcher, currentMouseX, currentMouseY); | ||
178 | 513 | // DraggedItem needs to hide and fakeDragItem become visible | ||
179 | 514 | tryCompare(fakeDragItem, "visible", true); | ||
180 | 515 | } | ||
181 | 516 | |||
182 | 505 | // Dragging a bit (> 1.5 gu) | 517 | // Dragging a bit (> 1.5 gu) |
183 | 506 | newMouseX -= units.gu(2) | 518 | newMouseX -= units.gu(2) |
184 | 507 | mouseFlick(launcher, currentMouseX, currentMouseY, newMouseX, newMouseY, false, false, 100) | 519 | mouseFlick(launcher, currentMouseX, currentMouseY, newMouseX, newMouseY, false, false, 100) |
185 | @@ -552,8 +564,10 @@ | |||
186 | 552 | 564 | ||
187 | 553 | function test_dragndrop_cancel_data() { | 565 | function test_dragndrop_cancel_data() { |
188 | 554 | return [ | 566 | return [ |
191 | 555 | {tag: "by mouse", mouse: true}, | 567 | {tag: "by mouse", mouse: true, releaseBeforeDrag: false}, |
192 | 556 | {tag: "by touch", mouse: false} | 568 | {tag: "by touch", mouse: false, releaseBeforeDrag: false}, |
193 | 569 | {tag: "by mouse with quicklist open", mouse: true, releaseBeforeDrag: true}, | ||
194 | 570 | {tag: "by touch with quicklist open", mouse: false, releaseBeforeDrag: true} | ||
195 | 557 | ] | 571 | ] |
196 | 558 | } | 572 | } |
197 | 559 | 573 | ||
198 | @@ -577,6 +591,22 @@ | |||
199 | 577 | tryCompare(draggedItem, "itemOpacity", 0) | 591 | tryCompare(draggedItem, "itemOpacity", 0) |
200 | 578 | tryCompare(fakeDragItem, "visible", true) | 592 | tryCompare(fakeDragItem, "visible", true) |
201 | 579 | 593 | ||
202 | 594 | if (data.releaseBeforeDrag) { | ||
203 | 595 | if(data.mouse) { | ||
204 | 596 | mouseRelease(draggedItem) | ||
205 | 597 | } else { | ||
206 | 598 | touchRelease(draggedItem) | ||
207 | 599 | } | ||
208 | 600 | tryCompare(fakeDragItem, "visible", false) | ||
209 | 601 | |||
210 | 602 | if(data.mouse) { | ||
211 | 603 | mousePress(draggedItem, currentMouseX, currentMouseY) | ||
212 | 604 | } else { | ||
213 | 605 | touchPress(draggedItem, currentMouseX, currentMouseY) | ||
214 | 606 | } | ||
215 | 607 | tryCompare(fakeDragItem, "visible", true); | ||
216 | 608 | } | ||
217 | 609 | |||
218 | 580 | // Dragging | 610 | // Dragging |
219 | 581 | currentMouseX -= units.gu(20) | 611 | currentMouseX -= units.gu(20) |
220 | 582 | 612 | ||
221 | @@ -604,6 +634,87 @@ | |||
222 | 604 | tryCompare(dndArea, "drag.target", undefined) | 634 | tryCompare(dndArea, "drag.target", undefined) |
223 | 605 | } | 635 | } |
224 | 606 | 636 | ||
225 | 637 | function test_dragndrop_with_other_quicklist_open() { | ||
226 | 638 | dragLauncherIntoView(); | ||
227 | 639 | var draggedItem = findChild(launcher, "launcherDelegate4") | ||
228 | 640 | var item0 = findChild(launcher, "launcherDelegate0") | ||
229 | 641 | var fakeDragItem = findChild(launcher, "fakeDragItem") | ||
230 | 642 | var initialItemHeight = draggedItem.height | ||
231 | 643 | var item4 = LauncherModel.get(4).appId | ||
232 | 644 | var item3 = LauncherModel.get(3).appId | ||
233 | 645 | |||
234 | 646 | var listView = findChild(launcher, "launcherListView"); | ||
235 | 647 | listView.flick(0, units.gu(200)); | ||
236 | 648 | tryCompare(listView, "flicking", false); | ||
237 | 649 | |||
238 | 650 | // Initial state | ||
239 | 651 | compare(draggedItem.itemOpacity, 1, "Item's opacity is not 1 at beginning") | ||
240 | 652 | compare(fakeDragItem.visible, false, "FakeDragItem isn't invisible at the beginning") | ||
241 | 653 | tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 0) | ||
242 | 654 | |||
243 | 655 | // Doing longpress | ||
244 | 656 | var mouseOnLauncher = launcher.mapFromItem(draggedItem, draggedItem.width / 2, draggedItem.height / 2) | ||
245 | 657 | var currentMouseX = mouseOnLauncher.x | ||
246 | 658 | var currentMouseY = mouseOnLauncher.y | ||
247 | 659 | var newMouseX = currentMouseX | ||
248 | 660 | var newMouseY = currentMouseY | ||
249 | 661 | mousePress(launcher, currentMouseX, currentMouseY) | ||
250 | 662 | // DraggedItem needs to hide and fakeDragItem become visible | ||
251 | 663 | tryCompare(draggedItem, "itemOpacity", 0) | ||
252 | 664 | tryCompare(fakeDragItem, "visible", true) | ||
253 | 665 | |||
254 | 666 | mouseRelease(launcher); | ||
255 | 667 | tryCompare(fakeDragItem, "visible", false) | ||
256 | 668 | |||
257 | 669 | // Now let's longpress and drag a different item | ||
258 | 670 | |||
259 | 671 | var draggedItem = findChild(launcher, "launcherDelegate3") | ||
260 | 672 | compare(draggedItem.itemOpacity, 1, "Item's opacity is not 1 at beginning") | ||
261 | 673 | tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 0) | ||
262 | 674 | |||
263 | 675 | // Doing longpress | ||
264 | 676 | var mouseOnLauncher = launcher.mapFromItem(draggedItem, draggedItem.width / 2, draggedItem.height / 2) | ||
265 | 677 | var currentMouseX = mouseOnLauncher.x | ||
266 | 678 | var currentMouseY = mouseOnLauncher.y | ||
267 | 679 | var newMouseX = currentMouseX | ||
268 | 680 | var newMouseY = currentMouseY | ||
269 | 681 | mousePress(launcher, currentMouseX, currentMouseY) | ||
270 | 682 | // DraggedItem needs to hide and fakeDragItem become visible | ||
271 | 683 | tryCompare(draggedItem, "itemOpacity", 0) | ||
272 | 684 | tryCompare(fakeDragItem, "visible", true) | ||
273 | 685 | |||
274 | 686 | // Dragging a bit (> 1.5 gu) | ||
275 | 687 | newMouseX -= units.gu(2) | ||
276 | 688 | mouseFlick(launcher, currentMouseX, currentMouseY, newMouseX, newMouseY, false, false, 100) | ||
277 | 689 | currentMouseX = newMouseX | ||
278 | 690 | |||
279 | 691 | // Other items need to expand and become 0.6 opaque | ||
280 | 692 | tryCompare(item0, "angle", 0) | ||
281 | 693 | tryCompare(item0, "itemOpacity", 0.6) | ||
282 | 694 | |||
283 | 695 | // Dragging a bit more | ||
284 | 696 | newMouseY += initialItemHeight * 1.5 | ||
285 | 697 | mouseFlick(launcher, currentMouseX, currentMouseY, newMouseX, newMouseY, false, false, 100) | ||
286 | 698 | currentMouseY = newMouseY | ||
287 | 699 | |||
288 | 700 | tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 1) | ||
289 | 701 | tryCompare(draggedItem, "height", units.gu(1)) | ||
290 | 702 | |||
291 | 703 | waitForRendering(draggedItem) | ||
292 | 704 | compare(LauncherModel.get(4).appId, item3) | ||
293 | 705 | compare(LauncherModel.get(3).appId, item4) | ||
294 | 706 | |||
295 | 707 | // Releasing and checking if initial values are restored | ||
296 | 708 | mouseRelease(launcher) | ||
297 | 709 | tryCompare(findChild(draggedItem, "dropIndicator"), "opacity", 0) | ||
298 | 710 | tryCompare(draggedItem, "itemOpacity", 1) | ||
299 | 711 | tryCompare(fakeDragItem, "visible", false) | ||
300 | 712 | |||
301 | 713 | // Click somewhere in the empty space to make it hide in case it isn't | ||
302 | 714 | mouseClick(launcher, launcher.width - units.gu(1), units.gu(1)); | ||
303 | 715 | waitUntilLauncherDisappears(); | ||
304 | 716 | } | ||
305 | 717 | |||
306 | 607 | function test_quicklist_dismiss() { | 718 | function test_quicklist_dismiss() { |
307 | 608 | dragLauncherIntoView(); | 719 | dragLauncherIntoView(); |
308 | 609 | var draggedItem = findChild(launcher, "launcherDelegate5") | 720 | var draggedItem = findChild(launcher, "launcherDelegate5") |
* 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