2
* Copyright (C) 2015 Canonical, Ltd.
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; version 3.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
import Ubuntu.Components 1.1
23
anchors { left: parent.left; top: parent.top; margins: units.gu(1) }
25
// Information about the transformed item
26
property int itemIndex: 0
27
property real itemHeight: units.gu(10)
29
// Information about the environment
30
property int totalItems: 0
31
property Item flickable: null
32
property int sceneHeight: units.gu(20)
35
property real spreadHeight: sceneHeight * 0.4
36
property int spreadBottomOffset: sceneHeight * 0.18
37
property int foldingAreaWidth: flickableWidth * 0.2
38
property int maxVisibleItems: 7
39
property int margins: flickableWidth * 0.05
40
property real stackScale: 0.1
41
property int leftEndFoldedAngle: 70
42
property int rightEndFoldedAngle: 65
43
property int unfoldedAngle: 30
44
property int stackWidth: flickableWidth * 0.01
48
readonly property int flickableWidth: flickable ? flickable.width : 0
49
readonly property int flickableContentWidth: flickable ? flickable.contentWidth: 0
50
readonly property real flickableProgress: flickable ? flickable.contentX / (flickable.contentWidth - flickableWidth) : 0
52
readonly property int contentWidth: flickableWidth - root.margins * 2
54
readonly property int distance: (flickableContentWidth - (margins * 2) - (foldingAreaWidth * 2)) / (totalItems - 2)
55
readonly property int startPos: margins + foldingAreaWidth + (itemIndex - 1) * distance
56
readonly property int linearX: startPos - flickableProgress * (flickableContentWidth - flickableWidth)
58
readonly property int leftFoldingAreaX: margins + foldingAreaWidth
59
readonly property int rightFoldingAreaX: flickableWidth - foldingAreaWidth - margins
61
readonly property real leftFoldingAreaProgress: linearAnimation(leftFoldingAreaX, margins, 0, 1, linearX)
62
readonly property real rightFoldingAreaProgress: linearAnimation(rightFoldingAreaX, flickableWidth - margins, 0, 1, linearX)
64
readonly property real limitedLeftProgress: Math.min(2, leftFoldingAreaProgress)
65
readonly property real limitedRightProgress: Math.min(2, rightFoldingAreaProgress)
67
readonly property real middleSectionProgress: (linearX - margins - foldingAreaWidth) / (flickableWidth - (margins + foldingAreaWidth) * 2)
70
readonly property int animatedX: {
71
if (leftFoldingAreaProgress > 4) { // Stop it at the edge
74
if (leftFoldingAreaProgress > 2) { // move it slowly through the stack
75
return linearAnimation(2, 4, margins + stackWidth, margins, leftFoldingAreaProgress)
77
if (leftFoldingAreaProgress > 1 && itemIndex == 0) {
78
// The leftmost runs faster... make it stop before the stack and wait for others
79
return margins + stackWidth;
82
if (leftFoldingAreaProgress > 0) { // slow it down in a curve
83
if (itemIndex == 0) { // except if it's the leftmost. that one goes straigt
84
return linearAnimation(0, 1, leftFoldingAreaX, margins + stackWidth, leftFoldingAreaProgress)
86
return linearAnimation(0, 1, leftFoldingAreaX, margins + stackWidth, leftEasing.value)
88
// same for the right side stack... mostly... don't need to treat the rightmost special...
89
if (rightFoldingAreaProgress > 4) {
90
return flickableWidth - margins
92
if (rightFoldingAreaProgress > 2) {
93
return linearAnimation(2, 4, flickableWidth - margins - stackWidth, flickableWidth - margins, rightFoldingAreaProgress)
96
if (rightFoldingAreaProgress > 0) {
97
return linearAnimation(0, 1, rightFoldingAreaX, flickableWidth - margins - stackWidth, rightEasing.value);
103
readonly property int animatedY: sceneHeight - itemHeight - spreadBottomOffset
105
readonly property real animatedAngle: {
106
if (limitedLeftProgress > 0) {
107
// Leftmost is special...
109
if (limitedLeftProgress < 1) {
110
return unfoldedAngle;
112
return linearAnimation(1, 2, unfoldedAngle, leftEndFoldedAngle, limitedLeftProgress)
115
return linearAnimation(0, 2, unfoldedAngle, leftEndFoldedAngle, limitedLeftProgress)
116
} else if (limitedRightProgress > 0) {
117
return linearAnimation(0, 1, unfoldedAngle, rightEndFoldedAngle, rightEasing.value)
123
readonly property real scale: limitedLeftProgress > 0 ?
124
linearAnimation(0, 1, 1, 1 + stackScale, leftEasing.value)
125
: limitedRightProgress > 0 ?
126
linearAnimation(0, 1, 1, 1 + stackScale, rightEasing.value)
127
: 0.95 + Math.abs(middleSectionProgress - 0.5) * 0.1
129
readonly property real closeIconOffset: (scale - 1) * (-root.spreadHeight / 2)
131
readonly property real tileInfoOpacity: leftFoldingAreaProgress > 0 ?
132
linearAnimation(1, 1.5, 1, 0, leftFoldingAreaProgress)
133
: rightFoldingAreaProgress > 0 ?
134
linearAnimation(1, 1.5, 1, 0, rightFoldingAreaProgress)
137
readonly property bool itemVisible: itemIndex == totalItems - 1 ? true : leftFoldingAreaProgress < 5 && rightFoldingAreaProgress < 5
138
readonly property real shadowOpacity: itemIndex == totalItems -1 ?
140
: leftFoldingAreaProgress > 3 ?
141
linearAnimation(3, 3.5, 1, 0, leftFoldingAreaProgress)
142
: rightFoldingAreaProgress > 3 ?
143
linearAnimation(3, 3.5, 1, 0, rightFoldingAreaProgress)
148
function linearAnimation(startProgress, endProgress, startValue, endValue, progress) {
149
// progress : progressDiff = value : valueDiff => value = progress * valueDiff / progressDiff
150
return (progress - startProgress) * (endValue - startValue) / (endProgress - startProgress) + startValue;
155
type: EasingCurve.OutSine
156
progress: limitedLeftProgress / 2 // OutSine starts with twice the speed. slow it down.
161
type: EasingCurve.OutSine
162
progress: limitedRightProgress / 2 // OutSine starts with twice the speed. slow it down.