on xenial help sign in
add some stacking animation
df92548Michael Zanetti
qml/Stages/DesktopStage.qml+21−6
@@ -46,7 +46,7 @@ FocusScope {
46 if (root.altTabPressed) {
46 if (root.altTabPressed) {
47 print("should tab next")
47 print("should tab next")
48 appRepeater.highlightedIndex = (appRepeater.highlightedIndex + 1) % ApplicationManager.count
48 appRepeater.highlightedIndex = (appRepeater.highlightedIndex + 1) % ApplicationManager.count
49− spreadFlickable.snapTo(spreadFlickable.width / 5 * Math.max(0, Math.min(ApplicationManager.count - 5, appRepeater.highlightedIndex - 2)))
49+ spreadFlickable.snapTo(spreadFlickable.width / 5 * Math.max(0, Math.min(ApplicationManager.count - 5, appRepeater.highlightedIndex - 3)))
50 }
50 }
51 }
51 }
52
52
@@ -55,7 +55,7 @@ FocusScope {
55 if (root.altTabPressed) {
55 if (root.altTabPressed) {
56 var newIndex = appRepeater.highlightedIndex - 1 >= 0 ? appRepeater.highlightedIndex - 1 : ApplicationManager.count - 1;
56 var newIndex = appRepeater.highlightedIndex - 1 >= 0 ? appRepeater.highlightedIndex - 1 : ApplicationManager.count - 1;
57 appRepeater.highlightedIndex = newIndex;
57 appRepeater.highlightedIndex = newIndex;
58− spreadFlickable.snapTo(spreadFlickable.width / 5 * Math.max(0, Math.min(ApplicationManager.count - 5, appRepeater.highlightedIndex - 2)))
58+ spreadFlickable.snapTo(spreadFlickable.width / 5 * Math.max(0, Math.min(ApplicationManager.count - 5, appRepeater.highlightedIndex - 1)))
59 }
59 }
60 }
60 }
61
61
@@ -151,9 +151,9 @@ FocusScope {
151 name: "altTab"; when: root.state == "altTab"
151 name: "altTab"; when: root.state == "altTab"
152 PropertyChanges {
152 PropertyChanges {
153 target: appDelegate
153 target: appDelegate
154− x: spreadMaths.desktopX(index, root.width, spreadFlickable.contentX)
154+ x: spreadMaths.animatedX
155 y: spreadMaths.desktopY(root.height, appDelegate.height)
155 y: spreadMaths.desktopY(root.height, appDelegate.height)
156− angle: spreadMaths.desktopAngle(index, spreadFlickable.contentX)
156+ angle: spreadMaths.animatedAngle
157 itemScale: spreadMaths.desktopScale(root.height, appDelegate.height)
157 itemScale: spreadMaths.desktopScale(root.height, appDelegate.height)
158 itemScaleOriginY: appDelegate.height;
158 itemScaleOriginY: appDelegate.height;
159 color: "green"
159 color: "green"
@@ -169,7 +169,7 @@ FocusScope {
169 }
169 }
170 PropertyChanges {
170 PropertyChanges {
171 target: tileInfo
171 target: tileInfo
172− visible: true
172+ visible: spreadMaths.desktopTitleInfoShown(index, spreadFlickable.contentX)
173 }
173 }
174 }
174 }
175 ]
175 ]
@@ -187,6 +187,9 @@ FocusScope {
187
187
188 SpreadMaths {
188 SpreadMaths {
189 id: spreadMaths
189 id: spreadMaths
190+ flickable: spreadFlickable
191+ itemIndex: index
192+ totalItems: ApplicationManager.count
190 }
193 }
191
194
192 WindowMoveResizeArea {
195 WindowMoveResizeArea {
@@ -269,7 +272,11 @@ FocusScope {
269 anchors.fill: parent
272 anchors.fill: parent
270 contentWidth: ApplicationManager.count * width / 5
273 contentWidth: ApplicationManager.count * width / 5
271 visible: false
274 visible: false
272− onContentXChanged: print("flickable flicked", contentX)
275+ //boundsBehavior: Flickable.StopAtBounds
276+
277+ function ensureVisible(index) {
278+
279+ }
273
280
274 function snapTo(contentX) {
281 function snapTo(contentX) {
275 snapAnimation.to = contentX
282 snapAnimation.to = contentX
@@ -283,6 +290,14 @@ FocusScope {
283 }
290 }
284 }
291 }
285
292
293+ Label {
294+ anchors { left: parent.left; bottom: parent.bottom; margins: units.gu(1) }
295+ text: "Progress: " + (spreadFlickable.contentX / (spreadFlickable.contentWidth - spreadFlickable.width))
296+ color: "red"
297+ fontSize: "x-large"
298+ z: 100
299+ }
300+
286 states: [
301 states: [
287 State {
302 State {
288 name: "windowed"
303 name: "windowed"
qml/Stages/SpreadMaths.qml+74−35
@@ -1,43 +1,66 @@
1import QtQuick 2.2
1import QtQuick 2.2
2+import Ubuntu.Components 1.1
2import Utils 0.1
3import Utils 0.1
3import Unity.Application 0.1
4import Unity.Application 0.1
4
5
5−QtObject {
6+Item {
6− id: root
7
7
8− function desktopX(index, totalWidth, flickableX) {
8+ Label {
9− var margins = units.gu(5);
9+ anchors {left: parent.left; top: parent.top }
10− var distance = (totalWidth - margins * 2) / 5;
10+ text: "prog:" + transitionCurve.progress.toFixed(2)
11− var foldedDistance = units.gu(0.5)
11+ color: isInLeftFoldingArea ? "red" : "black"
12− var reverseIndex = ApplicationManager.count - index
13−
14− var x = (index * distance) - flickableX + margins;
15− // limit at left
16− x = Math.max(margins + foldedDistance * index, x);
17− // limit at right
18− x = Math.min(totalWidth - margins - distance - foldedDistance * reverseIndex, x);
19−
20− return x
21−
22−
23− var startProgress = 0;
24− var endProgress = 1;
25− var startValue = index * distance;
26− var endValue = 0;
27− var progress = 1.0 * flickableX / startValue;
28− print("progress for tile", index, ":", startProgress, endProgress, startValue, endValue, progress)
29− var x = easingAnimation(startProgress, endProgress, startValue, endValue, progress);
30− print("resulting x:", x)
31− return x + units.gu(5);
32 }
12 }
33
13
14+ id: root
15+ anchors { left: parent.left; top: parent.top; margins: units.gu(1) }
16+
17+ property int itemIndex: 0
18+ property int totalItems: 0
19+ property Item flickable: null
20+ property int margins: units.gu(5)
21+ property int foldingAreaWidth: units.gu(5)
22+
23+ property int maxVisibleItems: 5
24+
25+ readonly property int flickableWidth: flickable ? flickable.width : 0
26+ readonly property int flickableContentWidth: flickable ? flickable.contentWidth: 0
27+ readonly property real flickableProgress: flickable ? flickable.contentX / (flickable.contentWidth - flickableWidth) : 0
28+
29+ readonly property int contentWidth: flickableWidth - root.margins * 2
30+
31+ readonly property int unfoldedDistance: (contentWidth - foldingAreaWidth) / maxVisibleItems
32+
33+ // Internal
34+ readonly property real progressSlice: 1 / totalItems;
35+ readonly property real startProgress: Math.max(0, index - 2) * progressSlice
36+ readonly property real endProgress: (index + 3) * progressSlice
37+
38+ readonly property real startX: index < maxVisibleItems ?
39+ margins + index * unfoldedDistance
40+ : contentWidth - foldingAreaWidth + (startLayout.value * foldingAreaWidth)
41+
42+ readonly property real endX: totalItems - maxVisibleItems < index ?
43+ contentWidth - (totalItems - index) * unfoldedDistance
44+ : margins + foldingAreaWidth - (endLayout.value * foldingAreaWidth)
45+
46+ readonly property int animatedX: transitionCurve.value * (endX - startX) + startX
47+
34 function desktopY(sceneHeight, itemHeight) {
48 function desktopY(sceneHeight, itemHeight) {
35 return sceneHeight - itemHeight - (sceneHeight * 0.2);
49 return sceneHeight - itemHeight - (sceneHeight * 0.2);
36 }
50 }
37
51
38− function desktopAngle(index, flickableX) {
52+ property int leftEndFoldedAngle: 80
39− return 40;
53+ property int rightEndFoldedAngle: 60
40− }
54+ property int unfoldedAngle: 30
55+
56+ property bool isInLeftFoldingArea: animatedX < foldingAreaWidth + margins
57+
58+ // x : foldingAreaWidth = leftEndFoldedAngle: unfoldedAngle:
59+
60+ readonly property int animatedAngle: isInLeftFoldingArea ?
61+ ((foldingAreaWidth + margins) - x) * unfoldedAngle / leftEndFoldedAngle
62+ : unfoldedAngle
63+
41
64
42 function desktopScale(sceneHeight, itemHeight) {
65 function desktopScale(sceneHeight, itemHeight) {
43 var maxHeight = sceneHeight * 0.35;
66 var maxHeight = sceneHeight * 0.35;
@@ -47,14 +70,30 @@ QtObject {
47 return 1;
70 return 1;
48 }
71 }
49
72
50− function easingAnimation(startProgress, endProgress, startValue, endValue, progress) {
73+ function desktopTitleInfoShown(index, flickableX) {
51− easingCurve.progress = progress - startProgress;
74+ return true;
52− easingCurve.period = endProgress - startProgress;
75+ }
53− return easingCurve.value * (endValue - startValue) + startValue;
76+
77+ EasingCurve {
78+ id: transitionCurve
79+ type: easingCurve.InOutSine
80+
81+ readonly property real normalizedEndProgress: endProgress - startProgress
82+ readonly property real normalizedProgress: (root.flickableProgress - root.startProgress) / normalizedEndProgress
83+ progress: normalizedProgress
84+ }
85+
86+ EasingCurve {
87+ id: startLayout
88+ type: EasingCurve.OutSine
89+ // total : 1 = index : p
90+ progress: 1.0 * index / root.totalItems
54 }
91 }
55
92
56− property var easingCurve: EasingCurve {
93+ EasingCurve {
94+ id: endLayout
57 type: EasingCurve.OutSine
95 type: EasingCurve.OutSine
58− period: 1
96+ // total : 1 = index : p
97+ progress: 1 - (1.0 * index / root.totalItems)
59 }
98 }
60}
99}
tests/qmltests/tst_DesktopShell.qml+9
@@ -126,6 +126,15 @@ Item {
126 }
126 }
127 }
127 }
128
128
129+ Button {
130+ text: "Start all apps"
131+ onClicked: {
132+ for (var i = 0; i < ApplicationManager.availableApplications.length; i++) {
133+ ApplicationManager.startApplication(ApplicationManager.availableApplications[i])
134+ }
135+ }
136+ }
137+
129 Repeater {
138 Repeater {
130 id: apps
139 id: apps
131 model: ApplicationManager.availableApplications
140 model: ApplicationManager.availableApplications