@@ -16,15 +16,60 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import "../Components"
21import "../Components"
20import "../Components/ListItems" as ListItems
22import "../Components/ListItems" as ListItems
22−ScopeView {
24+FocusScope {
23 id: scopeView
25 id: scopeView
28+ property SortFilterProxyModel categories: categoryFilter
29+ property bool isCurrent
30+ property ListModel searchHistory
31+ property alias moving: categoryView.moving
34+ signal movementStarted
35+ signal positionedAtBeginning
24 readonly property alias previewShown: previewListView.onScreen
37 readonly property alias previewShown: previewListView.onScreen
25 property bool enableHeightBehaviorOnNextCreation: false
38 property bool enableHeightBehaviorOnNextCreation: false
27− moving: categoryView.moving
40+ // FIXME delay the search so that daemons have time to settle, note that
41+ // removing this will break ScopeView::test_changeScope
45+ scope.activateApplication.connect(activateApp);
49+ function activateApp(desktopFilePath) {
50+ shell.activateApplication(desktopFilePath);
62+ onTriggered: scope.searchQuery = ""
65+ SortFilterProxyModel {
67+ model: scope ? scope.categories : null
68+ dynamicSortFilter: true
69+ filterRole: Categories.RoleCount
29 onIsCurrentChanged: {
74 onIsCurrentChanged: {
30 pageHeader.resetSearch();
75 pageHeader.resetSearch();
@@ -130,14 +175,14 @@ ScopeView {
130 target: rendererLoader.item
175 target: rendererLoader.item
131 onClicked: {
176 onClicked: {
132 // Prepare the preview in case activate() triggers a preview only
177 // Prepare the preview in case activate() triggers a preview only
133− effect.positionPx = mapToItem(categoryView, 0, itemY).y
178+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
134 previewListView.categoryId = categoryId
179 previewListView.categoryId = categoryId
135 previewListView.categoryDelegate = rendererLoader.item
180 previewListView.categoryDelegate = rendererLoader.item
136− previewListView.model = model;
181+ previewListView.model = target.model;
137 previewListView.init = true;
182 previewListView.init = true;
138 previewListView.currentIndex = index;
183 previewListView.currentIndex = index;
140− var item = model.get(index);
185+ var item = target.model.get(index);
142 if ((scopeView.scope.id == "applications.scope" && categoryId == "installed")
187 if ((scopeView.scope.id == "applications.scope" && categoryId == "installed")
143 || (scopeView.scope.id == "home.scope" && categoryId == "applications.scope")) {
188 || (scopeView.scope.id == "home.scope" && categoryId == "applications.scope")) {
@@ -151,15 +196,15 @@ ScopeView {
153 onPressAndHold: {
198 onPressAndHold: {
154− effect.positionPx = mapToItem(categoryView, 0, itemY).y
199+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
155 previewListView.categoryId = categoryId
200 previewListView.categoryId = categoryId
156 previewListView.categoryDelegate = rendererLoader.item
201 previewListView.categoryDelegate = rendererLoader.item
157− previewListView.model = model;
202+ previewListView.model = target.model;
158 previewListView.init = true;
203 previewListView.init = true;
159 previewListView.currentIndex = index;
204 previewListView.currentIndex = index;
160 previewListView.open = true
205 previewListView.open = true
162− var item = model.get(index)
207+ var item = target.model.get(index)
163 scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
208 scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
164 item.comment, item.dndUri, item.metadata)
209 item.comment, item.dndUri, item.metadata)
@@ -393,12 +438,19 @@ ScopeView {
394 if (!init && model !== undefined) {
439 if (!init && model !== undefined) {
395 var item = model.get(currentIndex)
440 var item = model.get(currentIndex)
396− scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
441+ scopeView.scope.preview(item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
399 var itemY = categoryView.contentItem.mapFromItem(categoryDelegate.currentItem).y;
444 var itemY = categoryView.contentItem.mapFromItem(categoryDelegate.currentItem).y;
446+ // Find new contentY and effect.postionPx
400 var newContentY = itemY - effect.positionPx - categoryDelegate.verticalSpacing;
447 var newContentY = itemY - effect.positionPx - categoryDelegate.verticalSpacing;
449+ // Make sure the item is not covered by a header. Move the effect split down if necessary
450+ var headerHeight = pageHeader.height + categoryView.stickyHeaderHeight;
401− var effectAdjust = effect.positionPx;
451+ var effectAdjust = Math.max(effect.positionPx, headerHeight);
453+ // Make sure we don't overscroll the listview. If yes, adjust effect position
402 if (newContentY < 0) {
454 if (newContentY < 0) {
403 effectAdjust += newContentY;
455 effectAdjust += newContentY;
404 newContentY = 0;
456 newContentY = 0;
@@ -409,7 +461,7 @@ ScopeView {
411 effect.positionPx = effectAdjust;
463 effect.positionPx = effectAdjust;
412− categoryView.contentY = newContentY - categoryView.originY;
464+ categoryView.contentY = newContentY;
415 property bool open: false
467 property bool open: false