on xenial help sign in
Add behaviours to the hud reveal. Fixes: https://bugs.launchpad.net/bugs/1224480, https://bugs.launchpad.net/bugs/1224633.

Approved by PS Jenkins bot, Michael Zanetti.

commit5623a7056ce6af58d9b68db3dfd6bb7d7e6fa67d authorAndrea Cimitan <andrea.cimitan@gmail.com> dateThu 3 Oct 2013, 10:54 (13 years ago) parent6984ac66755c64
9 files changed+187−41
Bottombar/Bottombar.qml+81−16 Shell.qml+2 plugins/Unity/bottombarvisibilitycommunicatorshell.cpp+15−1 plugins/Unity/bottombarvisibilitycommunicatorshell.h+6 tests/autopilot/unity8/shell/__init__.py+14 tests/autopilot/unity8/shell/emulators/dash.py+15−6 tests/autopilot/unity8/shell/emulators/hud.py+8−9 tests/autopilot/unity8/shell/emulators/main_window.py+3 tests/autopilot/unity8/shell/tests/test_hud.py+43−9
Bottombar/Bottombar.qml+81−16
@@ -34,15 +34,32 @@ Item {
3434
3535 state: "hidden"
3636
37+ function hide() {
38+ dismissTimer.stop()
39+ bottombar.state = "hidden"
40+ }
41+
42+ onApplicationIsOnForegroundChanged: {
43+ if (!applicationIsOnForeground) {
44+ hide()
45+ }
46+ }
47+
3748 onStateChanged: {
3849 if (state == "hidden") {
3950 dismissTimer.stop()
51+ bottomBarVisibilityCommunicatorShell.forceHidden = false
4052 } else {
4153 dismissTimer.restart()
4254 }
4355 }
4456
4557 onPreventHidingChanged: {
58+ if (!preventHiding) {
59+ if (state == "hint" || state == "reveal")
60+ hide()
61+ }
62+
4663 if (dismissTimer.running) {
4764 dismissTimer.restart();
4865 }
@@ -50,7 +67,7 @@ Item {
5067
5168 Timer {
5269 id: dismissTimer
53− interval: 5000
70+ interval: 1000
5471 onTriggered: {
5572 if (!bottombar.preventHiding) {
5673 bottombar.state = "hidden"
@@ -103,24 +120,29 @@ Item {
103120
104121 EdgeDragArea {
105122 id: dragArea
123+ objectName: "hudDragArea"
106124 width: parent.width
107125 height: distanceThreshold
108126 anchors.bottom: parent.bottom
109127
110− distanceThreshold: units.gu(1)
128+ distanceThreshold: units.gu(8)
111129 enabled: !theHud.shown && bottombar.enabled && applicationIsOnForeground
112130 direction: Direction.Upwards
131+ maxSilenceTime: 2000
113132
114133 property int previousStatus: -1
115134 property real touchStartX: -1
116135
136+ readonly property real distanceFromThreshold: (-distance) - distanceThreshold // distance is negative
137+ readonly property real revealDistance: units.gu(2)
138+ readonly property real commitDistance: units.gu(6)
139+ readonly property real commitProgress: MathLocal.clamp(distanceFromThreshold / commitDistance, 0, 1)
140+
117141 onStatusChanged: {
118142 if (status === DirectionalDragArea.WaitingForTouch) {
119143 if (previousStatus == DirectionalDragArea.Recognized) {
120144 if (hudButton.mouseOver) {
121145 hudButton.clicked()
122− } else {
123− bottombar.state = "hidden"
124146 }
125147 }
126148 } else if (status === DirectionalDragArea.Undecided) {
@@ -128,35 +150,78 @@ Item {
128150 touchStartX = touchX
129151 }
130152 } else if (status === DirectionalDragArea.Recognized) {
131− bottombar.state = "shown"
153+ bottombar.state = "hint"
132154 }
133155 previousStatus = status
134156 }
157+
158+ onDistanceChanged: {
159+ if (status === DirectionalDragArea.Recognized) {
160+ if (distanceFromThreshold > commitDistance)
161+ bottombar.state = "shown"
162+ else if (distanceFromThreshold > revealDistance)
163+ bottombar.state = "reveal"
164+ }
165+ }
166+ }
167+
168+ Item {
169+ id: dismissArea
170+ anchors {
171+ top: parent.top
172+ left: parent.left
173+ right: parent.right
174+ }
175+ height: parent.height - bottomBarVisibilityCommunicatorShell.position
176+
177+ MouseArea {
178+ anchors.fill: parent
179+ enabled: bottombar.state == "shown"
180+ onPressed: {
181+ bottomBarVisibilityCommunicatorShell.forceHidden = true
182+ bottombar.state = "hidden"
183+ }
184+ }
185+
186+ InputFilterArea {
187+ anchors.fill: parent
188+ blockInput: (hudButton.opacity == 1)
189+ }
135190 }
136191
137192 MouseArea {
138− anchors.fill: parent
139− enabled: bottombar.state == "shown"
193+ anchors {
194+ top: dismissArea.bottom
195+ left: parent.left
196+ right: parent.right
197+ bottom: parent.bottom
198+ }
199+ enabled: bottombar.state == "shown" && bottomBarVisibilityCommunicatorShell.position > 0
140200 onPressed: {
141201 bottombar.state = "hidden"
142202 }
143203 }
144204
145− InputFilterArea {
146− anchors.fill: parent
147− blockInput: (hudButton.opacity == 1)
148− }
149−
150205 states: [
151206 State {
152207 name: "hidden"
153− PropertyChanges { target: hudButton; opacity: 0}
154− PropertyChanges { target: hudButton; bottomMargin: units.gu(-1)}
208+ PropertyChanges { target: hudButton; opacity: 0 }
209+ PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) }
210+ },
211+ State {
212+ name: "hint"
213+ extend: "hidden"
214+ PropertyChanges { target: hudButton; opacity: 0.5 }
215+ },
216+ State {
217+ name: "reveal"
218+ extend: "hint"
219+ PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) + units.gu(2) * dragArea.commitProgress }
155220 },
156221 State {
157222 name: "shown"
158− PropertyChanges { target: hudButton; opacity: 1}
159− PropertyChanges { target: hudButton; bottomMargin: units.gu(0)}
223+ PropertyChanges { target: hudButton; opacity: 1 }
224+ PropertyChanges { target: hudButton; bottomMargin: units.gu(0) }
160225 }
161226 ]
162227}
Shell.qml+2
@@ -623,6 +623,7 @@ FocusScope {
623623 }
624624
625625 Bottombar {
626+ id: bottombar
626627 theHud: hud
627628 anchors.fill: parent
628629 enabled: hud.available
@@ -663,6 +664,7 @@ FocusScope {
663664 if (shown) {
664665 panel.indicators.hide()
665666 hud.hide()
667+ bottombar.hide()
666668 }
667669 }
668670 }
plugins/Unity/bottombarvisibilitycommunicatorshell.cpp+15−1
@@ -17,7 +17,8 @@
1717#include "bottombarvisibilitycommunicatorshell.h"
1818
1919BottomBarVisibilityCommunicatorShell::BottomBarVisibilityCommunicatorShell()
20− : m_forceHidden(false)
20+ : m_forceHidden(false),
21+ m_position(0)
2122{
2223}
2324
@@ -26,6 +27,11 @@ bool BottomBarVisibilityCommunicatorShell::forceHidden() const
2627 return m_forceHidden;
2728}
2829
30+double BottomBarVisibilityCommunicatorShell::position() const
31+{
32+ return m_position;
33+}
34+
2935void BottomBarVisibilityCommunicatorShell::setForceHidden(bool forceHidden)
3036{
3137 if (forceHidden != m_forceHidden) {
@@ -33,3 +39,11 @@ void BottomBarVisibilityCommunicatorShell::setForceHidden(bool forceHidden)
3339 Q_EMIT forceHiddenChanged(forceHidden);
3440 }
3541}
42+
43+void BottomBarVisibilityCommunicatorShell::setPosition(double position)
44+{
45+ if (position != m_position) {
46+ m_position = position;
47+ Q_EMIT positionChanged(position);
48+ }
49+}
plugins/Unity/bottombarvisibilitycommunicatorshell.h+6
@@ -30,6 +30,7 @@ class BottomBarVisibilityCommunicatorShell : public QObject
3030{
3131 Q_OBJECT
3232 Q_PROPERTY(bool forceHidden READ forceHidden WRITE setForceHidden NOTIFY forceHiddenChanged)
33+ Q_PROPERTY(double position READ position WRITE setPosition NOTIFY positionChanged)
3334
3435 Q_CLASSINFO("D-Bus Interface", "com.canonical.Shell.BottomBarVisibilityCommunicator")
3536public:
@@ -41,13 +42,18 @@ public:
4142 bool forceHidden() const;
4243 void setForceHidden(bool forceHidden);
4344
45+ double position() const;
46+ void setPosition(double position);
47+
4448Q_SIGNALS:
4549 void forceHiddenChanged(bool forceHidden);
50+ void positionChanged(double position);
4651
4752private:
4853 BottomBarVisibilityCommunicatorShell();
4954
5055 bool m_forceHidden;
56+ double m_position;
5157};
5258
5359#endif
tests/autopilot/unity8/shell/__init__.py+14
@@ -19,6 +19,7 @@
1919
2020"""unity shell autopilot tests and emulators - sub level package."""
2121
22+from time import sleep
2223from functools import wraps
2324import logging
2425
@@ -46,3 +47,16 @@ def disable_qml_mocking(fn):
4647 tests_self._qml_mock_enabled = False
4748 return fn(*args, **kwargs)
4849 return wrapper
50+
51+class DragMixin(object):
52+ def _drag(self, x1, y1, x2, y2):
53+ cur_x = x1
54+ cur_y = y1
55+ dx = 1.0 * (x2 - x1) / 100
56+ dy = 1.0 * (y2 - y1) / 100
57+ for i in range(0, 100):
58+ self.touch._finger_move(int(cur_x), int(cur_y))
59+ sleep(0.002)
60+ cur_x += dx
61+ cur_y += dy
62+ self.touch._finger_move(int(x2), int(y2))
tests/autopilot/unity8/shell/emulators/dash.py+15−6
@@ -18,17 +18,22 @@
1818#
1919
2020from unity8.shell.emulators import UnityEmulatorBase
21−
21+from time import sleep
2222
2323class Dash(UnityEmulatorBase):
2424
2525 """An emulator that understands the Dash."""
2626
2727 def get_home_applications_grid(self):
28− return self.get_scope('home').select_single(
29− "GenericFilterGrid",
30− objectName="applications.scope"
31− )
28+ for i in range(1,10):
29+ get_grid = self.get_scope('home').select_single(
30+ "GenericFilterGrid",
31+ objectName="applications.scope"
32+ )
33+ if get_grid != None:
34+ break
35+ sleep(1)
36+ return get_grid
3237
3338 def get_application_icon(self, text):
3439 """Returns a 'Tile' icon that has the text 'text' from the application
@@ -40,7 +45,11 @@ class Dash(UnityEmulatorBase):
4045
4146 """
4247 app_grid = self.get_home_applications_grid()
43− resp_grid = app_grid.select_single('ResponsiveGridView')
48+ for i in range(1,10):
49+ resp_grid = app_grid.select_single('ResponsiveGridView')
50+ if resp_grid != None:
51+ break
52+ sleep(1)
4453 return resp_grid.select_single('Tile', text=text)
4554
4655 def get_scope(self, scope_name='home'):
tests/autopilot/unity8/shell/emulators/hud.py+8−9
@@ -21,36 +21,35 @@ from collections import namedtuple
2121
2222from unity8 import get_grid_size
2323from unity8.shell.emulators import UnityEmulatorBase
24+from unity8.shell import DragMixin
2425from autopilot.input import Touch
2526
26−
2727SwipeCoords = namedtuple('SwipeCoords', 'start_x end_x start_y end_y')
2828
29−
30−class Hud(UnityEmulatorBase):
29+class Hud(UnityEmulatorBase, DragMixin):
3130
3231 """An emulator that understands the Hud."""
3332
3433 def show(self):
3534 """Swipes open the Hud."""
36− touch = Touch.create()
35+ self.touch = Touch.create()
3736
3837 window = self.get_root_instance().select_single('QQuickView')
3938 hud_show_button = window.select_single("HudButton")
4039
4140 swipe_coords = self.get_button_swipe_coords(window, hud_show_button)
4241
43− touch.press(swipe_coords.start_x, swipe_coords.start_y)
44− touch._finger_move(swipe_coords.end_x, swipe_coords.end_y)
42+ self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
43+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y)
4544 try:
4645 hud_show_button.opacity.wait_for(1.0)
47− touch.release()
46+ self.touch.release()
4847 self.shown.wait_for(True)
4948 except AssertionError:
5049 raise
5150 finally:
52− if touch._touch_finger is not None:
53− touch.release()
51+ if self.touch._touch_finger is not None:
52+ self.touch.release()
5453
5554 def dismiss(self):
5655 """Closes the open Hud."""
tests/autopilot/unity8/shell/emulators/main_window.py+3
@@ -58,6 +58,9 @@ class MainWindow(object):
5858 def get_hud_show_button(self):
5959 return self.app.select_single("HudButton")
6060
61+ def get_hud_edge_drag_area(self):
62+ return self.app.select_single(objectName="hudDragArea")
63+
6164 def get_dash(self):
6265 return self.app.select_single(Dash)
6366
tests/autopilot/unity8/shell/tests/test_hud.py+43−9
@@ -19,29 +19,30 @@
1919
2020from __future__ import absolute_import
2121
22−from unity8.shell import with_lightdm_mock
22+from unity8.shell import with_lightdm_mock, DragMixin
2323from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
2424
2525from testtools.matchers import Equals
2626from autopilot.matchers import Eventually
2727
28−
29−class TestHud(UnityTestCase):
28+class TestHud(UnityTestCase, DragMixin):
3029
3130 """Tests the Shell HUD."""
3231
3332 scenarios = _get_device_emulation_scenarios()
3433
3534 def test_show_hud_button_appears(self):
36− """Swiping up while an app is active must show the 'show hud' button.
35+ """Swiping up while an app is active must show the 'show hud' button, following some behaviours.
3736 The button must disappear not opening the HUD when releasing the
38− mouse again somewhere on the screen except on the button itself.
37+ mouse again somewhere on the screen except on the button itself following a timeout.
38+ The button must disappear when touching somewhere on the screen except the button itself.
3939
4040 """
4141 self.launch_unity()
4242 self.main_window.get_greeter().swipe()
4343 window = self.main_window.get_qml_view()
4444 hud_show_button = self.main_window.get_hud_show_button()
45+ edge_drag_area = self.main_window.get_hud_edge_drag_area()
4546 hud = self.main_window.get_hud()
4647
4748 self._launch_test_app_from_app_screen()
@@ -50,16 +51,33 @@ class TestHud(UnityTestCase):
5051 window,
5152 hud_show_button
5253 )
54+ initialBottomMargin = int(hud_show_button.bottomMargin)
55+
5356 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
5457 self.addCleanup(self._maybe_release_finger)
55− self.touch._finger_move(swipe_coords.end_x, swipe_coords.end_y + hud_show_button.height);
58+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5)
59+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.5)))
60+ self.assertThat(hud_show_button.bottomMargin, Eventually(Equals(initialBottomMargin)))
61+ self._drag(swipe_coords.start_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5, swipe_coords.end_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - int(edge_drag_area.commitDistance) - 5)
5662 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
63+ self.assertThat(hud_show_button.bottomMargin, Eventually(Equals(0.0)))
5764 self.touch.release();
65+ self.assertThat(hud.shown, Equals(False))
5866 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
67+
68+ self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
69+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y - int(hud_show_button.height))
70+ self.assertThat(hud.shown, Equals(False))
71+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
72+ self.touch.release()
73+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
74+ self.touch.tap(swipe_coords.end_x, swipe_coords.end_y - int(hud_show_button.height))
5975 self.assertThat(hud.shown, Equals(False))
76+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
6077
6178 def test_show_hud_appears(self):
6279 """Releasing the touch on the 'show hud' button must display the hud.
80+ Test that the hud button stays on screen and tapping it opens the hud.
6381
6482 """
6583 self.launch_unity()
@@ -74,14 +92,28 @@ class TestHud(UnityTestCase):
7492 window,
7593 hud_show_button
7694 )
95+
7796 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
7897 self.addCleanup(self._maybe_release_finger)
79− self.touch._finger_move(swipe_coords.end_x, swipe_coords.end_y)
80−
98+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y)
99+ self.assertThat(hud.shown, Eventually(Equals(False)))
100+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
101+ self.touch.release()
102+ self.assertThat(hud.shown, Eventually(Equals(True)))
103+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
104+ x, y = hud.get_close_button_coords()
105+ self.touch.tap(x, y)
81106 self.assertThat(hud.shown, Eventually(Equals(False)))
107+
108+ self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
109+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y - int(hud_show_button.height))
110+ self.assertThat(hud.shown, Equals(False))
82111 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
83112 self.touch.release()
113+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
114+ self.touch.tap(swipe_coords.end_x, swipe_coords.end_y)
84115 self.assertThat(hud.shown, Eventually(Equals(True)))
116+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
85117
86118 def test_hide_hud_click(self):
87119 """Tapping the close button of the Hud must dismiss it."""
@@ -90,6 +122,7 @@ class TestHud(UnityTestCase):
90122 hud = self.main_window.get_hud()
91123
92124 self._launch_test_app_from_app_screen()
125+
93126 hud.show()
94127
95128 x, y = hud.get_close_button_coords()
@@ -103,10 +136,11 @@ class TestHud(UnityTestCase):
103136 """
104137 self.launch_unity()
105138 self.main_window.get_greeter().swipe()
106− hud = self.main_window.get_hud()
107139 window = self.main_window.get_qml_view()
140+ hud = self.main_window.get_hud()
108141
109142 self._launch_test_app_from_app_screen()
143+
110144 hud.show()
111145
112146 start_x, start_y = hud.get_close_button_coords()