Lomiri
OrientationChangeAnimation.qml
1 /*
2  * Copyright 2015, 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 Lesser 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 Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 import QtQuick 2.12
18 
19 QtObject {
20  id: root
21 
22  // to be set from outside
23  property Item spreadDelegate
24  property Item background
25  property Item window
26  property Item screenshot
27 
28  function start() {
29  if (window.orientationAngle === 0) {
30  if (spreadDelegate.shellOrientationAngle === 90) {
31  chosenAnimation = simple90Animation;
32  } else if (spreadDelegate.shellOrientationAngle === 180) {
33  chosenAnimation = halfLoopAnimation;
34  } else if (spreadDelegate.shellOrientationAngle === 270) {
35  chosenAnimation = moving90Animation;
36  } else {
37  chosenAnimation = null;
38  }
39  } else if (window.orientationAngle === 90) {
40  if (spreadDelegate.shellOrientationAngle === 0) {
41  chosenAnimation = simple90Animation;
42  } else if (spreadDelegate.shellOrientationAngle === 180) {
43  chosenAnimation = moving90Animation;
44  } else if (spreadDelegate.shellOrientationAngle === 270) {
45  chosenAnimation = halfLoopAnimation;
46  } else {
47  chosenAnimation = null;
48  }
49  } else if (window.orientationAngle === 180) {
50  if (spreadDelegate.shellOrientationAngle === 0) {
51  chosenAnimation = halfLoopAnimation;
52  } else if (spreadDelegate.shellOrientationAngle === 90) {
53  chosenAnimation = moving90Animation;
54  } else if (spreadDelegate.shellOrientationAngle === 270) {
55  chosenAnimation = simple90Animation;
56  } else {
57  chosenAnimation = null;
58  }
59  } else if (window.orientationAngle === 270) {
60  if (spreadDelegate.shellOrientationAngle === 0) {
61  chosenAnimation = moving90Animation;
62  } else if (spreadDelegate.shellOrientationAngle === 90) {
63  chosenAnimation = halfLoopAnimation;
64  } else if (spreadDelegate.shellOrientationAngle === 180) {
65  chosenAnimation = simple90Animation;
66  } else {
67  chosenAnimation = null;
68  }
69  }
70 
71  if (chosenAnimation) {
72  chosenAnimation.setup();
73  }
74  }
75 
76  property Connections chosenAnimationConns: Connections {
77  target: root.chosenAnimation
78  onReadyChanged: {
79  if (root.chosenAnimation.ready) {
80  root.chosenAnimation.start();
81  }
82  }
83  }
84 
85  // to be read from outside
86  property bool running: chosenAnimation !== null
87 
88  property int duration: 450
89  property int easingType: Easing.InOutCubic
90 
91  property int shortestDimension: spreadDelegate.width < spreadDelegate.height
92  ? spreadDelegate.width : spreadDelegate.height
93  property int longestDimension: spreadDelegate.width > spreadDelegate.height
94  ? spreadDelegate.width : spreadDelegate.height
95  property string longestAxis: spreadDelegate.width > spreadDelegate.height ? "x" : "y"
96 
97  property QtObject chosenAnimation: null
98 
99  function setup90Animation() {
100  background.visible = true;
101 
102  screenshot.width = window.width;
103  screenshot.height = window.height;
104  screenshot.window.anchors.topMargin = window.window.anchors.topMargin;
105  screenshot.transformOriginX = root.shortestDimension / 2;
106  screenshot.transformOriginY = root.shortestDimension / 2;
107  screenshot.visible = true;
108 
109  window.rotation = 0;
110  window.width = spreadDelegate.width;
111  window.height = spreadDelegate.height;
112  window.transformOriginX = root.shortestDimension / 2;
113  window.transformOriginY = root.shortestDimension / 2;
114  }
115 
116  function tearDown90Animation() {
117  window.orientationAngle = spreadDelegate.shellOrientationAngle;
118  screenshot.discard();
119  screenshot.visible = false;
120  background.visible = false;
121  chosenAnimation.ranSetup = false;
122  chosenAnimation = null;
123  }
124 
125  property QtObject simple90Animation: SequentialAnimation {
126  id: simple90Animation
127 
128  function setup() { screenshot.take(); ranSetup = true; }
129  property bool ranSetup: false
130  readonly property bool ready: ranSetup && root.screenshot && root.screenshot.ready
131 
132  ScriptAction { script: setup90Animation() }
133  ParallelAnimation {
134  RotationAnimation {
135  target: root.window
136  duration: root.duration
137  easing.type: root.easingType
138  from: window.orientationAngle - spreadDelegate.shellOrientationAngle
139  to: 0
140  property: "transformRotationAngle"
141  }
142  RotationAnimation {
143  target: root.screenshot
144  duration: root.duration
145  easing.type: root.easingType
146  from: window.orientationAngle - spreadDelegate.shellOrientationAngle
147  to: 0
148  property: "transformRotationAngle"
149  }
150  NumberAnimation {
151  target: root.screenshot
152  duration: root.duration
153  easing.type: root.easingType
154  property: "opacity"
155  from: 1.0
156  to: 0.0
157  }
158  NumberAnimation {
159  target: root.window
160  duration: root.duration
161  easing.type: root.easingType
162  property: "opacity"
163  from: 0.0
164  to: 1.0
165  }
166  }
167  ScriptAction { script: tearDown90Animation() }
168  }
169 
170  property QtObject moving90Animation: SequentialAnimation {
171  id: moving90Animation
172 
173  function setup() { screenshot.take(); ranSetup = true; }
174  property bool ranSetup: false
175  readonly property bool ready: ranSetup && root.screenshot && root.screenshot.ready
176 
177  ScriptAction { script: setup90Animation() }
178  ParallelAnimation {
179  RotationAnimation {
180  target: root.window
181  duration: root.duration
182  easing.type: root.easingType
183  direction: RotationAnimation.Shortest
184  from: window.orientationAngle - spreadDelegate.shellOrientationAngle
185  to: 0
186  property: "transformRotationAngle"
187  }
188  RotationAnimation {
189  target: root.screenshot
190  duration: root.duration
191  easing.type: root.easingType
192  direction: RotationAnimation.Shortest
193  from: window.orientationAngle - spreadDelegate.shellOrientationAngle
194  to: 0
195  property: "transformRotationAngle"
196  }
197  NumberAnimation {
198  target: root.screenshot
199  duration: root.duration
200  easing.type: root.easingType
201  property: "opacity"
202  from: 1.0
203  to: 0.0
204  }
205  NumberAnimation {
206  target: root.window
207  duration: root.duration
208  easing.type: root.easingType
209  property: "opacity"
210  from: 0.0
211  to: 1.0
212  }
213  NumberAnimation {
214  target: root.window
215  duration: root.duration
216  easing.type: root.easingType
217  property: root.longestAxis
218  from: root.longestDimension - root.shortestDimension
219  to: 0
220  }
221  NumberAnimation {
222  target: root.screenshot
223  duration: root.duration
224  easing.type: root.easingType
225  property: root.longestAxis
226  from: root.longestDimension - root.shortestDimension
227  to: 0
228  }
229  }
230  ScriptAction { script: tearDown90Animation() }
231  }
232 
233  property QtObject halfLoopAnimation: SequentialAnimation {
234  id: halfLoopAnimation
235 
236  function setup() { ready = true; }
237  property bool ready: false
238 
239  ScriptAction { script: {
240  background.visible = true;
241 
242  window.rotation = 0;
243  window.width = spreadDelegate.width;
244  window.height = spreadDelegate.height;
245  window.transformOriginX = window.width / 2
246  window.transformOriginY = window.height / 2
247  } }
248  ParallelAnimation {
249  RotationAnimation {
250  target: root.window
251  duration: root.duration
252  easing.type: root.easingType
253  from: window.orientationAngle - spreadDelegate.shellOrientationAngle
254  to: 0
255  property: "transformRotationAngle"
256  }
257  }
258  ScriptAction { script: {
259  window.orientationAngle = spreadDelegate.shellOrientationAngle;
260  background.visible = false;
261  chosenAnimation = null;
262  halfLoopAnimation.ready = false;
263  } }
264  }
265 }