[gnome-shell/wip/swarm: 114/126] appDisplay: Animate folder view items
- From: Carlos Soriano <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/swarm: 114/126] appDisplay: Animate folder view items
- Date: Mon, 11 Aug 2014 20:30:16 +0000 (UTC)
commit 34a40fe39dfc0435a7cb39033ef32f1d0e7a11dd
Author: Carlos Soriano <carlos soriano89 gmail com>
Date: Tue Jun 17 12:47:00 2014 +0200
appDisplay: Animate folder view items
js/ui/appDisplay.js | 23 ++++++++++++-
js/ui/iconGrid.js | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+), 2 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index dcecae3..ca56d6c 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -966,6 +966,10 @@ const FolderView = new Lang.Class({
Util.ensureActorVisibleInScrollView(this.actor, actor);
},
+ animate: function(animationType, animationDirection, params) {
+ this._grid.animate(animationType, animationDirection, params);
+ },
+
createFolderIcon: function(size) {
let layout = new Clutter.GridLayout();
let icon = new St.Widget({ layout_manager: layout,
@@ -1341,8 +1345,22 @@ const AppFolderPopup = new Lang.Class({
this.actor.show();
this._boxPointer.setArrowActor(this._source.actor);
+ // We need to hide the icons of the view until the boxpointer animation
+ // is completed so we can animate the icons after as we like withouth
+ // showing them while boxpointer is animating.
+ this._view.actor.opacity = 0;
this._boxPointer.show(BoxPointer.PopupAnimation.FADE |
- BoxPointer.PopupAnimation.SLIDE);
+ BoxPointer.PopupAnimation.SLIDE,
+ Lang.bind(this,
+ function() {
+ // Restore the view opacity, so now we show the icons and animate
+ // them
+ this._view.actor.opacity = 255;
+ this._view.animate(IconGrid.AnimationType.BOUNCE,
+ IconGrid.AnimationDirection.IN,
+ { sourcePosition: this._source.actor.get_transformed_position(),
+ sourceSize: this._source.actor.get_transformed_size() });
+ }));
this.emit('open-state-changed', true);
},
@@ -1354,7 +1372,8 @@ const AppFolderPopup = new Lang.Class({
this._grabHelper.ungrab({ actor: this.actor });
this._boxPointer.hide(BoxPointer.PopupAnimation.FADE |
- BoxPointer.PopupAnimation.SLIDE);
+ BoxPointer.PopupAnimation.SLIDE,
+ this._view.animateOut);
this._isOpen = false;
this.emit('open-state-changed', false);
},
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 9cf9f2f..e29f3ba 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -10,12 +10,26 @@ const St = imports.gi.St;
const Lang = imports.lang;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
+const Main = imports.ui.main;
const ICON_SIZE = 96;
const MIN_ICON_SIZE = 16;
const EXTRA_SPACE_ANIMATION_TIME = 0.25;
+const ANIMATION_TIME_IN = 0.350;
+const ANIMATION_MAX_DELAY_FOR_ITEM = 2/3 * ANIMATION_TIME_IN;
+
+const ANIMATION_BOUNCE_ICON_SCALE = 1.1;
+
+const AnimationType = {
+ BOUNCE: 0
+};
+
+const AnimationDirection = {
+ IN: 0
+};
+
const BaseIcon = new Lang.Class({
Name: 'BaseIcon',
@@ -338,6 +352,81 @@ const IconGrid = new Lang.Class({
}
},
+ /**
+ * Intended to be override by subclasses if they need a diferent
+ * set of items to be animated.
+ */
+ _getChildrenToAnimate: function() {
+ return this._getVisibleChildren();
+ },
+
+ animate: function(animationType, animationDirection, params) {
+ let actors = this._getChildrenToAnimate();
+ if (this._animating || actors.length == 0)
+ return;
+ this._animating = true;
+
+ for (let index = 0; index < actors.length; index++)
+ actors[index].opacity = 0;
+
+ let delayedAnimation = Lang.bind(this, function() {
+ switch (animationType) {
+ case AnimationType.BOUNCE:
+ this._animateBounce(actors, animationDirection);
+ break;
+ default:
+ break;
+ }
+ });
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, delayedAnimation);
+ },
+
+ _animateBounce: function(actors, animationDirection) {
+ for (let index = 0; index < actors.length; index++) {
+ let delay = index / actors.length * ANIMATION_MAX_DELAY_FOR_ITEM;
+
+ let [originalX, originalY] = actors[index].get_transformed_position();
+ let [originalWidth, originalHeight] = actors[index].get_transformed_size();
+
+ let actorClone = new Clutter.Clone({ source: actors[index],
+ reactive: false });
+ Main.uiGroup.add_actor(actorClone);
+
+ actorClone.reactive = false;
+ actorClone.set_position(originalX, originalY);
+ actorClone.set_scale(0, 0);
+ actorClone.set_pivot_point(0.5, 0.5);
+ let [width, height] = actors[index].get_transformed_size();
+ actorClone.set_size(width, height);
+
+ // Defeat onComplete anonymous function closure
+ let actor= actors[index];
+ let isLastActor= index == actors.length - 1;
+ Tweener.addTween(actorClone,
+ { time: ANIMATION_TIME_IN / 4,
+ transition: 'easeInOutQuad',
+ delay: delay,
+ scale_x: ANIMATION_BOUNCE_ICON_SCALE,
+ scale_y: ANIMATION_BOUNCE_ICON_SCALE,
+ onComplete: Lang.bind(this, function() {
+ Tweener.addTween(actorClone,
+ { time: ANIMATION_TIME_IN - ANIMATION_TIME_IN / 4,
+ transition: 'easeInOutQuad',
+ scale_x: 1,
+ scale_y: 1,
+ onComplete: Lang.bind(this, function() {
+ if (isLastActor)
+ this._animating = false;
+ actor.opacity = 255;
+ actorClone.destroy();
+ this.emit('animation-done');
+ })
+ });
+ })
+ });
+ }
+ },
+
_calculateChildBox: function(child, x, y, box) {
let [childMinWidth, childMinHeight, childNaturalWidth, childNaturalHeight] =
child.get_preferred_size();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]