@@ -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,16 @@ FocusScope {
4344 searchField.focus = true;
4445 }
4546
47+ Keys.onPressed: {
48+ if (event.text.trim() !== "") {
49+ focusInput();
50+ searchField.text = event.text;
51+ }
52+ // Catch all presses here in case the navigation lets something through
53+ // We never want to end up in the launcher with focus
54+ event.accepted = true;
55+ }
56+
4657 Settings {
4758 property alias selectedTab: sections.selectedIndex
4859 }
@@ -76,9 +87,13 @@ FocusScope {
7687
7788 TextField {
7889 id: searchField
90+ objectName: "searchField"
7991 anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) }
8092 placeholderText: i18n.tr("Search…")
8193 focus: true
94+
95+ KeyNavigation.down: sections
96+
8297 onAccepted: {
8398 if (searchField.displayText != "" && listLoader.item && listLoader.item.currentItem) {
8499 root.applicationSelected(listLoader.item.getFirstAppId());
@@ -95,14 +110,21 @@ FocusScope {
95110
96111 Sections {
97112 id: sections
113+ objectName: "drawerSections"
98114 width: parent.width
115+
116+ KeyNavigation.up: searchField
117+ KeyNavigation.down: headerFocusScope
118+ KeyNavigation.backtab: searchField
119+ KeyNavigation.tab: headerFocusScope
120+
99121 actions: [
100122 Action {
101123 text: i18n.ctr("Apps sorted alphabetically", "A-Z")
102124 // 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")
125+ },
126+ Action {
127+ text: i18n.ctr("Most used apps", "Most used")
106128 }
107129 ]
108130
@@ -115,9 +137,45 @@ FocusScope {
115137 }
116138 }
117139
140+ FocusScope {
141+ id: headerFocusScope
142+ objectName: "headerFocusScope"
143+ KeyNavigation.up: sections
144+ KeyNavigation.down: listLoader.item
145+ KeyNavigation.backtab: sections
146+ KeyNavigation.tab: listLoader.item
147+ activeFocusOnTab: true
148+
149+ GSettings {
150+ id: settings
151+ schema.id: "com.canonical.Unity8"
152+ }
153+
154+ Keys.onPressed: {
155+ switch (event.key) {
156+ case Qt.Key_Return:
157+ case Qt.Key_Enter:
158+ case Qt.Key_Space:
159+ trigger();
160+ event.accepted = true;
161+ }
162+ }
163+
164+ function trigger() {
165+ Qt.openUrlExternally(settings.appstoreUri)
166+ }
167+ }
168+
118169 Loader {
119170 id: listLoader
171+ objectName: "drawerListLoader"
120172 anchors { left: parent.left; top: sectionsContainer.bottom; right: parent.right; bottom: parent.bottom; leftMargin: units.gu(1); rightMargin: units.gu(1) }
173+
174+ KeyNavigation.up: headerFocusScope
175+ KeyNavigation.down: searchField
176+ KeyNavigation.backtab: headerFocusScope
177+ KeyNavigation.tab: searchField
178+
121179 sourceComponent: {
122180 switch (sections.selectedIndex) {
123181 case 0: return aToZComponent;
@@ -167,10 +225,13 @@ FocusScope {
167225 Component {
168226 id: mostUsedComponent
169227 DrawerListView {
228+ id: mostUsedListView
170229
171230 header: MoreAppsHeader {
172231 width: parent.width
173232 height: units.gu(6)
233+ highlighted: headerFocusScope.activeFocus
234+ onClicked: headerFocusScope.trigger();
174235 }
175236
176237 model: AppDrawerProxyModel {
@@ -196,6 +257,9 @@ FocusScope {
196257 bottomMargin: units.gu(1)
197258 clip: true
198259
260+ interactive: true
261+ focus: index == mostUsedListView.currentIndex
262+
199263 model: sortProxyModel
200264
201265 delegateWidth: units.gu(8)
@@ -209,10 +273,13 @@ FocusScope {
209273 Component {
210274 id: aToZComponent
211275 DrawerListView {
276+ id: aToZListView
212277
213278 header: MoreAppsHeader {
214279 width: parent.width
215280 height: units.gu(6)
281+ highlighted: headerFocusScope.activeFocus
282+ onClicked: headerFocusScope.trigger();
216283 }
217284
218285 model: AppDrawerProxyModel {
@@ -244,7 +311,11 @@ FocusScope {
244311 anchors { left: parent.left; top: categoryNameLabel.bottom; right: parent.right; topMargin: units.gu(1) }
245312 height: rows * delegateHeight
246313
247− interactive: false
314+ interactive: true
315+ focus: index == aToZListView.currentIndex
316+ onFocusChanged: print("drawer grid", index, "has focus", focus)
317+
318+ onCurrentIndexChanged: print("grid currentIndex changed", currentIndex)
248319
249320 model: AppDrawerProxyModel {
250321 id: categoryModel
@@ -263,10 +334,13 @@ FocusScope {
263334 Component {
264335 id: drawerDelegateComponent
265336 AbstractButton {
337+ id: drawerDelegate
266338 width: GridView.view.cellWidth
267339 height: units.gu(10)
268340 objectName: "drawerItem_" + model.appId
269341
342+ readonly property bool focused: index === GridView.view.currentIndex && GridView.view.activeFocus
343+
270344 onClicked: root.applicationSelected(model.appId)
271345
272346 Column {
@@ -290,6 +364,17 @@ FocusScope {
290364 source: model.icon
291365 }
292366 sourceFillMode: UbuntuShape.PreserveAspectCrop
367+
368+ Image {
369+ objectName: "focusRing"
370+ anchors.centerIn: parent
371+ height: width * 15 / 16
372+ width: parent.width + units.gu(1)
373+ source: "graphics/launcher-app-focus-ring.svg"
374+ sourceSize.width: width
375+ sourceSize.height: height
376+ visible: drawerDelegate.focused
377+ }
293378 }
294379
295380 Label {