appDisplay: Animate AllView and FrequentView
Following design decision, we want to animate AllView and FrequentView when opening and closing with a swarm spring form. This involves a few changes needed to allow that, since from some time now, we are animating page changes in viewSelector, using only a fade transition. However now we want to let appDisplay and iconGrid apply its own animation. For that we special case the change to and from apps page on viewSelector to let appDisplay to animate its own items, using and API on appDisplay which at the same time uses an API on iconGrid. Thanks Florian Müllner for the debugging work https://bugzilla.gnome.org/show_bug.cgi?id=734726
This commit is contained in:
@ -18,12 +18,16 @@ const MIN_ICON_SIZE = 16;
|
||||
const EXTRA_SPACE_ANIMATION_TIME = 0.25;
|
||||
|
||||
const ANIMATION_TIME_IN = 0.350;
|
||||
const ANIMATION_TIME_OUT = 1/2 * ANIMATION_TIME_IN;
|
||||
const ANIMATION_MAX_DELAY_FOR_ITEM = 2/3 * ANIMATION_TIME_IN;
|
||||
const ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 2/3 * ANIMATION_TIME_OUT;
|
||||
const ANIMATION_FADE_IN_TIME_FOR_ITEM = 1/4 * ANIMATION_TIME_IN;
|
||||
|
||||
const ANIMATION_BOUNCE_ICON_SCALE = 1.1;
|
||||
|
||||
const AnimationDirection = {
|
||||
IN: 0
|
||||
IN: 0,
|
||||
OUT: 1
|
||||
};
|
||||
|
||||
const BaseIcon = new Lang.Class({
|
||||
@ -420,6 +424,118 @@ const IconGrid = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
animateSpring: function(animationDirection, sourceActor) {
|
||||
if (this._animating)
|
||||
return;
|
||||
|
||||
this._animating = true;
|
||||
|
||||
let actors = this._getChildrenToAnimate();
|
||||
if (actors.length == 0) {
|
||||
this._animationDone();
|
||||
return;
|
||||
}
|
||||
|
||||
let [sourceX, sourceY] = sourceActor.get_transformed_position();
|
||||
let [sourceWidth, sourceHeight] = sourceActor.get_size();
|
||||
// Get the center
|
||||
let [sourceCenterX, sourceCenterY] = [sourceX + sourceWidth / 2, sourceY + sourceHeight / 2];
|
||||
// Design decision, 1/2 of the source actor size.
|
||||
let [sourceScaledWidth, sourceScaledHeight] = [sourceWidth / 2, sourceHeight / 2];
|
||||
|
||||
actors.forEach(function(actor) {
|
||||
let [actorX, actorY] = actor._transformedPosition = actor.get_transformed_position();
|
||||
let [x, y] = [actorX - sourceX, actorY - sourceY];
|
||||
actor._distance = Math.sqrt(x * x + y * y);
|
||||
});
|
||||
let maxDist = actors.reduce(function(prev, cur) {
|
||||
return Math.max(prev, cur._distance);
|
||||
}, 0);
|
||||
let minDist = actors.reduce(function(prev, cur) {
|
||||
return Math.min(prev, cur._distance);
|
||||
}, Infinity);
|
||||
let normalization = maxDist - minDist;
|
||||
|
||||
for (let index = 0; index < actors.length; index++) {
|
||||
let actor = actors[index];
|
||||
actor.opacity = 0;
|
||||
|
||||
let actorClone = new Clutter.Clone({ source: actor });
|
||||
Main.uiGroup.add_actor(actorClone);
|
||||
|
||||
let [width, height,,] = this._getAllocatedChildSizeAndSpacing(actor);
|
||||
actorClone.set_size(width, height);
|
||||
let scaleX = sourceScaledWidth / width;
|
||||
let scaleY = sourceScaledHeight / height;
|
||||
let [adjustedSourcePositionX, adjustedSourcePositionY] = [sourceCenterX - sourceScaledWidth / 2, sourceY - sourceScaledHeight / 2];
|
||||
|
||||
// Defeat onComplete anonymous function closure
|
||||
let isLastItem = index == actors.length - 1;
|
||||
|
||||
let movementParams, fadeParams;
|
||||
if (animationDirection == AnimationDirection.IN) {
|
||||
actorClone.opacity = 0;
|
||||
actorClone.set_scale(scaleX, scaleY);
|
||||
|
||||
actorClone.set_position(adjustedSourcePositionX, adjustedSourcePositionY);
|
||||
|
||||
let delay = (1 - (actor._distance - minDist) / normalization) * ANIMATION_MAX_DELAY_FOR_ITEM;
|
||||
let [finalX, finalY] = actor._transformedPosition;
|
||||
movementParams = { time: ANIMATION_TIME_IN,
|
||||
transition: 'easeInOutQuad',
|
||||
delay: delay,
|
||||
x: finalX,
|
||||
y: finalY,
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
onComplete: Lang.bind(this, function() {
|
||||
if (isLastItem)
|
||||
this._animationDone();
|
||||
|
||||
actor.opacity = 255;
|
||||
actorClone.destroy();
|
||||
})};
|
||||
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
||||
transition: 'easeInOutQuad',
|
||||
delay: delay,
|
||||
opacity: 255 };
|
||||
} else {
|
||||
let [startX, startY] = actor._transformedPosition;
|
||||
actorClone.set_position(startX, startY);
|
||||
|
||||
let delay = (actor._distance - minDist) / normalization * ANIMATION_MAX_DELAY_OUT_FOR_ITEM;
|
||||
movementParams = { time: ANIMATION_TIME_OUT,
|
||||
transition: 'easeInOutQuad',
|
||||
delay: delay,
|
||||
x: adjustedSourcePositionX,
|
||||
y: adjustedSourcePositionY,
|
||||
scale_x: scaleX,
|
||||
scale_y: scaleY,
|
||||
onComplete: Lang.bind(this, function() {
|
||||
if (isLastItem) {
|
||||
this._animationDone();
|
||||
this._restoreItemsOpacity();
|
||||
}
|
||||
actorClone.destroy();
|
||||
})};
|
||||
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
||||
transition: 'easeInOutQuad',
|
||||
delay: ANIMATION_TIME_OUT + delay - ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
||||
opacity: 0 };
|
||||
}
|
||||
|
||||
|
||||
Tweener.addTween(actorClone, movementParams);
|
||||
Tweener.addTween(actorClone, fadeParams);
|
||||
}
|
||||
},
|
||||
|
||||
_restoreItemsOpacity: function() {
|
||||
for (let index = 0; index < this._items.length; index++) {
|
||||
this._items[index].actor.opacity = 255;
|
||||
}
|
||||
},
|
||||
|
||||
_getAllocatedChildSizeAndSpacing: function(child) {
|
||||
let [,, natWidth, natHeight] = child.get_preferred_size();
|
||||
let width = Math.min(this._getHItemSize(), natWidth);
|
||||
@ -632,6 +748,7 @@ const PaginatedIconGrid = new Lang.Class({
|
||||
_init: function(params) {
|
||||
this.parent(params);
|
||||
this._nPages = 0;
|
||||
this.currentPage = 0;
|
||||
this._rowsPerPage = 0;
|
||||
this._spaceBetweenPages = 0;
|
||||
this._childrenPerPage = 0;
|
||||
@ -695,6 +812,15 @@ const PaginatedIconGrid = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
// Overriden from IconGrid
|
||||
_getChildrenToAnimate: function() {
|
||||
let children = this._getVisibleChildren();
|
||||
let firstIndex = this._childrenPerPage * this.currentPage;
|
||||
let lastIndex = firstIndex + this._childrenPerPage;
|
||||
|
||||
return children.slice(firstIndex, lastIndex);
|
||||
},
|
||||
|
||||
_computePages: function (availWidthPerPage, availHeightPerPage) {
|
||||
let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage);
|
||||
let nRows;
|
||||
|
Reference in New Issue
Block a user