@@ -20,6 +20,7 @@ import Unity.Launcher 0.1
20import Utils 0.1
20import Utils 0.1
21import "../Components"
21import "../Components"
22import Qt.labs.settings 1.0
22import Qt.labs.settings 1.0
24FocusScope {
25FocusScope {
@@ -47,8 +48,10 @@ FocusScope {
47 if (event.text.trim() !== "") {
48 if (event.text.trim() !== "") {
48 focusInput();
49 focusInput();
49 searchField.text = event.text;
50 searchField.text = event.text;
50− event.accepted = true;
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;
54 Settings {
57 Settings {
@@ -88,6 +91,9 @@ FocusScope {
88 anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) }
91 anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) }
89 placeholderText: i18n.tr("Search…")
92 placeholderText: i18n.tr("Search…")
90 focus: true
93 focus: true
95+ KeyNavigation.down: sections
91 onAccepted: {
97 onAccepted: {
92 if (searchField.displayText != "" && listLoader.item && listLoader.item.currentItem) {
98 if (searchField.displayText != "" && listLoader.item && listLoader.item.currentItem) {
93 root.applicationSelected(listLoader.item.getFirstAppId());
99 root.applicationSelected(listLoader.item.getFirstAppId());
@@ -104,7 +110,14 @@ FocusScope {
105 Sections {
111 Sections {
106 id: sections
112 id: sections
113+ objectName: "drawerSections"
107 width: parent.width
114 width: parent.width
116+ KeyNavigation.up: searchField
117+ KeyNavigation.down: headerFocusScope
118+ KeyNavigation.backtab: searchField
119+ KeyNavigation.tab: headerFocusScope
108 actions: [
121 actions: [
110 text: i18n.ctr("Apps sorted alphabetically", "A-Z")
123 text: i18n.ctr("Apps sorted alphabetically", "A-Z")
@@ -124,9 +137,45 @@ 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
151+ schema.id: "com.canonical.Unity8"
155+ switch (event.key) {
160+ event.accepted = true;
164+ function trigger() {
165+ Qt.openUrlExternally(settings.appstoreUri)
128 id: listLoader
170 id: listLoader
171+ objectName: "drawerListLoader"
129− anchors { left: parent.left; top: sectionsContainer.bottom; right: parent.right; bottom: parent.bottom; leftMargin: units.gu(1); rightMargin: units.gu(1) }
172+ anchors { left: parent.left; top: sectionsContainer.bottom; right: parent.right; bottom: parent.bottom }
174+ KeyNavigation.up: headerFocusScope
175+ KeyNavigation.down: searchField
176+ KeyNavigation.backtab: headerFocusScope
177+ KeyNavigation.tab: searchField
130 sourceComponent: {
179 sourceComponent: {
131 switch (sections.selectedIndex) {
180 switch (sections.selectedIndex) {
132 case 0: return aToZComponent;
181 case 0: return aToZComponent;
@@ -176,10 +225,13 @@ FocusScope {
176 Component {
225 Component {
177 id: mostUsedComponent
226 id: mostUsedComponent
178 DrawerListView {
227 DrawerListView {
228+ id: mostUsedListView
180 header: MoreAppsHeader {
230 header: MoreAppsHeader {
181 width: parent.width
231 width: parent.width
182 height: units.gu(6)
232 height: units.gu(6)
233+ highlighted: headerFocusScope.activeFocus
234+ onClicked: headerFocusScope.trigger();
185 model: AppDrawerProxyModel {
237 model: AppDrawerProxyModel {
@@ -189,7 +241,8 @@ FocusScope {
191 delegate: UbuntuShape {
243 delegate: UbuntuShape {
192− width: parent.width
244+ width: parent.width - units.gu(2)
245+ anchors.horizontalCenter: parent.horizontalCenter
193 color: "#20ffffff"
246 color: "#20ffffff"
194 aspect: UbuntuShape.Flat
247 aspect: UbuntuShape.Flat
195 // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
248 // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
@@ -205,6 +258,9 @@ FocusScope {
205 bottomMargin: units.gu(1)
258 bottomMargin: units.gu(1)
206 clip: true
259 clip: true
262+ focus: index == mostUsedListView.currentIndex
208 model: sortProxyModel
264 model: sortProxyModel
210 delegateWidth: units.gu(8)
266 delegateWidth: units.gu(8)
@@ -218,10 +274,13 @@ FocusScope {
218 Component {
274 Component {
219 id: aToZComponent
275 id: aToZComponent
220 DrawerListView {
276 DrawerListView {
222 header: MoreAppsHeader {
279 header: MoreAppsHeader {
223 width: parent.width
280 width: parent.width
224 height: units.gu(6)
281 height: units.gu(6)
282+ highlighted: headerFocusScope.activeFocus
283+ onClicked: headerFocusScope.trigger();
227 model: AppDrawerProxyModel {
286 model: AppDrawerProxyModel {
@@ -231,7 +290,8 @@ FocusScope {
233 delegate: UbuntuShape {
292 delegate: UbuntuShape {
234− width: parent.width
293+ width: parent.width - units.gu(2)
294+ anchors.horizontalCenter: parent.horizontalCenter
235 color: "#20ffffff"
295 color: "#20ffffff"
236 aspect: UbuntuShape.Flat
296 aspect: UbuntuShape.Flat
@@ -253,7 +313,8 @@ FocusScope {
253 anchors { left: parent.left; top: categoryNameLabel.bottom; right: parent.right; topMargin: units.gu(1) }
313 anchors { left: parent.left; top: categoryNameLabel.bottom; right: parent.right; topMargin: units.gu(1) }
254 height: rows * delegateHeight
314 height: rows * delegateHeight
256− interactive: false
316+ interactive: true
317+ focus: index == aToZListView.currentIndex
258 model: AppDrawerProxyModel {
319 model: AppDrawerProxyModel {
259 id: categoryModel
320 id: categoryModel
@@ -272,10 +333,13 @@ FocusScope {
272 Component {
333 Component {
273 id: drawerDelegateComponent
334 id: drawerDelegateComponent
274 AbstractButton {
335 AbstractButton {
275 width: GridView.view.cellWidth
337 width: GridView.view.cellWidth
276 height: units.gu(10)
338 height: units.gu(10)
277 objectName: "drawerItem_" + model.appId
339 objectName: "drawerItem_" + model.appId
341+ readonly property bool focused: index === GridView.view.currentIndex && GridView.view.activeFocus
279 onClicked: root.applicationSelected(model.appId)
343 onClicked: root.applicationSelected(model.appId)
@@ -299,6 +363,15 @@ FocusScope {
299 source: model.icon
363 source: model.icon
301 sourceFillMode: UbuntuShape.PreserveAspectCrop
365 sourceFillMode: UbuntuShape.PreserveAspectCrop
368+ styleName: "FocusShape"
369+ anchors.fill: parent
371+ visible: drawerDelegate.focused
372+ radius: units.gu(2.55)