on xenial help sign in
reworked animation
240add3Michael Zanetti
qml/Stages/PhoneStage.qml+156−87
@@ -191,7 +191,7 @@ Item {
191 priv.requestNewScreenshot();
191 priv.requestNewScreenshot();
192 }
192 }
193 if (dragging && !priv.waitingForScreenshot) {
193 if (dragging && !priv.waitingForScreenshot) {
194− coverFlip.progress = -(touchX - root.dragAreaWidth) / root.width
194+ coverFlickable.contentX = -touchX
195 }
195 }
196 }
196 }
197
197
@@ -219,45 +219,23 @@ Item {
219 anchors.fill: root
219 anchors.fill: root
220 blockInput: coverFlip.visible
220 blockInput: coverFlip.visible
221 }
221 }
222− MouseArea {
222+ Flickable {
223+ id: coverFlickable
223 anchors.fill: root
224 anchors.fill: root
225+ contentHeight: height
226+ contentWidth: width * ApplicationManager.count
227+ flickableDirection: Qt.Horizontal
224 enabled: coverFlip.visible
228 enabled: coverFlip.visible
225− property int oldMouseX
226− property int startX
227
229
228− property bool isDrag: false
230+ onContentXChanged: {
229−
230− onPressed: {
231− isDrag = false
232− oldMouseX = mouseX
233− startX = mouseX
234− }
235−
236− onMouseXChanged: {
237− var diff = (oldMouseX - mouseX) * .001;
238− coverFlip.progress = Math.max(.8, coverFlip.progress + diff);
239− oldMouseX = mouseX
240− print("mousex changed", mouseX - startX)
231+// print("contentX changed", contentX)
241− if (Math.abs(mouseX - startX) > units.gu(.5)) {
232+ var progress = contentX / width
242− isDrag = true;
233+ if (progress > .5) {
243− }
234+ progress += progress - .5
244− }
245− onClicked: {
246− // From Qt docs:
247− // "A click is defined as a press followed by a release, both inside the
248− // MouseArea (pressing, moving outside the MouseArea, and then moving back
249− // inside and releasing is also considered a click)."
250− // This means, that pressing, moving the coverFlip around and then releasing
251− // will still be threated as a click. Let's add our own logic to not activate
252− // a tile if the user just wants to drag stuff around.
253− if (isDrag) {
254− return;
255 }
235 }
256
236
257− var index = Math.floor(mouseX / coverFlip.tileWidth)
237+ coverFlip.progress = progress;
258− index = Math.min(tileRepeater.count - 1, index)
238+// print("progress is", coverFlip.progress)
259− print("clicked item", index)
260− coverFlip.selectItem(index);
261 }
239 }
262 }
240 }
263
241
@@ -268,22 +246,37 @@ Item {
268 visible: progress > 0
246 visible: progress > 0
269
247
270 property real progress: 0
248 property real progress: 0
271− property int maxAngle: 45
249+ property real startAngle: 45
250+ property int endAngle: 10
251+
252+ property real maxScale: 1.4
272 property real minScale: .6
253 property real minScale: .6
254+
255+ // Markers: relative screen position from left to right
256+ // marks the line where first application is finished moving in from the right
257+ property real progressMarker1: 0.5
258+
273 property bool animatingBack: false
259 property bool animatingBack: false
274
260
275− property real tileWidth: Math.max(units.gu(2), root.width - (coverFlip.progress * root.width))
261+ property real tileWidth: root.width
276
262
263+ property real oldProgress: 0
277−// onProgressChanged: print("CoverFlip progress changed", progress)
264+ onProgressChanged: {
278− onXChanged: print("coverflip x changed", x)
265+ if (oldProgress <= coverFlip.progressMarker1 && progress > coverFlip.progressMarker1) {
266+ ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
267+ } else if (oldProgress >= 0.5 && progress < 0.5) {
268+ ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
269+ }
270+ oldProgress = progress;
271+ }
279
272
280 function snap() {
273 function snap() {
281 if (coverFlip.progress < 0.25) {
274 if (coverFlip.progress < 0.25) {
282− snapAnimation.targetProgress = 0
275+ snapAnimation.targetContentX = 0
283 } else if (coverFlip.progress < 0.6) {
276 } else if (coverFlip.progress < 0.6) {
284− snapAnimation.targetProgress = 0.5
277+ snapAnimation.targetContentX = root.width * coverFlip.progressMarker1
285 } else {
278 } else {
286− snapAnimation.targetProgress = .8;
279+ snapAnimation.targetContentX = root.width * .9;
287 }
280 }
288 snapAnimation.start();
281 snapAnimation.start();
289 }
282 }
@@ -294,18 +287,17 @@ Item {
294
287
295 SequentialAnimation {
288 SequentialAnimation {
296 id: snapAnimation
289 id: snapAnimation
297− property var targetProgress
290+ property var targetContentX
298
291
299 UbuntuNumberAnimation {
292 UbuntuNumberAnimation {
300− target: coverFlip
293+ target: coverFlickable
301− properties: "progress"
294+ properties: "contentX"
302− to: snapAnimation.targetProgress
295+ to: snapAnimation.targetContentX
303 }
296 }
304 ScriptAction {
297 ScriptAction {
305 script: {
298 script: {
306− if (snapAnimation.targetProgress == 0.5) {
299+ if (snapAnimation.targetContentX == root.width * coverFlip.progressMarker1) {
307− ApplicationManager.focusApplication(ApplicationManager.get(1).appId);
300+ coverFlickable.contentX = 0;
308− coverFlip.progress = 0;
309 }
301 }
310 }
302 }
311 }
303 }
@@ -332,80 +324,157 @@ Item {
332
324
333 property real progress: coverFlip.progress
325 property real progress: coverFlip.progress
334
326
327+ property int xTranslation: {
328+ var xTranslate = 0;
329+ var minXTranslate = -index * root.width + index * units.dp(3);
330+ switch (index) {
331+ case 0:
332+ if (appImage.progress < coverFlip.progressMarker1) {
333+ var progress = appImage.progress
334+ var progressDiff = coverFlip.progressMarker1
335+ var translateDiff = -root.width * 0.25
336+ // progress : progressDiff = translate : translateDiff
337+ xTranslate = progress * translateDiff / progressDiff
338+ }
339+ break;
340+ case 1:
341+ if (appImage.progress < coverFlip.progressMarker1) {
342+ var progress = appImage.progress;
343+ var progressDiff = coverFlip.progressMarker1;
344+ var translateDiff = -root.width;
345+ // progress : progressDiff = translate : translateDiff
346+ xTranslate = progress * translateDiff / progressDiff;
347+ break;
348+ }
349+ // Intentionally no break here...
350+ default:
351+ if (appImage.progress > coverFlip.progressMarker1) {
352+ // Used to move all tiles directly to the right of the screen as starting position
353+ var mainTranslate = -root.width * (index - 1)
354+ // Used to add the offset to each tile so they are not on one stack
355+ var indexTranslate = (index - 1) * root.width / 4
356+
357+ var progress = appImage.progress - coverFlip.progressMarker1
358+ var progressDiff = 1 - coverFlip.progressMarker1
359+ var translateDiff = -root.width * coverFlip.progressMarker1// -(coverFlip.progressMarker1 + index * root.width * 0.25 + root.width * 0.25)
360+
361+ // progress : progressDiff = translate : translateDiff
362+ xTranslate = progress * translateDiff / progressDiff;
363+
364+ // Add starting point and index translate
365+ xTranslate += mainTranslate + indexTranslate;
366+
367+ // make sure we stop at the left screen edge
368+ xTranslate = Math.max(xTranslate, minXTranslate)
369+ break;
370+ }
371+ }
372+ return xTranslate;
373+ }
374+
335 transform: [
375 transform: [
336 Rotation {
376 Rotation {
337− origin { x: units.gu(5); y: height / 2 }
377+ origin { x: 0; y: coverFlip.height / 2 }
338 axis { x: 0; y: 1; z: 0 }
378 axis { x: 0; y: 1; z: 0 }
339 angle: {
379 angle: {
340 var newAngle = 0;
380 var newAngle = 0;
341 if (coverFlip.animatingBack) {
381 if (coverFlip.animatingBack) {
342− newAngle = Math.min(appImage.progress, .75) * coverFlip.maxAngle;
382+ newAngle = Math.min(appImage.progress, .75) * coverFlip.endAngle;
343 } else {
383 } else {
344 switch (index) {
384 switch (index) {
345 case 0:
385 case 0:
346− if (appImage.progress < .5) {
386+ if (appImage.progress <= coverFlip.progressMarker1) {
387+ var progress = appImage.progress;
388+ var angleDiff = coverFlip.endAngle;
389+ var progressDiff = coverFlip.progressMarker1;
390+ // progress : progressDiff = angle : angleDiff
347− newAngle = appImage.progress * coverFlip.maxAngle;
391+ newAngle = progress * angleDiff / progressDiff;
348 } else {
392 } else {
349− newAngle = (appImage.progress - .5) * coverFlip.maxAngle * 2;
393+ var progress = appImage.progress - coverFlip.progressMarker1;
394+ var angleDiff = coverFlip.endAngle;
395+ var progressDiff = 1 - coverFlip.progressMarker1;
396+ // progress : progressDiff = angle : angleDiff
397+ newAngle = progress * angleDiff / progressDiff;
398+ newAngle = Math.min(coverFlip.endAngle, newAngle);
350 }
399 }
351 break;
400 break;
352 case 1:
401 case 1:
353− if (appImage.progress < .5) {
402+ if (appImage.progress < coverFlip.progressMarker1) {
354− newAngle = coverFlip.maxAngle - (appImage.progress * coverFlip.maxAngle * 2);
403+ var progress = coverFlip.progress;
355− } else {
404+ var angleDiff = coverFlip.startAngle;
356− newAngle = (appImage.progress - .5) * coverFlip.maxAngle * 2;
405+ var progressDiff = coverFlip.progressMarker1;
406+ // progress : progressDiff = angle : angleDiff
407+ var angle = progress * angleDiff / progressDiff;
408+ newAngle = coverFlip.startAngle - angle;
409+ break;
357 }
410 }
358− break;
411+ // Intentionally no break here...
359 default:
412 default:
360− newAngle = Math.min(appImage.progress, .75) * coverFlip.maxAngle;
413+ var progress = appImage.progress;
414+ var angleDiff = coverFlip.startAngle - coverFlip.endAngle;
415+ var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
416+ // progress : progressDiff = angle : angleDiff
417+ newAngle = progress * angleDiff / progressDiff;
418+ newAngle = Math.max(coverFlip.endAngle, coverFlip.startAngle - newAngle)
361 }
419 }
362 }
420 }
363− return Math.min(newAngle, coverFlip.maxAngle);
421+ return newAngle;
364 }
422 }
365 },
423 },
366 Translate {
424 Translate {
367− x: {
425+ x: appImage.xTranslation
368− if (coverFlip.animatingBack) {
369− return 0;
370− }
371−
372− switch (index) {
373− case 1:
374− if (appImage.progress < .5) {
375− return -root.width * appImage.progress;
376− } else if (appImage.progress < .75) {
377− // relation equation: x : width/2 = progress-.5 : 0.25
378− return (-root.width * .5) + (root.width/2) * (appImage.progress - .5) / 0.25
379− }
380− }
381− return 0;
382− }
383 },
426 },
384 Scale {
427 Scale {
385− origin { x: 0; y: root.height / 2 }
428+ origin { x: appImage.xTranslation; y: root.height / 2 - (root.height - appImage.height)}
386 xScale: {
429 xScale: {
387 var scale = 1;
430 var scale = 1;
388− // progress : 1 = x : root.width
431+
389− var progress = root.width / (root.width - x)
432+ switch (index) {
433+ case 0:
390− if (appImage.progress > .5) {
434+ if (appImage.progress > coverFlip.progressMarker1) {
391− // relation equation: scale : (1-minScale) = progress-.5 : 0.5
435+ var scaleDiff = coverFlip.maxScale - 1;
392− scale = 1 - (1 - coverFlip.minScale) * (appImage.progress - 0.5) / 0.5
436+ var progressDiff = 1.5 - coverFlip.progressMarker1;
437+ // progress : progressDiff = scale : scaleDiff
438+ scale = 1 - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff;
439+ }
440+ break;
441+ case 1:
442+ if (appImage.progress < coverFlip.progressMarker1) {
443+ var scaleDiff = coverFlip.maxScale - 1
444+ var progressDiff = coverFlip.progressMarker1
445+ // progress : progressDiff = scale : scaleDiff
446+ scale = coverFlip.maxScale - (appImage.progress * scaleDiff / progressDiff);
447+ break;
448+ }
449+ // Intentionally no break
450+ default:
451+ var scaleDiff = coverFlip.maxScale - coverFlip.minScale
452+ var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
453+ // progress : progressDiff = scale : scaleDiff
454+ scale = coverFlip.maxScale - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff
455+ break;
393 }
456 }
394− scale = Math.max(coverFlip.minScale, scale);
457+ return Math.min(coverFlip.maxScale, Math.max(coverFlip.minScale, scale));
395− return scale;
396 }
458 }
397 yScale: xScale
459 yScale: xScale
398 }
460 }
399 ]
461 ]
400
462
463+ MouseArea {
464+ anchors.fill: parent
465+ onClicked: {
466+ print("clicked on index", index)
467+ select()
468+ }
469+ }
401 }
470 }
402
471
403 SequentialAnimation {
472 SequentialAnimation {
404 id: switchToAppAnimation
473 id: switchToAppAnimation
405 PropertyAction { target: coverFlip; property: "animatingBack"; value: true }
474 PropertyAction { target: coverFlip; property: "animatingBack"; value: true }
406 ParallelAnimation {
475 ParallelAnimation {
407− UbuntuNumberAnimation { target: coverFlip; property: "progress"; to: 0 }
476+ UbuntuNumberAnimation { target: coverFlickable; property: "contentX"; to: 0; duration: 5000 }
408− UbuntuNumberAnimation { target: coverFlip; property: "x"; to: -root.width * index }
477+ UbuntuNumberAnimation { target: coverFlip; property: "x"; to: -root.width * index; duration: 5000 }
409 }
478 }
410 ScriptAction {
479 ScriptAction {
411 script: {
480 script: {