Lomiri
StagedRightEdgeMaths.qml
1 /*
2  * Copyright (C) 2016 Canonical Ltd.
3  *
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.
7  *
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.
12  *
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/>.
15  */
16 
17 import QtQuick 2.12
18 import Lomiri.Components 1.3
19 import QtMir.Application 0.1
20 import "MathUtils.js" as MathUtils
21 
22 QtObject {
23  id: root
24 
25  // Input
26  property int itemIndex: 0
27  property real progress: 0
28  property int sceneWidth: 0
29  property int sideStageWidth: 0
30  property int sceneHeight: 0
31  property int targetX: 0
32  property int startY: 0
33  property int targetY: 0
34  property real startAngle: 30
35  property real targetAngle: 0
36  property int targetHeight: 0
37  property real startScale: 1.3
38  property real targetScale: 0
39  property real breakPoint: units.gu(15) / sceneWidth
40 
41  property bool isMainStageApp: false
42  property bool isSideStageApp: false
43  property bool sideStageOpen: false
44  property int nextInStack: 0
45  property int shuffledZ: 0
46 
47 
48  // Config
49  property int tileDistance: units.gu(10)
50 
51  // Output
52 
53  readonly property real scaleToPreviewProgress: {
54  return progress < breakPoint ? 0 : MathUtils.clamp(MathUtils.linearAnimation(breakPoint, 1, 0, 1, progress), 0, 1)
55  }
56  readonly property int animatedWidth: {
57  return progress < breakPoint ? root.sceneHeight : MathUtils.linearAnimation(breakPoint, 1, root.sceneWidth, targetHeight, progress)
58  }
59 
60  readonly property int animatedHeight: {
61  return progress < breakPoint ? root.sceneHeight : MathUtils.linearAnimation(breakPoint, 1, root.sceneHeight, targetHeight, progress)
62  }
63 
64 
65  readonly property int animatedX: {
66  var nextStage = appRepeater.itemAt(nextInStack) ? appRepeater.itemAt(nextInStack).stage : ApplicationInfoInterface.MainStage;
67 
68  var startX = 0;
69  if (isMainStageApp) {
70  if (progress < breakPoint) {
71  if (nextStage == ApplicationInfoInterface.MainStage) {
72  return MathUtils.linearAnimation(0, breakPoint, 0, -units.gu(4), progress);
73  } else {
74  return 0;
75  }
76  } else {
77  if (nextStage == ApplicationInfoInterface.MainStage) {
78  return MathUtils.linearAnimation(breakPoint, 1, -units.gu(4), targetX, progress);
79  } else {
80  return MathUtils.linearAnimation(breakPoint, 1, 0, targetX, progress);
81  }
82  }
83  } else if (isSideStageApp) {
84  startX = sceneWidth - sideStageWidth;
85  } else if (itemIndex == nextInStack && itemIndex <= 2 && priv.sideStageDelegate && nextStage == ApplicationInfoInterface.MainStage) {
86  startX = sceneWidth - sideStageWidth;
87  } else {
88  var stageCount = (priv.mainStageDelegate ? 1 : 0) + (priv.sideStageDelegate ? 1 : 0)
89  startX = sceneWidth + Math.max(0, itemIndex - stageCount - 1) * tileDistance;
90  }
91 
92  if (itemIndex == nextInStack) {
93  if (progress < breakPoint) {
94  return MathUtils.linearAnimation(0, breakPoint, startX, startX * (1 - breakPoint), progress)
95  }
96  return MathUtils.linearAnimation(breakPoint, 1, startX * (1 - breakPoint), targetX, progress)
97  }
98 
99  if (progress < breakPoint) {
100  return startX;
101  }
102 
103  return MathUtils.linearAnimation(breakPoint, 1, startX, targetX, progress)
104 
105  }
106 
107  readonly property int animatedY: progress < breakPoint ? startY : MathUtils.linearAnimation(breakPoint, 1, startY, targetY, progress)
108 
109  readonly property int animatedZ: {
110  if (progress < breakPoint + (1 - breakPoint) / 2) {
111  return shuffledZ
112  }
113  return itemIndex;
114  }
115 
116  readonly property real animatedAngle: {
117  var nextStage = appRepeater.itemAt(nextInStack) ? appRepeater.itemAt(nextInStack).stage : ApplicationInfoInterface.MainStage;
118 
119  var startAngle = 0;
120  if (isMainStageApp) {
121  startAngle = 0;
122  } else if (isSideStageApp) {
123  startAngle = 0;
124  } else {
125  if (stage == ApplicationInfoInterface.SideStage && itemIndex == nextInStack && !sideStageOpen) {
126  startAngle = 0;
127  } else {
128  startAngle = root.startAngle;
129  }
130  }
131 
132  if ((itemIndex == nextInStack)
133  || (isMainStageApp && nextStage === ApplicationInfoInterface.MainStage)
134  || (isSideStageApp && nextStage === ApplicationInfoInterface.SideStage)) {
135  return MathUtils.linearAnimation(0, 1, startAngle, targetAngle, progress);
136  }
137 
138  if (progress < breakPoint) {
139  return 0;
140  }
141  return MathUtils.linearAnimation(breakPoint, 1, startAngle, targetAngle, progress);
142  }
143 
144  readonly property real animatedScale: {
145  var pullingInSideStage = itemIndex == nextInStack && stage == ApplicationInfoInterface.SideStage && !sideStageOpen;
146 
147  var startScale = 1;
148  if (isMainStageApp) {
149  startScale = 1;
150  } else if (isSideStageApp) {
151  startScale = 1;
152  } else {
153  if (pullingInSideStage) {
154  startScale = 1
155  } else {
156  startScale = root.startScale;
157  }
158  }
159 
160  if (progress < breakPoint) {
161  if (itemIndex == nextInStack && (sideStageOpen || stage == ApplicationInfoInterface.MainStage)) {
162  return MathUtils.linearAnimation(0, 1, startScale, targetScale, progress);
163  }
164  return startScale;
165  }
166  if (itemIndex == nextInStack) {
167  return MathUtils.linearAnimation(0, 1, startScale, targetScale, progress)
168  }
169 
170  return MathUtils.linearAnimation(breakPoint, 1, startScale, targetScale, progress)
171  }
172 
173  readonly property bool itemVisible: true //animatedX < sceneWidth
174 }