on xenial help sign in
initial take on keyboard navigation support

still need the UITK to export the focus ring

commit687f06844e1937749e3f27352f95559d77bfc60c authorMichael Zanetti <michael.zanetti@canonical.com> dateTue 13 Dec 2016, 15:44 (10 years ago) parentcfcde21
5 files changed+92−17
qml/Launcher/Drawer.qml+80−4 qml/Launcher/DrawerGridView.qml+3−1 qml/Launcher/DrawerListView.qml+6 qml/Launcher/Launcher.qml+1−2 qml/Launcher/MoreAppsHeader.qml+2−10
qml/Launcher/Drawer.qml+80−4
@@ -20,6 +20,7 @@ import Unity.Launcher 0.1
2020import Utils 0.1
2121import "../Components"
2222import Qt.labs.settings 1.0
23+import GSettings 1.0
2324
2425FocusScope {
2526 id: root
@@ -43,6 +44,12 @@ FocusScope {
4344 searchField.focus = true;
4445 }
4546
47+ Keys.onPressed: {
48+ // Catch all presses here in case the navigation lets something through
49+ // We never want to end up in the launcher with focus
50+ event.accepted = true;
51+ }
52+
4653 Settings {
4754 property alias selectedTab: sections.selectedIndex
4855 }
@@ -79,6 +86,9 @@ FocusScope {
7986 anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) }
8087 placeholderText: i18n.tr("Search…")
8188 focus: true
89+
90+ KeyNavigation.down: sections
91+
8292 onAccepted: {
8393 if (searchField.displayText != "" && listLoader.item && listLoader.item.currentItem) {
8494 root.applicationSelected(listLoader.item.getFirstAppId());
@@ -96,13 +106,19 @@ FocusScope {
96106 Sections {
97107 id: sections
98108 width: parent.width
109+
110+ KeyNavigation.up: searchField
111+ KeyNavigation.down: headerFocusScope
112+ KeyNavigation.backtab: searchField
113+ KeyNavigation.tab: headerFocusScope
114+
99115 actions: [
100116 Action {
101117 text: i18n.ctr("Apps sorted alphabetically", "A-Z")
102118 // TODO: Disabling this for now as we don't get the right input from u-a-l yet.
103−// },
104−// Action {
105−// text: i18n.ctr("Most used apps", "Most used")
119+ },
120+ Action {
121+ text: i18n.ctr("Most used apps", "Most used")
106122 }
107123 ]
108124
@@ -115,9 +131,42 @@ FocusScope {
115131 }
116132 }
117133
134+ FocusScope {
135+ id: headerFocusScope
136+ KeyNavigation.up: sections
137+ KeyNavigation.down: listLoader.item
138+ KeyNavigation.backtab: sections
139+ KeyNavigation.tab: listLoader.item
140+
141+ GSettings {
142+ id: settings
143+ schema.id: "com.canonical.Unity8"
144+ }
145+
146+ Keys.onPressed: {
147+ switch (event.key) {
148+ case Qt.Key_Return:
149+ case Qt.Key_Enter:
150+ case Qt.Key_Space:
151+ trigger();
152+ event.accepted = true;
153+ }
154+ }
155+
156+ function trigger() {
157+ Qt.openUrlExternally(settings.appstoreUri)
158+ }
159+ }
160+
118161 Loader {
119162 id: listLoader
120163 anchors { left: parent.left; top: sectionsContainer.bottom; right: parent.right; bottom: parent.bottom; leftMargin: units.gu(1); rightMargin: units.gu(1) }
164+
165+ KeyNavigation.up: headerFocusScope
166+ KeyNavigation.down: searchField
167+ KeyNavigation.backtab: headerFocusScope
168+ KeyNavigation.tab: searchField
169+
121170 sourceComponent: {
122171 switch (sections.selectedIndex) {
123172 case 0: return aToZComponent;
@@ -167,10 +216,13 @@ FocusScope {
167216 Component {
168217 id: mostUsedComponent
169218 DrawerListView {
219+ id: mostUsedListView
170220
171221 header: MoreAppsHeader {
172222 width: parent.width
173223 height: units.gu(6)
224+ highlighted: headerFocusScope.activeFocus
225+ onClicked: headerFocusScope.trigger();
174226 }
175227
176228 model: AppDrawerProxyModel {
@@ -196,6 +248,9 @@ FocusScope {
196248 bottomMargin: units.gu(1)
197249 clip: true
198250
251+ interactive: true
252+ focus: index == mostUsedListView.currentIndex
253+
199254 model: sortProxyModel
200255
201256 delegateWidth: units.gu(8)
@@ -209,10 +264,13 @@ FocusScope {
209264 Component {
210265 id: aToZComponent
211266 DrawerListView {
267+ id: aToZListView
212268
213269 header: MoreAppsHeader {
214270 width: parent.width
215271 height: units.gu(6)
272+ highlighted: headerFocusScope.activeFocus
273+ onClicked: headerFocusScope.trigger();
216274 }
217275
218276 model: AppDrawerProxyModel {
@@ -244,7 +302,11 @@ FocusScope {
244302 anchors { left: parent.left; top: categoryNameLabel.bottom; right: parent.right; topMargin: units.gu(1) }
245303 height: rows * delegateHeight
246304
247− interactive: false
305+ interactive: true
306+ focus: index == aToZListView.currentIndex
307+ onFocusChanged: print("drawer grid", index, "has focus", focus)
308+
309+ onCurrentIndexChanged: print("grid currentIndex changed", currentIndex)
248310
249311 model: AppDrawerProxyModel {
250312 id: categoryModel
@@ -263,10 +325,13 @@ FocusScope {
263325 Component {
264326 id: drawerDelegateComponent
265327 AbstractButton {
328+ id: drawerDelegate
266329 width: GridView.view.cellWidth
267330 height: units.gu(10)
268331 objectName: "drawerItem_" + model.appId
269332
333+ property bool focused: index === GridView.view.currentIndex && GridView.view.activeFocus
334+
270335 onClicked: root.applicationSelected(model.appId)
271336
272337 Column {
@@ -290,6 +355,17 @@ FocusScope {
290355 source: model.icon
291356 }
292357 sourceFillMode: UbuntuShape.PreserveAspectCrop
358+
359+ Image {
360+ objectName: "focusRing"
361+ anchors.centerIn: parent
362+ height: width * 15 / 16
363+ width: parent.width + units.gu(1)
364+ source: "graphics/launcher-app-focus-ring.svg"
365+ sourceSize.width: width
366+ sourceSize.height: height
367+ visible: drawerDelegate.focused
368+ }
293369 }
294370
295371 Label {
qml/Launcher/DrawerGridView.qml+3−1
@@ -17,7 +17,7 @@
1717import QtQuick 2.4
1818import "../Components"
1919
20−Item {
20+FocusScope {
2121 id: root
2222
2323 property int delegateWidth: units.gu(10)
@@ -25,6 +25,7 @@ Item {
2525 property alias delegate: gridView.delegate
2626 property alias model: gridView.model
2727 property alias interactive: gridView.interactive
28+ property alias currentIndex: gridView.currentIndex
2829
2930 property alias header: gridView.header
3031 property alias topMargin: gridView.topMargin
@@ -37,6 +38,7 @@ Item {
3738 id: gridView
3839 anchors.fill: parent
3940 leftMargin: spacing
41+ focus: true
4042
4143 readonly property int overflow: width - (root.columns * root.delegateWidth)
4244 readonly property real spacing: overflow / (root.columns)
qml/Launcher/DrawerListView.qml+6
@@ -25,6 +25,12 @@ ListView {
2525 bottomMargin: units.gu(1)
2626 spacing: units.gu(1)
2727 clip: true
28+ focus: true
29+
30+ onActiveFocusChanged: {
31+ currentIndex = -1;
32+ currentIndex = 0;
33+ }
2834
2935 function getFirstAppId() {
3036 return model.appId(0);
qml/Launcher/Launcher.qml+1−2
@@ -539,8 +539,7 @@ FocusScope {
539539 if (!dragging) {
540540 if (distance > panel.width / 2) {
541541 if (root.drawerEnabled && distance > panel.width * 3 && dragDirection() !== "left") {
542− root.switchToNextState("drawer");
543− root.focus = true;
542+ root.openDrawer(false)
544543 } else {
545544 root.switchToNextState("visible");
546545 }
qml/Launcher/MoreAppsHeader.qml+2−10
@@ -1,23 +1,15 @@
11import QtQuick 2.4
22import Ubuntu.Components 1.3
3−import GSettings 1.0
43
54AbstractButton {
65 id: root
76
8− GSettings {
9− id: settings
10− schema.id: "com.canonical.Unity8"
11− }
12−
13− onClicked: {
14− Qt.openUrlExternally(settings.appstoreUri)
15− }
7+ property bool highlighted: false
168
179 UbuntuShape {
1810 width: parent.width
1911 height: parent.height - units.gu(1)
20− color: "#20ffffff"
12+ color: root.highlighted ? "red" : "#20ffffff"
2113 aspect: UbuntuShape.Flat
2214
2315 Row {