@@ -48,6 +48,10 @@ FocusScope {
49 signal backClicked()
49 signal backClicked()
52+ floatingSeeLess.companionBase = null;
51 function positionAtBeginning() {
55 function positionAtBeginning() {
52 categoryView.positionAtBeginning()
56 categoryView.positionAtBeginning()
@@ -154,11 +158,55 @@ FocusScope {
154 pixelAligned: true
158 pixelAligned: true
155 interactive: !navigationShown
159 interactive: !navigationShown
157− property Item expandedCategoryItem: null
161+ property string expandedCategoryId: ""
162+ property int runMaximizeAfterSizeChanges: 0
159 readonly property bool pageHeaderTotallyVisible: scopeView.showPageHeader &&
164 readonly property bool pageHeaderTotallyVisible: scopeView.showPageHeader &&
160 ((headerItemShownHeight == 0 && categoryView.contentY <= categoryView.originY) || (headerItemShownHeight == pageHeaderLoader.item.height))
165 ((headerItemShownHeight == 0 && categoryView.contentY <= categoryView.originY) || (headerItemShownHeight == pageHeaderLoader.item.height))
167+ onExpandedCategoryIdChanged: {
168+ var firstCreated = firstCreatedIndex();
169+ var shrinkingAny = false;
170+ var shrinkHeightDifference = 0;
171+ for (var i = 0; i < createdItemCount(); ++i) {
172+ var baseItem = item(firstCreated + i);
173+ if (baseItem.expandable) {
174+ var shouldExpand = baseItem.category === expandedCategoryId;
175+ if (shouldExpand != baseItem.expanded) {
177+ var animate = false;
178+ if (!subPageLoader.open) {
179+ var animateShrinking = !shouldExpand && baseItem.y + baseItem.item.collapsedHeight + baseItem.seeAll.height < categoryView.height;
180+ var animateGrowing = shouldExpand && baseItem.y + baseItem.height < categoryView.height;
181+ animate = shrinkingAny || animateShrinking || animateGrowing;
184+ if (!shouldExpand) {
185+ shrinkingAny = true;
186+ shrinkHeightDifference = baseItem.item.expandedHeight - baseItem.item.collapsedHeight;
189+ if (shouldExpand && !subPageLoader.open) {
190+ if (!shrinkingAny) {
191+ categoryView.maximizeVisibleArea(firstCreated + i, baseItem.item.expandedHeight + baseItem.seeAll.height);
193+ // If the space that shrkinking is smaller than the one we need to grow we'll call maximizeVisibleArea
194+ // after the shrink/grow animation ends
195+ var growHeightDifference = baseItem.item.expandedHeight - baseItem.item.collapsedHeight;
196+ if (growHeightDifference > shrinkHeightDifference) {
197+ runMaximizeAfterSizeChanges = 2;
199+ runMaximizeAfterSizeChanges = 0;
204+ baseItem.expand(shouldExpand, animate);
162 delegate: ListItems.Base {
210 delegate: ListItems.Base {
163 id: baseItem
211 id: baseItem
164 objectName: "dashCategory" + category
212 objectName: "dashCategory" + category
@@ -177,6 +225,7 @@ FocusScope {
177 readonly property string category: categoryId
225 readonly property string category: categoryId
178 readonly property string headerLink: model.headerLink
226 readonly property string headerLink: model.headerLink
179 readonly property var item: rendererLoader.item
227 readonly property var item: rendererLoader.item
228+ readonly property var seeAll: seeAll
181 function expand(expand, animate) {
230 function expand(expand, animate) {
182 heightBehaviour.enabled = animate;
231 heightBehaviour.enabled = animate;
@@ -196,7 +245,7 @@ FocusScope {
196 // This can happen with the VJ that doesn't know how height it will be on creation
245 // This can happen with the VJ that doesn't know how height it will be on creation
197 // so doesn't set expandable until a bit too late for onLoaded
246 // so doesn't set expandable until a bit too late for onLoaded
198 if (expandable) {
247 if (expandable) {
199− var shouldExpand = baseItem === categoryView.expandedCategoryItem;
248+ var shouldExpand = baseItem.category === categoryView.expandedCategoryId;
200 baseItem.expand(shouldExpand, false /*animate*/);
249 baseItem.expand(shouldExpand, false /*animate*/);
@@ -217,9 +266,23 @@ FocusScope {
217 id: heightBehaviour
266 id: heightBehaviour
218 enabled: false
267 enabled: false
219 animation: UbuntuNumberAnimation {
268 animation: UbuntuNumberAnimation {
269+ duration: UbuntuAnimation.FastDuration
220 onRunningChanged: {
270 onRunningChanged: {
221 if (!running) {
271 if (!running) {
222 heightBehaviour.enabled = false
272 heightBehaviour.enabled = false
273+ if (categoryView.runMaximizeAfterSizeChanges > 0) {
274+ categoryView.runMaximizeAfterSizeChanges--;
275+ if (categoryView.runMaximizeAfterSizeChanges == 0) {
276+ var firstCreated = categoryView.firstCreatedIndex();
277+ for (var i = 0; i < categoryView.createdItemCount(); ++i) {
278+ var baseItem = categoryView.item(firstCreated + i);
279+ if (baseItem.category === categoryView.expandedCategoryId) {
280+ categoryView.maximizeVisibleArea(firstCreated + i, baseItem.item.expandedHeight + baseItem.seeAll.height);
@@ -247,7 +310,7 @@ FocusScope {
247 item.objectName = Qt.binding(function() { return categoryId })
310 item.objectName = Qt.binding(function() { return categoryId })
248 item.scopeStyle = scopeView.scopeStyle;
311 item.scopeStyle = scopeView.scopeStyle;
249 if (baseItem.expandable) {
312 if (baseItem.expandable) {
250− var shouldExpand = baseItem === categoryView.expandedCategoryItem;
313+ var shouldExpand = baseItem.category === categoryView.expandedCategoryId;
251 baseItem.expand(shouldExpand, false /*animate*/);
314 baseItem.expand(shouldExpand, false /*animate*/);
253 updateRanges();
316 updateRanges();
@@ -374,10 +437,11 @@ FocusScope {
374 height: seeAllLabel.visible ? seeAllLabel.font.pixelSize + units.gu(4) : 0
437 height: seeAllLabel.visible ? seeAllLabel.font.pixelSize + units.gu(4) : 0
376 onClicked: {
439 onClicked: {
377− if (categoryView.expandedCategoryItem !== baseItem) {
440+ if (categoryView.expandedCategoryId !== baseItem.category) {
378− categoryView.expandedCategoryItem = baseItem;
441+ categoryView.expandedCategoryId = baseItem.category;
442+ floatingSeeLess.companionBase = baseItem;
380− categoryView.expandedCategoryItem = null;
444+ categoryView.expandedCategoryId = "";
@@ -477,7 +541,7 @@ FocusScope {
477 objectName: "floatingSeeLess"
541 objectName: "floatingSeeLess"
479 property Item companionTo: companionBase ? companionBase.seeAllButton : null
543 property Item companionTo: companionBase ? companionBase.seeAllButton : null
480− property Item companionBase: categoryView.expandedCategoryItem
544+ property Item companionBase: null
481 property bool showBecausePosition: false
545 property bool showBecausePosition: false
482 property real yOffset: 0
546 property real yOffset: 0
@@ -489,7 +553,7 @@ FocusScope {
489 height: seeLessLabel.font.pixelSize + units.gu(4)
553 height: seeLessLabel.font.pixelSize + units.gu(4)
490 visible: companionTo && showBecausePosition
554 visible: companionTo && showBecausePosition
492− onClicked: categoryView.expandedCategoryItem = null;
556+ onClicked: categoryView.expandedCategoryId = "";
494 function updateVisibility() {
558 function updateVisibility() {
495 var companionPos = companionTo.mapToItem(floatingSeeLess, 0, 0);
559 var companionPos = companionTo.mapToItem(floatingSeeLess, 0, 0);
@@ -498,6 +562,10 @@ FocusScope {
498 var posToBase = floatingSeeLess.mapToItem(companionBase, 0, -yOffset).y;
562 var posToBase = floatingSeeLess.mapToItem(companionBase, 0, -yOffset).y;
499 yOffset = Math.max(0, companionBase.item.collapsedHeight - posToBase);
563 yOffset = Math.max(0, companionBase.item.collapsedHeight - posToBase);
500 yOffset = Math.min(yOffset, height);
564 yOffset = Math.min(yOffset, height);
566+ if (!showBecausePosition && categoryView.expandedCategoryId === "") {
567+ companionBase = null;