Merge lp:~unity-team/unity/phablet.dashBar_bottomswipe into lp:unity/phablet

Proposed by Andrea Cimitan
Status: Rejected
Rejected by: Andrea Cimitan
Proposed branch: lp:~unity-team/unity/phablet.dashBar_bottomswipe
Merge into: lp:unity/phablet
Diff against target: 465 lines (+311/-50)
5 files modified
CMakeLists.txt (+1/-0)
Dash/DashBar.qml (+146/-46)
tests/qmluitests/CMakeLists.txt (+1/-0)
tests/qmluitests/UnityTestCase.qml (+6/-4)
tests/qmluitests/tst_DashBar.qml (+157/-0)
To merge this branch: bzr merge lp:~unity-team/unity/phablet.dashBar_bottomswipe
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Michał Sawicz Needs Fixing
Michael Zanetti (community) Needs Fixing
Review via email: mp+150847@code.launchpad.net

Commit message

Bottom swipe reveals the dash bar

Description of the change

Bottom swipe reveals the dash bar, integrating some logic from GenericToolbar.qml internal qml component used in the SDK

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote :

misses tests

review: Needs Fixing
439. By Andrea Cimitan

Merged trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
440. By Andrea Cimitan

Merged trunk, modified unittests CMakeList, added WIP qmluitest DashBar

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
441. By Andrea Cimitan

Some more tests

442. By Andrea Cimitan

Merged trunk

443. By Andrea Cimitan

Add slow swipe

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
444. By Andrea Cimitan

Add test for hide after navigation

445. By Andrea Cimitan

Add test for itemSelected, added readonly property rowWidth for the wdth of the row inside the DashBar, made some properties readonly

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Can we please have a separate MR with just the CMake tweaks?

Also, this looks a lot like a copy of what's there for the Launcher, could we not think of a way of abstracting that behaviour?

review: Needs Fixing
446. By Michael Zanetti

make it even more weird

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
447. By Andrea Cimitan

This is weird

448. By Andrea Cimitan

better debug

449. By Andrea Cimitan

Finished testing DashBar

450. By Andrea Cimitan

Revert old CMake for unittests

Revision history for this message
Andrea Cimitan (cimi) wrote :

> Can we please have a separate MR with just the CMake tweaks?
>
I extracted and pushed lp:~unity-team/unity/phablet.unittests_new-cmake

> Also, this looks a lot like a copy of what's there for the Launcher, could we
> not think of a way of abstracting that behaviour?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
451. By Andrea Cimitan

id: root is not used

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andrea Cimitan (cimi) wrote :

> misses tests

not anymore! :-)

Revision history for this message
Michael Zanetti (mzanetti) wrote :

> > misses tests
>
> not anymore! :-)

Great! Testing looks ok. I couldn't verify because there are a bunch of merge conflicts by now. Anyways, once they are resolved its fine with me.

I think there is one Needs Fixing from Saviq left tho. The one about duplicating the dragging-code from the launcher.

Revision history for this message
Michael Zanetti (mzanetti) wrote :

Can we please either fix or delete this?

Revision history for this message
Andrea Cimitan (cimi) wrote :

There's a new branch using Panel SDK component

Unmerged revisions

451. By Andrea Cimitan

id: root is not used

450. By Andrea Cimitan

Revert old CMake for unittests

449. By Andrea Cimitan

Finished testing DashBar

448. By Andrea Cimitan

better debug

447. By Andrea Cimitan

This is weird

446. By Michael Zanetti

make it even more weird

445. By Andrea Cimitan

Add test for itemSelected, added readonly property rowWidth for the wdth of the row inside the DashBar, made some properties readonly

444. By Andrea Cimitan

Add test for hide after navigation

443. By Andrea Cimitan

Add slow swipe

442. By Andrea Cimitan

Merged trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-03-19 09:16:26 +0000
3+++ CMakeLists.txt 2013-03-20 15:46:22 +0000
4@@ -32,6 +32,7 @@
5 # Tests
6 enable_testing()
7 add_custom_target(check make test CTEST_OUTPUT_ON_FAILURE=1)
8+add_dependencies(check make unittests CTEST_OUTPUT_ON_FAILURE=1)
9
10 # Autopilot tests
11 include(autopilot)
12
13=== modified file 'Dash/DashBar.qml'
14--- Dash/DashBar.qml 2013-01-15 11:37:07 +0000
15+++ Dash/DashBar.qml 2013-03-20 15:46:22 +0000
16@@ -17,6 +17,7 @@
17 import QtQuick 2.0
18 import Ubuntu.Components 0.1
19 import Unity 0.1
20+import "../Components"
21
22 Item {
23 id: dashBar
24@@ -24,23 +25,24 @@
25 property var model
26 property int currentIndex
27
28- property int lineHeight: units.dp(2)
29- property int itemSize: units.gu(7)
30- property int iconSize: units.gu(2.5)
31- property int initialHeight: lineHeight
32- property int maxHeight: units.gu(6)
33+ readonly property alias rowWidth: row.width
34+ readonly property int lineHeight: units.dp(2)
35+ readonly property int itemSize: units.gu(7)
36+ readonly property int iconSize: units.gu(2.5)
37+ readonly property int initialHeight: lineHeight
38+ readonly property int maxHeight: units.gu(6)
39
40 width: units.gu(40)
41 height: initialHeight
42 Behavior on height {NumberAnimation { duration: 300; easing.type: Easing.OutQuad}}
43
44- state: "initial"
45+ state: "hint"
46
47 signal itemSelected(int index)
48
49 function startNavigation() {
50 timeout.stop()
51- dashBar.state = "navigation"
52+ dashBar.state = "spread"
53 }
54
55 function stopNavigation() {
56@@ -48,7 +50,140 @@
57 }
58
59 function finishNavigation() {
60- dashBar.state = "initial"
61+ dashBar.state = "hint"
62+ }
63+
64+ states: [
65+ State {
66+ name: "hint"
67+ PropertyChanges {
68+ target: bar
69+ y: bar.height - initialHeight
70+ }
71+ PropertyChanges {
72+ target: dashBar
73+ height: initialHeight
74+ }
75+ },
76+ State {
77+ name: "moving"
78+ PropertyChanges {
79+ target: bar
80+ y: MathUtils.clamp(bar.height, draggingArea.mouseY - internal.movingDelta, 0, bar.height)
81+ }
82+ PropertyChanges {
83+ target: dashBar
84+ height: Math.max(bar.height - bar.y, initialHeight)
85+ }
86+ },
87+ State {
88+ name: "spread"
89+ PropertyChanges {
90+ target: bar
91+ y: 0
92+ }
93+ PropertyChanges {
94+ target: dashBar
95+ height: maxHeight
96+ }
97+ }
98+ ]
99+
100+ transitions: [
101+ Transition {
102+ to: "hint"
103+ PropertyAnimation {
104+ target: bar
105+ properties: "y"
106+ duration: 100
107+ easing.type: Easing.OutQuad
108+ }
109+ },
110+ Transition {
111+ to: "spread"
112+ PropertyAnimation {
113+ target: bar
114+ properties: "y"
115+ duration: 100
116+ easing.type: Easing.OutQuad
117+ }
118+ }
119+ ]
120+
121+ QtObject {
122+ id: internal
123+ property string previousState: "hint"
124+ property int movingDelta
125+ }
126+
127+ onStateChanged: {
128+ if (state == "hint" || (state == "moving" && internal.previousState == "hint")) {
129+ internal.movingDelta = dashBar.initialHeight + draggingArea.initialY - bar.height;
130+ } else if (state == "moving" && internal.previousState == "spread") {
131+ internal.movingDelta = draggingArea.initialY;
132+ }
133+
134+ internal.previousState = state;
135+ }
136+
137+ Timer {
138+ id: timeout
139+ interval: 1500
140+ running: false
141+ repeat: false
142+ onTriggered: finishNavigation()
143+ }
144+
145+ Item {
146+ id: bar
147+ height: maxHeight
148+ anchors {
149+ left: parent.left
150+ right: parent.right
151+ }
152+
153+ y: dashBar.state == "spread" ? 0 : height - initialHeight
154+ }
155+
156+ DraggingArea {
157+ orientation: Qt.Vertical
158+ id: draggingArea
159+ anchors {
160+ bottom: parent.bottom
161+ left: parent.left
162+ right: parent.right
163+ }
164+ height: dashBar.state == "spread" ? bar.height + units.gu(1) : units.gu(2)
165+ zeroVelocityCounts: true
166+ propagateComposedEvents: true
167+
168+ property int initialY
169+
170+ onPressed: {
171+ if (dashBar.state == "hint")
172+ initialY = mouseY
173+ }
174+
175+ onPositionChanged: {
176+ dashBar.state = "moving";
177+ }
178+
179+ onReleased: finishMoving()
180+ // Mouse cursor moving out of the window while pressed on desktop
181+ onCanceled: finishMoving()
182+
183+ // FIXME: Make all parameters below themable.
184+ // The value of 44 was copied from the Launcher.
185+ function finishMoving() {
186+ if (draggingArea.dragVelocity < -44) {
187+ dashBar.state = "spread";
188+ } else if (draggingArea.dragVelocity > 44) {
189+ dashBar.state = "hint";
190+ } else {
191+ dashBar.state = (bar.y < bar.height / 2) ? "spread" : "hint";
192+ }
193+ timeout.restart()
194+ }
195 }
196
197 Rectangle {
198@@ -64,7 +199,7 @@
199 anchors.horizontalCenter: parent.horizontalCenter
200 currentIndex: dashBar.currentIndex
201 onMovingChanged: if (moving) { timeout.stop() } else { timeout.restart() }
202- interactive: visibleArea.widthRatio < 1 && dashBar.state == "navigation"
203+ interactive: visibleArea.widthRatio < 1 && dashBar.state == "spread"
204 delegate:
205 Item {
206 width: itemSize
207@@ -85,22 +220,12 @@
208 smooth: true
209 }
210 MouseArea {
211- enabled: dashBar.state == "navigation"
212+ enabled: dashBar.state == "spread"
213 anchors.fill: parent
214- onPressed: {
215- timeout.stop()
216- if (dashbar.state == "initial") {
217- dashbar.state = "navigation"
218- mouse.accepted = false
219- }
220- }
221-
222- onReleased: {
223- timeout.restart()
224- }
225
226 onClicked: {
227 dashBar.itemSelected(index)
228+ timeout.restart()
229 }
230 }
231 }
232@@ -119,30 +244,5 @@
233 }
234 }
235 }
236-
237- Timer {
238- id: timeout
239- interval: 1500
240- running: false
241- repeat: false
242- onTriggered: finishNavigation()
243- }
244-
245- states: [
246- State {
247- name: "initial"
248- PropertyChanges {
249- target: dashBar
250- height: initialHeight
251- }
252- },
253- State {
254- name: "navigation"
255- PropertyChanges {
256- target: dashBar
257- height: maxHeight
258- }
259- }
260- ]
261 }
262
263
264=== modified file 'tests/qmluitests/CMakeLists.txt'
265--- tests/qmluitests/CMakeLists.txt 2013-03-20 09:39:25 +0000
266+++ tests/qmluitests/CMakeLists.txt 2013-03-20 15:46:22 +0000
267@@ -20,6 +20,7 @@
268 add_dependencies(qmluitests test${COMPONENT_NAME})
269 endmacro(add_qml_test)
270
271+add_qml_test(DashBar ${CMAKE_SOURCE_DIR}/plugins)
272 add_qml_test(DraggingArea)
273 add_qml_test(FilterGrid ${CMAKE_BINARY_DIR}/plugins)
274 add_qml_test(Hud ${CMAKE_CURRENT_BINARY_DIR}/qml)
275
276=== modified file 'tests/qmluitests/UnityTestCase.qml'
277--- tests/qmluitests/UnityTestCase.qml 2013-03-20 14:43:40 +0000
278+++ tests/qmluitests/UnityTestCase.qml 2013-03-20 15:46:22 +0000
279@@ -26,11 +26,12 @@
280 }
281
282 // Flickable won't recognise a single mouse move as dragging the flickable.
283- // Use 5 steps because it's what
284+ // Use 5 steps because it's what
285 // Qt uses in QQuickViewTestUtil::flick
286- function mouseFlick(item, x, y, toX, toY, pressMouse, releaseMouse) {
287- pressMouse = ((pressMouse != null) ? pressMouse : true); // Default to true for pressMouse if not present
288- releaseMouse = ((releaseMouse != null) ? releaseMouse : true); // Default to true for releaseMouse if not present
289+ function mouseFlick(item, x, y, toX, toY, pressMouse, releaseMouse, duration) {
290+ if (pressMouse === undefined) pressMouse = true; // Default to true for pressMouse if not present
291+ if (releaseMouse === undefined) releaseMouse = true; // Default to true for releaseMouse if not present
292+ if (duration === undefined) duration = 0; // Default to 0 for duration if not present
293 var nIterations = 5
294 var diffX = (toX - x) / nIterations
295 var diffY = (toY - y) / nIterations
296@@ -40,6 +41,7 @@
297 }
298 for (var i = 0; i < nIterations; ++i) {
299 fakeDateTime.currentTimeMs += 10
300+ wait(duration / nIterations)
301 if (i === nIterations - 1) {
302 // Avoid any rounding errors by making the last move be at precisely
303 // the point specified
304
305=== added file 'tests/qmluitests/tst_DashBar.qml'
306--- tests/qmluitests/tst_DashBar.qml 1970-01-01 00:00:00 +0000
307+++ tests/qmluitests/tst_DashBar.qml 2013-03-20 15:46:22 +0000
308@@ -0,0 +1,157 @@
309+/*
310+ * Copyright 2013 Canonical Ltd.
311+ *
312+ * This program is free software; you can redistribute it and/or modify
313+ * it under the terms of the GNU General Public License as published by
314+ * the Free Software Foundation; version 3.
315+ *
316+ * This program is distributed in the hope that it will be useful,
317+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
318+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
319+ * GNU General Public License for more details.
320+ *
321+ * You should have received a copy of the GNU General Public License
322+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
323+ */
324+
325+import QtQuick 2.0
326+import QtTest 1.0
327+import Unity 0.1
328+import "../../Dash"
329+
330+Item {
331+ width: units.gu(40)
332+ height: units.gu(71)
333+
334+ DashBar {
335+ id: dashBar
336+
337+ anchors {
338+ left: parent.left
339+ right: parent.right
340+ bottom: parent.bottom
341+ }
342+ model: Lenses {}
343+ }
344+
345+ SignalSpy {
346+ id: signalSpy
347+ signalName: "itemSelected"
348+ target: dashBar
349+ }
350+
351+ UnityTestCase {
352+ name: "DashBarTest"
353+ when: windowShown
354+
355+ property alias model: dashBar.model
356+ property alias currentIndex: dashBar.currentIndex
357+
358+ readonly property alias rowWidth: dashBar.rowWidth
359+ readonly property alias lineHeight: dashBar.lineHeight
360+ readonly property alias itemSize: dashBar.itemSize
361+ readonly property alias iconSize: dashBar.iconSize
362+ readonly property alias initialHeight: dashBar.initialHeight
363+ readonly property alias maxHeight: dashBar.maxHeight
364+
365+ function checkInitialHeight() {
366+ // basically waits for the dashBar to hide... (initial status)
367+ tryCompare(dashBar, "height", dashBar.initialHeight)
368+ }
369+
370+ function test_navigationAndHide() {
371+ checkInitialHeight()
372+
373+ dashBar.startNavigation()
374+ tryCompare(dashBar, "height", dashBar.maxHeight)
375+
376+ dashBar.finishNavigation()
377+ tryCompare(dashBar, "height", dashBar.initialHeight)
378+ }
379+
380+ function test_bottomSwipeComplete() {
381+ checkInitialHeight()
382+
383+ // (item, x, y, button, modifiers, delay)
384+ mousePress(parent,
385+ parent.width / 2, parent.height,
386+ Qt.LeftButton, Qt.NoModifier, 0);
387+ // (item, x, y, delay, button)
388+ mouseMove(parent,
389+ parent.width / 2, parent.height01,
390+ 0, Qt.LeftButton);
391+ // (item, x, y, button, modifiers, delay)
392+ mouseRelease(parent,
393+ parent.width / 2, parent.height01,
394+ Qt.LeftButton, Qt.NoModifier, 0);
395+ tryCompare(dashBar, "height", dashBar.maxHeight)
396+ }
397+
398+ function test_bottomSwipeBack() {
399+ checkInitialHeight()
400+
401+ mousePress(parent,
402+ parent.width / 2, parent.height,
403+ Qt.LeftButton, Qt.NoModifier, 0);
404+ mouseMove(parent,
405+ parent.width / 2, parent.height - dashBar.maxHeight / 2,
406+ 0, Qt.LeftButton);
407+ mouseMove(parent,
408+ parent.width / 2, parent.height,
409+ 0, Qt.LeftButton);
410+ mouseRelease(parent,
411+ parent.width / 2, parent.height,
412+ Qt.LeftButton, Qt.NoModifier, 0);
413+ tryCompare(dashBar, "height", dashBar.initialHeight)
414+ }
415+
416+ function test_bottomSwipeHalfFast() {
417+ checkInitialHeight()
418+
419+ mouseFlick(parent,
420+ parent.width / 2, parent.height,
421+ parent.width / 2, parent.height - 5,
422+ true, true, 0);
423+ tryCompare(dashBar, "height", dashBar.maxHeight)
424+ }
425+
426+ function test_bottomSwipeHalfSlow() {
427+ checkInitialHeight()
428+
429+ mouseFlick(parent,
430+ parent.width / 2, parent.height,
431+ parent.width / 2, parent.height - 5,
432+ true, true, 75);
433+ tryCompare(dashBar, "height", dashBar.initialHeight)
434+ }
435+
436+ function test_itemSelected() {
437+ checkInitialHeight()
438+ signalSpy.clear()
439+
440+ dashBar.startNavigation()
441+ tryCompare(dashBar, "height", dashBar.maxHeight)
442+
443+ var rowStartX = dashBar.width / 2 - rowWidth / 2;
444+ for (var i = 0; i < model.rowCount(); i++) {
445+ // coordinate x in the middle of item with index 'i'
446+ var x = rowStartX + (rowWidth / model.rowCount()) * i + itemSize / 2
447+ if (x > rowWidth) {
448+ /* FIXME exit the cycle if we have more lenses than dashBar width.
449+ Let's fix and test this behaviour when we'll have more lenses! */
450+ break;
451+ }
452+ // FIXME workaround for a bug in SignalSpy
453+ signalSpy.clear()
454+
455+ // (item, x, y, button, modifiers, delay)
456+ mouseClick(dashBar, x, dashBar.height / 2, Qt.LeftButton, Qt.NoModifier, 0)
457+ compare(signalSpy.count > 0, true, "signal itemSelected not triggered")
458+ compare(signalSpy.signalArguments[0][0], i, "signal itemSelected emitted unexpected index");
459+ }
460+
461+ dashBar.finishNavigation()
462+ }
463+ }
464+}
465+

Subscribers

People subscribed via source and target branches

to all changes: