@@ -221,347 +221,350 @@ Item {
221 anchors.fill: root
221 anchors.fill: root
222 blockInput: coverFlip.visible
222 blockInput: coverFlip.visible
224 Flickable {
225 Flickable {
225 id: coverFlickable
226 id: coverFlickable
226 anchors.fill: root
227 anchors.fill: root
227 contentHeight: height
228 contentHeight: height
228− contentWidth: width * ApplicationManager.count
229+ contentWidth: width * ApplicationManager.count * 0.5
229 flickableDirection: Qt.Horizontal
230 flickableDirection: Qt.Horizontal
230 enabled: coverFlip.visible
231 enabled: coverFlip.visible
232 onContentXChanged: {
233 onContentXChanged: {
233−// print("contentX changed", contentX)
234 var progress = contentX / width
234 var progress = contentX / width
235 if (progress > coverFlip.progressMarker1) {
235 if (progress > coverFlip.progressMarker1) {
236 progress += progress - coverFlip.progressMarker1
236 progress += progress - coverFlip.progressMarker1
239 coverFlip.progress = progress;
239 coverFlip.progress = progress;
240−// print("progress is", coverFlip.progress)
245− id: coverFlip
242+ id: coverFlip
246− height: parent.height
243+ height: parent.height
247− x: 0
244+ // The MouseAreas on the AppImages need to be children of the flickable in order to make focus stealing
245+ // for flicking vs. clicking work correctly.
246+ // However, for the animation calculations to become easier we don't want the row to move so we don't
247+ // always have to take contentX into account. So lets just compensate the flickable's movement here.
248+ x: coverFlickable.contentX
248− visible: progress > 0
249+ visible: progress > 0
250− property real progress: 0
251+ property real progress: 0
251− property real startAngle: 45
252+ property real startAngle: 45
252− property int endAngle: 10
253+ property int endAngle: 10
254− property real maxScale: 1.4
255+ property real maxScale: 1.4
255− property real minScale: .6
256+ property real minScale: .6
257− // Markers: relative screen position from left to right
258+ // Markers: relative screen position from left to right
258− // marks the line where first application is finished moving in from the right
259+ // marks the line where first application is finished moving in from the right
259− property real progressMarker1: 0.5
260+ property real progressMarker1: 0.5
261− property real tileDistance: 0.1
262+ property real tileDistance: 0.1
263− property bool animatingBack: false
264+ property bool animatingBack: false
265− property real tileWidth: root.width
266+ property real tileWidth: root.width
267− property real oldProgress: 0
268+ property real oldProgress: 0
268− onProgressChanged: {
269+ onProgressChanged: {
269− if (oldProgress <= coverFlip.progressMarker1 && progress > coverFlip.progressMarker1) {
270+ if (oldProgress <= coverFlip.progressMarker1 && progress > coverFlip.progressMarker1) {
270− ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
271+ ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
271− } else if (oldProgress >= coverFlip.progressMarker1 && progress <= coverFlip.progressMarker1) {
272+ } else if (oldProgress >= coverFlip.progressMarker1 && progress <= coverFlip.progressMarker1) {
272− ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
273+ ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
275+ oldProgress = progress;
274− oldProgress = progress;
277− function snap() {
278+ function snap() {
278− if (coverFlip.progress < 0.25) {
279+ if (coverFlip.progress < 0.25) {
279− snapAnimation.targetContentX = 0
280+ snapAnimation.targetContentX = 0
280− } else if (coverFlip.progress < 0.6) {
281+ } else if (coverFlip.progress < 0.6) {
281− snapAnimation.targetContentX = root.width * coverFlip.progressMarker1
282+ snapAnimation.targetContentX = root.width * coverFlip.progressMarker1
283− if (ApplicationManager.count == 3) {
284− snapAnimation.targetContentX = root.width * .8;
284+ if (ApplicationManager.count == 3) {
285+ snapAnimation.targetContentX = root.width * .8;
286− snapAnimation.targetContentX = root.width * .9;
287+ snapAnimation.targetContentX = root.width * .9;
290+ snapAnimation.start();
289− snapAnimation.start();
292− function selectItem(index) {
293+ function selectItem(index) {
293− tileRepeater.itemAt(index).select();
294+ tileRepeater.itemAt(index).select();
296− SequentialAnimation {
297+ SequentialAnimation {
297− id: snapAnimation
298+ id: snapAnimation
298− property var targetContentX
299+ property var targetContentX
300− UbuntuNumberAnimation {
301+ UbuntuNumberAnimation {
301− target: coverFlickable
302+ target: coverFlickable
302− properties: "contentX"
303+ properties: "contentX"
303− to: snapAnimation.targetContentX
304+ to: snapAnimation.targetContentX
305− ScriptAction {
306+ ScriptAction {
306− script: {
307+ script: {
307− if (snapAnimation.targetContentX == root.width * coverFlip.progressMarker1) {
308+ if (snapAnimation.targetContentX == root.width * coverFlip.progressMarker1) {
308− coverFlickable.contentX = 0;
309+ coverFlickable.contentX = 0;
314− Repeater {
315+ Repeater {
315− id: tileRepeater
316+ id: tileRepeater
316− model: ApplicationManager
317+ model: ApplicationManager
319− height: parent.height
320+ height: parent.height
320− width: coverFlip.tileWidth
321+ width: coverFlip.tileWidth
323− id: appImage
324+ id: appImage
324− anchors { left: parent.left; bottom: parent.bottom }
325+ anchors { left: parent.left; bottom: parent.bottom }
325− width: root.width
326+ width: root.width
326− source: ApplicationManager.get(index).screenshot
327+ source: ApplicationManager.get(index).screenshot
327− scale: 1
328+ scale: 1
329− // This is the main progress, of the gesture, the same for every tile
330+ // This is the main progress, of the gesture, the same for every tile
330− property real progress: coverFlip.progress
331+ property real progress: coverFlip.progress
331− // The progress, translated for the second stage of the animation, after the first app switch has happened
332+ // The progress, translated for the second stage of the animation, after the first app switch has happened
332− // Additionally it speeds it up a bit, depending on the distance of the tile
333+ // Additionally it speeds it up a bit, depending on the distance of the tile
333− property real translatedProgress: appImage.progress - coverFlip.progressMarker1 - (coverFlip.tileDistance * (index-1))
334+ property real translatedProgress: appImage.progress - coverFlip.progressMarker1 - (coverFlip.tileDistance * (index-1))
335− // Is this tile selected by a click?
336+ // Is this tile selected by a click?
336− property bool isSelected: false
337+ property bool isSelected: false
337− // We need to remember some values when app is selected to be able to animate it to the foreground
338+ // We need to remember some values when app is selected to be able to animate it to the foreground
338− property real selectedXTranslation: 0
339+ property real selectedXTranslation: 0
339− property real selectedTranslatedProgress: 0
340+ property real selectedTranslatedProgress: 0
340− property real selectedAngle: 0
341+ property real selectedAngle: 0
341− property real selectedXScale: 0
342+ property real selectedXScale: 0
343− function select() {
344+ function select() {
344− print("selecting item, current translation:", appImage.xTranslation)
345+ print("selecting item, current translation:", appImage.xTranslation)
345− appImage.selectedXTranslation = appImage.xTranslation;
346+ appImage.selectedXTranslation = appImage.xTranslation;
346− appImage.selectedAngle = appImage.angle;
347+ appImage.selectedAngle = appImage.angle;
347− appImage.selectedXScale = appImage.xScale;
348+ appImage.selectedXScale = appImage.xScale;
348− appImage.selectedTranslatedProgress = appImage.translatedProgress;
349+ appImage.selectedTranslatedProgress = appImage.translatedProgress;
349− print("set selected x translation", appImage.selectedXTranslation)
350+ print("set selected x translation", appImage.selectedXTranslation)
350− appImage.isSelected = true;
351+ appImage.isSelected = true;
351− switchToAppAnimation.start();
352+ switchToAppAnimation.start();
354− property int xTranslation: {
355+ property int xTranslation: {
355− var xTranslate = 0;
356+ var xTranslate = 0;
356− var minXTranslate = -index * root.width + index * units.dp(3);
357+ var minXTranslate = -index * root.width + index * units.dp(3);
357− switch (index) {
358+ switch (index) {
359− if (appImage.progress < coverFlip.progressMarker1) {
360+ if (appImage.progress < coverFlip.progressMarker1) {
360− var progress = appImage.progress
361+ var progress = appImage.progress
361− var progressDiff = coverFlip.progressMarker1
362+ var progressDiff = coverFlip.progressMarker1
362− var translateDiff = -root.width * 0.25
363+ var translateDiff = -root.width * 0.25
363− // progress : progressDiff = translate : translateDiff
364+ // progress : progressDiff = translate : translateDiff
364− xTranslate = progress * translateDiff / progressDiff
365+ xTranslate = progress * translateDiff / progressDiff
368− if (appImage.progress < coverFlip.progressMarker1) {
369− var progress = appImage.progress;
370− var progressDiff = coverFlip.progressMarker1;
371− var translateDiff = -root.width;
372− // progress : progressDiff = translate : translateDiff
373− xTranslate = progress * translateDiff / progressDiff;
369+ if (appImage.progress < coverFlip.progressMarker1) {
370+ var progress = appImage.progress;
371+ var progressDiff = coverFlip.progressMarker1;
372+ var translateDiff = -root.width;
373+ // progress : progressDiff = translate : translateDiff
374+ xTranslate = progress * translateDiff / progressDiff;
377+ // Intentionally no break here...
379+ if (appImage.progress > coverFlip.progressMarker1) {
380+ xTranslate = xTranslateEasing.value * xTranslateEasing.period;
382+ // make sure we stop at the left screen edge
383+ // xTranslate = Math.max(xTranslate, minXTranslate)
376− // Intentionally no break here...
387+ if (appImage.isSelected) {
377− default:
388+ var newTranslate = selectedXTranslateEasing.value * selectedXTranslateEasing.period
378− if (appImage.progress > coverFlip.progressMarker1) {
389+ xTranslate = appImage.selectedXTranslation + newTranslate;
379− xTranslate = xTranslateEasing.value * xTranslateEasing.period;
381− // make sure we stop at the left screen edge
382−// xTranslate = Math.max(xTranslate, minXTranslate)
386− if (appImage.isSelected) {
387− var newTranslate = selectedXTranslateEasing.value * selectedXTranslateEasing.period
388− xTranslate = appImage.selectedXTranslation + newTranslate;
391− return xTranslate;
392+ return xTranslate;
394− property real angle: {
395+ property real angle: {
395− var newAngle = 0;
396+ var newAngle = 0;
396− switch (index) {
397+ switch (index) {
398− if (appImage.progress <= coverFlip.progressMarker1) {
399+ if (appImage.progress <= coverFlip.progressMarker1) {
399− var progress = appImage.progress;
400+ var progress = appImage.progress;
400− var angleDiff = coverFlip.endAngle;
401+ var angleDiff = coverFlip.endAngle;
401− var progressDiff = coverFlip.progressMarker1;
402+ var progressDiff = coverFlip.progressMarker1;
402− // progress : progressDiff = angle : angleDiff
403+ // progress : progressDiff = angle : angleDiff
403− newAngle = progress * angleDiff / progressDiff;
404+ newAngle = progress * angleDiff / progressDiff;
404− } else {
405+ } else {
405− var progress = appImage.progress - coverFlip.progressMarker1;
406+ var progress = appImage.progress - coverFlip.progressMarker1;
406− var angleDiff = coverFlip.endAngle;
407+ var angleDiff = coverFlip.endAngle;
407− var progressDiff = 1 - coverFlip.progressMarker1;
408+ var progressDiff = 1 - coverFlip.progressMarker1;
408− // progress : progressDiff = angle : angleDiff
409+ // progress : progressDiff = angle : angleDiff
409− newAngle = progress * angleDiff / progressDiff;
410+ newAngle = progress * angleDiff / progressDiff;
410− newAngle = Math.min(coverFlip.endAngle, newAngle);
411+ newAngle = Math.min(coverFlip.endAngle, newAngle);
414− if (appImage.progress < coverFlip.progressMarker1) {
415− var progress = coverFlip.progress;
416− var angleDiff = coverFlip.startAngle;
417− var progressDiff = coverFlip.progressMarker1;
418− // progress : progressDiff = angle : angleDiff
419− var angle = progress * angleDiff / progressDiff;
420− newAngle = coverFlip.startAngle - angle;
415+ if (appImage.progress < coverFlip.progressMarker1) {
416+ var progress = coverFlip.progress;
417+ var angleDiff = coverFlip.startAngle;
418+ var progressDiff = coverFlip.progressMarker1;
419+ // progress : progressDiff = angle : angleDiff
420+ var angle = progress * angleDiff / progressDiff;
421+ newAngle = coverFlip.startAngle - angle;
423− // Intentionally no break here...
424+ // Intentionally no break here...
424− default:
425+ default:
425−// var progress = appImage.progress;
426+ // var progress = appImage.progress;
426−// var angleDiff = coverFlip.startAngle - coverFlip.endAngle;
427+ // var angleDiff = coverFlip.startAngle - coverFlip.endAngle;
427−//// var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
428+ //// var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
428−// var progressDiff = index
429+ // var progressDiff = index
429−// // progress : progressDiff = angle : angleDiff
430+ // // progress : progressDiff = angle : angleDiff
430−// newAngle = progress * angleDiff / progressDiff;
431+ // newAngle = progress * angleDiff / progressDiff;
431−// newAngle = Math.max(coverFlip.endAngle, coverFlip.startAngle - newAngle)
432+ // newAngle = Math.max(coverFlip.endAngle, coverFlip.startAngle - newAngle)
434+ newAngle = coverFlip.startAngle - (angleEasing.value * angleEasing.period);
433− newAngle = coverFlip.startAngle - (angleEasing.value * angleEasing.period);
436+ // make sure we stop at the left screen edge
437+ newAngle = Math.max(newAngle, coverFlip.endAngle);
435− // make sure we stop at the left screen edge
439+ }
436− newAngle = Math.max(newAngle, coverFlip.endAngle);
440+ if (appImage.isSelected) {
441+ var selectedAngleTranslate = selectedAngleEasing.value * selectedAngleEasing.period
442+ print("selectedAngle", appImage.selectedAngle, "translate", selectedAngleTranslate)
443+ newAngle = appImage.selectedAngle - selectedAngleTranslate;
438− }
446+ return newAngle;
439− if (appImage.isSelected) {
440− var selectedAngleTranslate = selectedAngleEasing.value * selectedAngleEasing.period
441− print("selectedAngle", appImage.selectedAngle, "translate", selectedAngleTranslate)
442− newAngle = appImage.selectedAngle - selectedAngleTranslate;
448− property real xScale: {
449+ property real xScale: {
449− var scale = 1;
450+ var scale = 1;
451− switch (index) {
452+ switch (index) {
453− if (appImage.progress > coverFlip.progressMarker1) {
454+ if (appImage.progress > coverFlip.progressMarker1) {
454− var scaleDiff = coverFlip.maxScale - 1;
455+ var scaleDiff = coverFlip.maxScale - 1;
455− var progressDiff = 1.5 - coverFlip.progressMarker1;
456+ var progressDiff = 1.5 - coverFlip.progressMarker1;
456− // progress : progressDiff = scale : scaleDiff
457+ // progress : progressDiff = scale : scaleDiff
457− scale = 1 - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff;
458+ scale = 1 - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff;
461− if (appImage.progress < coverFlip.progressMarker1) {
462− var scaleDiff = coverFlip.maxScale - 1
463− var progressDiff = coverFlip.progressMarker1
464− // progress : progressDiff = scale : scaleDiff
465− scale = coverFlip.maxScale - (appImage.progress * scaleDiff / progressDiff);
462+ if (appImage.progress < coverFlip.progressMarker1) {
463+ var scaleDiff = coverFlip.maxScale - 1
464+ var progressDiff = coverFlip.progressMarker1
465+ // progress : progressDiff = scale : scaleDiff
466+ scale = coverFlip.maxScale - (appImage.progress * scaleDiff / progressDiff);
469+ // Intentionally no break
471+ // var scaleDiff = coverFlip.maxScale - coverFlip.minScale
472+ //// var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
473+ // var progressDiff = index
474+ // // progress : progressDiff = scale : scaleDiff
475+ // scale = coverFlip.maxScale - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff
478+ scale = coverFlip.maxScale - scaleEasing.value * scaleEasing.period;
468− // Intentionally no break
470−// var scaleDiff = coverFlip.maxScale - coverFlip.minScale
471−//// var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
472−// var progressDiff = index
473−// // progress : progressDiff = scale : scaleDiff
474−// scale = coverFlip.maxScale - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff
477− scale = coverFlip.maxScale - scaleEasing.value * scaleEasing.period;
480− if (appImage.isSelected) {
481+ if (appImage.isSelected) {
481− var selectedScaleTranslate = selectedScaleEasing.value * selectedScaleEasing.period
482+ var selectedScaleTranslate = selectedScaleEasing.value * selectedScaleEasing.period
482− scale = appImage.selectedXScale + selectedScaleTranslate;
483+ scale = appImage.selectedXScale + selectedScaleTranslate;
485− return Math.min(coverFlip.maxScale, Math.max(coverFlip.minScale, scale));
486+ return Math.min(coverFlip.maxScale, Math.max(coverFlip.minScale, scale));
489− EasingCurve {
490+ EasingCurve {
490− id: xTranslateEasing
491+ id: xTranslateEasing
491− type: EasingCurve.OutQuad
492+ type: EasingCurve.OutQuad
492− period: index * -width
493+ period: index * -width
493− progress: appImage.translatedProgress
494+ progress: appImage.translatedProgress
495− EasingCurve {
496+ EasingCurve {
496− id: selectedXTranslateEasing
497+ id: selectedXTranslateEasing
497− type: EasingCurve.Linear
498+ type: EasingCurve.Linear
498− period: xTranslateEasing.period - appImage.selectedXTranslation
499+ period: xTranslateEasing.period - appImage.selectedXTranslation
499− progress: appImage.selectedTranslatedProgress - xTranslateEasing.progress
500+ progress: appImage.selectedTranslatedProgress - xTranslateEasing.progress
501− EasingCurve {
502+ EasingCurve {
502− id: angleEasing
503+ id: angleEasing
503− type: EasingCurve.InQuad
504+ type: EasingCurve.InQuad
504− period: coverFlip.startAngle - coverFlip.endAngle
505+ period: coverFlip.startAngle - coverFlip.endAngle
505− progress: appImage.translatedProgress
506+ progress: appImage.translatedProgress
507− EasingCurve {
508+ EasingCurve {
508− id: selectedAngleEasing
509+ id: selectedAngleEasing
509− type: EasingCurve.Linear
510+ type: EasingCurve.Linear
510− period: appImage.selectedAngle
511+ period: appImage.selectedAngle
511− progress: appImage.selectedTranslatedProgress - angleEasing.progress
512+ progress: appImage.selectedTranslatedProgress - angleEasing.progress
513− EasingCurve {
514+ EasingCurve {
514− id: scaleEasing
515+ id: scaleEasing
515− type: EasingCurve.Linear
516+ type: EasingCurve.Linear
516− period: coverFlip.maxScale - coverFlip.minScale
517+ period: coverFlip.maxScale - coverFlip.minScale
517− progress: appImage.translatedProgress
518+ progress: appImage.translatedProgress
519− EasingCurve {
520+ EasingCurve {
520− id: selectedScaleEasing
521+ id: selectedScaleEasing
521− type: EasingCurve.Linear
522+ type: EasingCurve.Linear
522− period: 1 - appImage.selectedXScale
523+ period: 1 - appImage.selectedXScale
523− progress: appImage.selectedTranslatedProgress - scaleEasing.progress
524+ progress: appImage.selectedTranslatedProgress - scaleEasing.progress
528− origin { x: 0; y: coverFlip.height / 2 }
529− axis { x: 0; y: 1; z: 0 }
530− angle: appImage.angle
533− x: appImage.xTranslation
536− origin { x: appImage.xTranslation; y: root.height / 2 - (root.height - appImage.height)}
537− xScale: appImage.xScale
529+ origin { x: 0; y: coverFlip.height / 2 }
530+ axis { x: 0; y: 1; z: 0 }
531+ angle: appImage.angle
534+ x: appImage.xTranslation
537+ origin { x: appImage.xTranslation; y: root.height / 2 - (root.height - appImage.height)}
538+ xScale: appImage.xScale
542− MouseArea {
543+ MouseArea {
543− anchors.fill: parent
544+ anchors.fill: parent
544− onClicked: {
545+ onClicked: {
545− print("clicked on index", index)
546+ print("clicked on index", index)
546− appImage.select()
547+ appImage.select()
551− SequentialAnimation {
552+ SequentialAnimation {
552− id: switchToAppAnimation
553+ id: switchToAppAnimation
553− ParallelAnimation {
554+ ParallelAnimation {
554− UbuntuNumberAnimation { target: coverFlickable; property: "contentX"; to: 0}
555+ UbuntuNumberAnimation { target: coverFlickable; property: "contentX"; to: 0}
556− ScriptAction {
557+ ScriptAction {
557− script: {
558+ script: {
558− ApplicationManager.focusApplication(ApplicationManager.get(index).appId);
559+ ApplicationManager.focusApplication(ApplicationManager.get(index).appId);
559− appImage.isSelected = false;
560+ appImage.isSelected = false;
560− coverFlip.progress = 0;
561+ coverFlip.progress = 0;