on xenial help sign in
Implement rotation animations to/from all adjacent angles

And unlock N4 to rotate to any orientation TODO: Rotation animations between opposite angles (e.g.: 0 to 180)

commit9649c3a60c2c65d45bd7d576ade9cdd886b573c9 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateMon 9 Jun 2014, 17:08 (12 years ago) parentd03fbe8
3 files changed+204−10
qml/Components/WindowScreenshot.qml+5 qml/OrientedShell.qml+197−10 qml/Shell.qml+2
qml/Components/WindowScreenshot.qml+5
@@ -24,6 +24,11 @@ Item {
2424 image.source = "image://window/" + timeNow;
2525 }
2626
27+ // Unload the image to free up memory
28+ function discard() {
29+ image.source = "";
30+ }
31+
2732 Image {
2833 id: image
2934 }
qml/OrientedShell.qml+197−10
@@ -90,6 +90,8 @@ Item {
9090 PropertyChanges {
9191 target: shell
9292 transformRotationAngle: 0
93+ transformOriginX: orientedShell.width / 2
94+ transformOriginY: orientedShell.width / 2
9395 x: 0
9496 y: 0
9597 width: orientedShell.width
@@ -101,20 +103,23 @@ Item {
101103 PropertyChanges {
102104 target: shell
103105 transformRotationAngle: 90
106+ transformOriginX: orientedShell.width / 2
107+ transformOriginY: orientedShell.width / 2
104108 x: 0
105109 y: 0
106110 width: orientedShell.height
107111 height: orientedShell.width
108112 }
109113 },
110− // FIXME: 180 and 270 need to be updated
111114 State {
112115 name: "180"
113116 PropertyChanges {
114117 target: shell
115− rotation: 180
116− x: orientedShell.width
117− y: orientedShell.height
118+ transformRotationAngle: 180
119+ transformOriginX: orientedShell.width / 2
120+ transformOriginY: orientedShell.width / 2
121+ x: 0
122+ y: orientedShell.height - orientedShell.width
118123 width: orientedShell.width
119124 height: orientedShell.height
120125 }
@@ -123,9 +128,11 @@ Item {
123128 name: "270"
124129 PropertyChanges {
125130 target: shell
126− rotation: 270
131+ transformRotationAngle: -90
132+ transformOriginX: orientedShell.height / 2
133+ transformOriginY: orientedShell.height / 2
127134 x: 0
128− y: orientedShell.height
135+ y: 0
129136 width: orientedShell.height
130137 height: orientedShell.width
131138 }
@@ -150,6 +157,11 @@ Item {
150157 PropertyAction { target: shell; property: "width"; value: orientedShell.width }
151158 PropertyAction { target: shell; property: "height"; value: orientedShell.height }
152159 PropertyAction { target: shell; property: "transformRotationAngle"; value: 90 }
160+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.width / 2 }
161+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.width / 2 }
162+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.width / 2 }
163+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.width / 2 }
164+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
153165 ParallelAnimation {
154166 NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
155167 NumberAnimation { target: shell; property: "transformRotationAngle"; to: 0; duration: rotationDuration; easing.type: rotationEasing }
@@ -158,6 +170,7 @@ Item {
158170 NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: -90; duration: rotationDuration; easing.type: rotationEasing }
159171 }
160172 PropertyAction { target: windowScreenshot; property: "visible"; value: false }
173+ ScriptAction { script: { windowScreenshot.discard(); } }
161174 }
162175 },
163176 Transition {
@@ -170,6 +183,11 @@ Item {
170183 PropertyAction { target: shell; property: "width"; value: orientedShell.height }
171184 PropertyAction { target: shell; property: "height"; value: orientedShell.width }
172185 PropertyAction { target: shell; property: "transformRotationAngle"; value: 0 }
186+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.width / 2 }
187+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.width / 2 }
188+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.width / 2 }
189+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.width / 2 }
190+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
173191 ParallelAnimation {
174192 NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
175193 NumberAnimation { target: shell; property: "transformRotationAngle"; to: 90; duration: rotationDuration; easing.type: rotationEasing }
@@ -178,16 +196,181 @@ Item {
178196 NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: 90; duration: rotationDuration; easing.type: rotationEasing }
179197 }
180198 PropertyAction { target: windowScreenshot; property: "visible"; value: false }
199+ ScriptAction { script: { windowScreenshot.discard(); } }
200+ }
201+ },
202+ Transition {
203+ from: "0"
204+ to: "270"
205+ enabled: ready
206+ SequentialAnimation {
207+ ScriptAction { script: { windowScreenshot.take(); } }
208+ PropertyAction { target: windowScreenshot; property: "visible"; value: true }
209+ PropertyAction { target: shell; property: "width"; value: orientedShell.height }
210+ PropertyAction { target: shell; property: "height"; value: orientedShell.width }
211+ PropertyAction { target: shell; property: "transformRotationAngle"; value: 0 }
212+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.height / 2 }
213+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.height / 2 }
214+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.height / 2 }
215+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.height / 2 }
216+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
217+ ParallelAnimation {
218+ NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
219+ NumberAnimation { target: shell; property: "transformRotationAngle"; to: -90; duration: rotationDuration; easing.type: rotationEasing }
220+
221+ NumberAnimation { target: windowScreenshot; property: "opacity"; from: 1; to: 0; duration: rotationDuration; easing.type: rotationEasing }
222+ NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: -90; duration: rotationDuration; easing.type: rotationEasing }
223+ }
224+ PropertyAction { target: windowScreenshot; property: "visible"; value: false }
225+ ScriptAction { script: { windowScreenshot.discard(); } }
226+ }
227+ },
228+ Transition {
229+ from: "270"
230+ to: "0"
231+ enabled: ready
232+ SequentialAnimation {
233+ ScriptAction { script: { windowScreenshot.take(); } }
234+ PropertyAction { target: windowScreenshot; property: "visible"; value: true }
235+ PropertyAction { target: shell; property: "width"; value: orientedShell.width }
236+ PropertyAction { target: shell; property: "height"; value: orientedShell.height }
237+ PropertyAction { target: shell; property: "transformRotationAngle"; value: -90 }
238+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.height / 2 }
239+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.height / 2 }
240+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.height / 2 }
241+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.height / 2 }
242+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
243+ ParallelAnimation {
244+ NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
245+ NumberAnimation { target: shell; property: "transformRotationAngle"; to: 0; duration: rotationDuration; easing.type: rotationEasing }
246+
247+ NumberAnimation { target: windowScreenshot; property: "opacity"; from: 1; to: 0; duration: rotationDuration; easing.type: rotationEasing }
248+ NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: 90; duration: rotationDuration; easing.type: rotationEasing }
249+ }
250+ PropertyAction { target: windowScreenshot; property: "visible"; value: false }
251+ ScriptAction { script: { windowScreenshot.discard(); } }
252+ }
253+ },
254+ Transition {
255+ from: "90"
256+ to: "180"
257+ enabled: true
258+ SequentialAnimation {
259+ ScriptAction { script: { windowScreenshot.take(); } }
260+ PropertyAction { target: windowScreenshot; property: "visible"; value: true }
261+ PropertyAction { target: shell; property: "width"; value: orientedShell.width }
262+ PropertyAction { target: shell; property: "height"; value: orientedShell.height }
263+ PropertyAction { target: shell; property: "transformRotationAngle"; value: 90 }
264+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.width / 2 }
265+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.width / 2 }
266+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.width / 2 }
267+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.width / 2 }
268+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
269+ ParallelAnimation {
270+ NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
271+ NumberAnimation { target: shell; property: "transformRotationAngle"; to: 180; duration: rotationDuration; easing.type: rotationEasing }
272+ NumberAnimation { target: shell; property: "y"; from: 0; to: orientedShell.height - orientedShell.width; duration: rotationDuration; easing.type: rotationEasing }
273+
274+ NumberAnimation { target: windowScreenshot; property: "opacity"; from: 1; to: 0; duration: rotationDuration; easing.type: rotationEasing }
275+ NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: 90; duration: rotationDuration; easing.type: rotationEasing }
276+ NumberAnimation { target: windowScreenshot; property: "y"; from: 0; to: orientedShell.height - orientedShell.width; duration: rotationDuration; easing.type: rotationEasing }
277+ }
278+ PropertyAction { target: windowScreenshot; property: "visible"; value: false }
279+ ScriptAction { script: { windowScreenshot.discard(); } }
280+ }
281+ },
282+ Transition {
283+ from: "180"
284+ to: "90"
285+ enabled: true
286+ SequentialAnimation {
287+ ScriptAction { script: { windowScreenshot.take(); } }
288+ PropertyAction { target: windowScreenshot; property: "visible"; value: true }
289+ PropertyAction { target: shell; property: "width"; value: orientedShell.height }
290+ PropertyAction { target: shell; property: "height"; value: orientedShell.width }
291+ PropertyAction { target: shell; property: "transformRotationAngle"; value: 180 }
292+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.width / 2 }
293+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.width / 2 }
294+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.width / 2 }
295+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.height - (orientedShell.width / 2) }
296+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
297+ ParallelAnimation {
298+ NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
299+ NumberAnimation { target: shell; property: "transformRotationAngle"; to: 90; duration: rotationDuration; easing.type: rotationEasing }
300+ NumberAnimation { target: shell; property: "y"; from: orientedShell.height - orientedShell.width; to: 0; duration: rotationDuration; easing.type: rotationEasing }
301+
302+ NumberAnimation { target: windowScreenshot; property: "opacity"; from: 1; to: 0; duration: rotationDuration; easing.type: rotationEasing }
303+ NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: -90; duration: rotationDuration; easing.type: rotationEasing }
304+ NumberAnimation { target: windowScreenshot; property: "y"; from: 0; to: -orientedShell.height + orientedShell.width; duration: rotationDuration; easing.type: rotationEasing }
305+ }
306+ PropertyAction { target: windowScreenshot; property: "visible"; value: false }
307+ ScriptAction { script: { windowScreenshot.discard(); } }
308+ }
309+ },
310+ Transition {
311+ from: "180"
312+ to: "270"
313+ enabled: true
314+ SequentialAnimation {
315+ ScriptAction { script: { windowScreenshot.take(); } }
316+ PropertyAction { target: windowScreenshot; property: "visible"; value: true }
317+ PropertyAction { target: shell; property: "width"; value: orientedShell.height }
318+ PropertyAction { target: shell; property: "height"; value: orientedShell.width }
319+ PropertyAction { target: shell; property: "y"; value: orientedShell.height - orientedShell.width }
320+ PropertyAction { target: shell; property: "transformRotationAngle"; value: 180 }
321+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.width / 2 }
322+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.width / 2 }
323+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.width / 2 }
324+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.height - (orientedShell.width / 2) }
325+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
326+ ParallelAnimation {
327+ NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
328+ NumberAnimation { target: shell; property: "transformRotationAngle"; to: 270; duration: rotationDuration; easing.type: rotationEasing }
329+
330+ NumberAnimation { target: windowScreenshot; property: "opacity"; from: 1; to: 0; duration: rotationDuration; easing.type: rotationEasing }
331+ NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: 90; duration: rotationDuration; easing.type: rotationEasing }
332+ }
333+ PropertyAction { target: windowScreenshot; property: "visible"; value: false }
334+ ScriptAction { script: { windowScreenshot.discard(); } }
335+ }
336+ },
337+ Transition {
338+ from: "270"
339+ to: "180"
340+ enabled: ready
341+ SequentialAnimation {
342+ ScriptAction { script: { windowScreenshot.take(); } }
343+ PropertyAction { target: windowScreenshot; property: "visible"; value: true }
344+ PropertyAction { target: shell; property: "width"; value: orientedShell.width }
345+ PropertyAction { target: shell; property: "height"; value: orientedShell.height }
346+ PropertyAction { target: shell; property: "y"; value: orientedShell.height - orientedShell.width }
347+ PropertyAction { target: shell; property: "transformRotationAngle"; value: 270 }
348+ PropertyAction { target: shell; property: "transformOriginX"; value: orientedShell.width / 2 }
349+ PropertyAction { target: shell; property: "transformOriginY"; value: orientedShell.width / 2 }
350+ PropertyAction { target: windowScreenshot; property: "transformOriginX"; value: orientedShell.width / 2 }
351+ PropertyAction { target: windowScreenshot; property: "transformOriginY"; value: orientedShell.height - (orientedShell.width / 2) }
352+ PropertyAction { target: windowScreenshot; property: "y"; value: 0 }
353+ ParallelAnimation {
354+ NumberAnimation { target: shell; property: "opacity"; from: 0; to: 1; duration: rotationDuration; easing.type: rotationEasing }
355+ NumberAnimation { target: shell; property: "transformRotationAngle"; to: 180; duration: rotationDuration; easing.type: rotationEasing }
356+
357+ NumberAnimation { target: windowScreenshot; property: "opacity"; from: 1; to: 0; duration: rotationDuration; easing.type: rotationEasing }
358+ NumberAnimation { target: windowScreenshot; property: "transformRotationAngle"; from: 0; to: -90; duration: rotationDuration; easing.type: rotationEasing }
359+ }
360+ PropertyAction { target: windowScreenshot; property: "visible"; value: false }
361+ ScriptAction { script: { windowScreenshot.discard(); } }
181362 }
182363 }
183364 ]
184365
185366 Shell {
186367 id: shell
187− property real transformRotationAngle: 0
368+ property real transformRotationAngle
369+ property real transformOriginX
370+ property real transformOriginY
188371
189372 transform: Rotation {
190− origin.x: orientedShell.width / 2; origin.y: orientedShell.width / 2; axis { x: 0; y: 0; z: 1 }
373+ origin.x: shell.transformOriginX; origin.y: shell.transformOriginY; axis { x: 0; y: 0; z: 1 }
191374 angle: shell.transformRotationAngle
192375 }
193376 }
@@ -195,11 +378,15 @@ Item {
195378 WindowScreenshot {
196379 id: windowScreenshot
197380 visible: false
381+ width: orientedShell.width
382+ height: orientedShell.height
198383
199− property real transformRotationAngle: 0
384+ property real transformRotationAngle
385+ property real transformOriginX
386+ property real transformOriginY
200387
201388 transform: Rotation {
202− origin.x: orientedShell.width / 2; origin.y: orientedShell.width / 2; axis { x: 0; y: 0; z: 1 }
389+ origin.x: windowScreenshot.transformOriginX; origin.y: windowScreenshot.transformOriginY; axis { x: 0; y: 0; z: 1 }
203390 angle: windowScreenshot.transformRotationAngle
204391 }
205392 }
qml/Shell.qml+2
@@ -45,6 +45,8 @@ FocusScope {
4545 deviceOrientations = Qt.LandscapeOrientation;
4646 } else if (applicationArguments.device() === "mako") {
4747 deviceOrientations = Qt.PortraitOrientation
48+ | Qt.InvertedPortraitOrientation
49+ | Qt.LandscapeOrientation
4850 | Qt.InvertedLandscapeOrientation;
4951 }
5052