[gnome-shell/wip/swarm] nnn



commit e9ae20ffcb464785763944eb30f89e1b4e3ac0aa
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Tue Jun 10 01:45:41 2014 +0200

    nnn

 js/ui/appDisplay.js   |   94 ++++++------
 js/ui/iconGrid.js     |  410 +++++++++++++++++++++++++++----------------------
 js/ui/viewSelector.js |   44 ++++--
 3 files changed, 306 insertions(+), 242 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 285df9d..e43a329 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -144,11 +144,7 @@ const BaseAppView = new Lang.Class({
         return a.name.localeCompare(b.name);
     },
     
-    animateIn: function(origin, originSize, animationType) {
-        throw new Error('Not implemented');
-    },
-    
-    animateOut: function(origin, animationType) {
+    animate: function(animationType, animationDirection, params) {
         throw new Error('Not implemented');
     },
 
@@ -445,21 +441,28 @@ const AllView = new Lang.Class({
         this._refilterApps();
     },
     
-    animateIn: function(origin, originSize, animationType) {
-        let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
-            function() {
-                if (this._grid.actor.mapped) {
-                    this._grid.actor.disconnect(toAnimate);
-                    this._grid.animateIn(origin, originSize, animationType);
-                }
-            }));
-    },
-    
-    animateOut: function(origin, animationType) {
-        throw new Error('Not implemented');
+    animate: function(animationDirection) {
+        let dashPosition = Main.overview._dash._showAppsIcon.get_transformed_position();
+        let dashSize = Main.overview._dash._showAppsIcon.get_transformed_size();
+        if (animationDirection == IconGrid.ANIMATION_DIRECTION_IN) {
+            let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
+                function() {
+                    if (this._grid.actor.mapped) {
+                        this._grid.actor.disconnect(toAnimate);
+                        this._grid.animate(IconGrid.ANIMATION_TYPE_SWARM_SPRING,
+                                           animationDirection,
+                                           { sourcePosition: dashPosition,
+                                             sourceSize: dashSize });
+                    }
+                }));
+        } else {
+            this._grid.animate(IconGrid.ANIMATION_TYPE_SWARM_SPRING,
+                                           animationDirection,
+                                           { sourcePosition: dashPosition,
+                                             sourceSize: dashSize });
+        }
     },
 
-
     getCurrentPageY: function() {
         return this._grid.getPageY(this._currentPage);
     },
@@ -701,18 +704,26 @@ const FrequentView = new Lang.Class({
         }
     },
     
-    animateIn: function(origin, originSize, animationType) {
-        let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
-            function() {
-                if (this._grid.actor.mapped) {
-                    this._grid.actor.disconnect(toAnimate);
-                    this._grid.animateIn(origin, originSize, animationType);
-                }
-            }));
-    },
-    
-    animateOut: function(origin, animationType) {
-        throw new Error('Not implemented');
+    animate: function(animationDirection) {
+        let dashPosition = Main.overview._dash._showAppsIcon.get_transformed_position();
+        let dashSize = Main.overview._dash._showAppsIcon.get_transformed_size();
+        if (animationDirection == IconGrid.ANIMATION_DIRECTION_IN) {
+            let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
+                function() {
+                    if (this._grid.actor.mapped) {
+                        this._grid.actor.disconnect(toAnimate);
+                        this._grid.animate(IconGrid.ANIMATION_TYPE_SWARM_SPRING,
+                                           animationDirection,
+                                           { sourcePosition: dashPosition,
+                                             sourceSize: dashSize });
+                    }
+                }));
+        } else {
+            this._grid.animate(IconGrid.ANIMATION_TYPE_SWARM_SPRING,
+                                           animationDirection,
+                                           { sourcePosition: dashPosition,
+                                             sourceSize: dashSize });
+        }
     },
 
     // Called before allocation to calculate dynamic spacing
@@ -837,12 +848,10 @@ const AppDisplay = new Lang.Class({
         this._updateFrequentVisibility();
     },
     
-    animateIn: function() {
+    animate: function(animationDirection) {
         let view = this._views[global.settings.get_uint('app-picker-view')].view;
-        log("size " + Main.overview._dash._showAppsIcon.get_transformed_size());
-        view.animateIn(Main.overview._dash._showAppsIcon.get_transformed_position(),
-                       Main.overview._dash._showAppsIcon.get_transformed_size(),
-                       IconGrid.ANIMATION_TYPE_SWARM_FAR_FIRST);
+        log("animationDirection " + animationDirection);
+        view.animate(animationDirection);
     },
 
     _showView: function(activeIndex) {
@@ -994,12 +1003,8 @@ const FolderView = new Lang.Class({
         Util.ensureActorVisibleInScrollView(this.actor, actor);
     },
     
-    animateIn: function(origin, originSize, animationType) {
-        this._grid.animateIn(origin, originSize, animationType);
-    },
-    
-     animateOut: function(origin, animationType) {
-        log("FolderView out");
+    animate: function(animationType, animationDirection, params) {
+        this._grid.animate(animationType, animationDirection, params);
     },
 
     createFolderIcon: function(size) {
@@ -1351,9 +1356,10 @@ const AppFolderPopup = new Lang.Class({
                 // Restore the view opacity, so now we show the icons and animate
                 // them
                 this._view.actor.opacity = 255;
-                this._view.animateIn(this._source.actor.get_transformed_position(),
-                                     this._source.actor.get_transformed_size(),
-                                     IconGrid.ANIMATION_TYPE_APPEAR);
+                this._view.animate(IconGrid.ANIMATION_TYPE_APPEAR,
+                                     IconGrid.ANIMATION_DIRECTION_IN,
+                                     { sourcePosition: this._source.actor.get_transformed_position(),
+                                       sourceSize: this._source.actor.get_transformed_size() });
             }));
 
         this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 23aa2a5..9bbe54c 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -17,8 +17,10 @@ const MIN_ICON_SIZE = 16;
 
 const EXTRA_SPACE_ANIMATION_TIME = 0.25;
 
-const ANIMATION_TIME = 0.400;
+const ANIMATION_TIME_IN = 0.400;
+const ANIMATION_TIME_OUT = 0.200;
 const ANIMATION_MAX_DELAY_FOR_ITEM = 0.250;
+const ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 0.125;
 const ANIMATION_FADE_IN_TIME_FOR_ITEM = 0.100;
 
 const ANIMATION_TIME_TYPE_APPEAR = 0.400;
@@ -27,8 +29,10 @@ const ANIMATION_APPEAR_ICON_SCALE = 1.1;
 const ANIMATION_TYPE_NONE = 0;
 const ANIMATION_TYPE_APPEAR = 1;
 const ANIMATION_TYPE_SWARM_RANDOM = 2;
-const ANIMATION_TYPE_SWARM_FAR_FIRST = 3;
+const ANIMATION_TYPE_SWARM_SPRING = 3;
 
+const ANIMATION_DIRECTION_OUT = 0;
+const ANIMATION_DIRECTION_IN = 1;
 
 const BaseIcon = new Lang.Class({
     Name: 'BaseIcon',
@@ -373,78 +377,242 @@ const IconGrid = new Lang.Class({
         }
     },
 
-
-    animateIn: function(origin, originSize, animationType) {
-        this._animationOrigin = origin;
-        this._animationOriginSize = originSize;
-        this._animationType = animationType;
-
-        this._animateInReal(this._paintedItems);
+    /**
+     * Intended to be override by subclasses if they need a diferent
+     * set of items to be animated.
+     */
+    animate: function(animationType, animationDirection, params) {
+        this._animateReal(this._paintedItems, animationType, animationDirection, params);
     },
 
-    _animateInReal: function(items) {
-        log("items " + items.length);
+    _animateReal: function(items, animationType, animationDirection, params) {
+        params = Params.parse(params, { sourcePosition: null,
+                                        sourceSize: null });
         if (this._animating || items.length == 0)
             return;
-
-        log("animating real to be done");
         this._animating = true;
 
+        switch (animationType) {
+            case ANIMATION_TYPE_SWARM_SPRING:
+                this._animateSwarmSpring(items, animationDirection, params.sourcePosition, 
params.sourceSize);
+                break;
+            case ANIMATION_TYPE_SWARM_RANDOM:
+                this._animateSwarmRandom(items, animationDirection, params.sourcePosition, 
params.sourceSize);
+                break;
+            case ANIMATION_TYPE_APPEAR:
+                this._animateAppear(items, animationDirection);
+                break;
+            default:
+                break;
+        }
+    },
+
+    _animateAppear: function(items, animationDirection) {
+        for (let index = 0; index < items.length; index++) {
+            // FIXME? Seems that putting the items at opacity 0
+            // for animating seems like it doesn't belongs here.
+            // But works well.
+            items[index].actor.opacity = 0;
+            let delay = index / items.length * ANIMATION_MAX_DELAY_FOR_ITEM;
+
+            let [originalX, originalY] = items[index].actor.get_transformed_position();
+            let [originalWidth, originalHeight] = items[index].actor.get_transformed_size();
+
+            let itemClone = items[index].clone();
+            Main.uiGroup.add_actor(itemClone.actor);
+
+            itemClone.actor.reactive = false;
+            itemClone.actor.set_position(originalX, originalY);
+            itemClone.icon.icon.set_size(0, 0);
+            // Force to use the current size, so the label and the container
+            // of the actor doesnn't resize while the icon texture is 
+            // animating. That avoids to see the label wrapping the text and
+            // also avoids the container to be positioned top left while animating instead
+            // of center.
+            itemClone.actor.set_size(originalWidth, originalHeight);
+
+            let originalIconSize = itemClone.icon.iconSize;
+            // Defeat onComplete anonymous function closure
+            let item = items[index];
+            let isLastItem = index == items.length - 1;
+            Tweener.addTween(itemClone.icon.icon,
+                            { time: ANIMATION_TIME_TYPE_APPEAR / 4,
+                              transition: 'easeInOutQuad',
+                              delay: delay,
+                              width: originalIconSize * ANIMATION_APPEAR_ICON_SCALE,
+                              height: originalIconSize * ANIMATION_APPEAR_ICON_SCALE,
+                              onComplete: Lang.bind(this, function() {
+                                  Tweener.addTween(itemClone.icon.icon,
+                                                   { time: ANIMATION_TIME_TYPE_APPEAR - 
ANIMATION_TIME_TYPE_APPEAR / 4,
+                                                     transition: 'easeInOutQuad',
+                                                     width: originalIconSize,
+                                                     height: originalIconSize,
+                                                     onComplete: Lang.bind(this, function() {
+                                                        if (isLastItem)
+                                                            this._animating = false;
+                                                        item.actor.opacity = 255;
+                                                        itemClone.actor.destroy();
+                                                    })
+                                                   });
+                              })
+                            });
+        }
+    },
+
+            /*
+            _animateSwarmSpring
+            // Implicit animations implementation.
+            itemClone.actor.save_easing_state();
+            itemClone.icon._iconBin.save_easing_state();
+
+            itemClone.actor.set_easing_duration(ANIMATION_TIME_IN * 3);
+            itemClone.actor.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
+            itemClone.actor.set_easing_delay(delay);
+            itemClone.icon._iconBin.set_easing_delay(delay);
+            itemClone.actor.set_position(originalX, originalY);
+            itemClone.actor.set_opacity(255);
+
+            if (this._animationType == ANIMATION_TYPE_APPEAR) {
+                itemClone.icon._iconBin.set_easing_mode(Clutter.AnimationMode.EASE_OUT_BACK);
+                itemClone.actor.set_easing_mode(Clutter.AnimationMode.EASE_OUT_BACK);
+            } else {
+                itemClone.icon._iconBin.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
+            }
+            itemClone.icon._iconBin.set_size(300-20, 300-20);
+            itemClone.actor.set_size(300, 300);
+
+            itemClone.actor.restore_easing_state();
+            itemClone.icon._iconBin.restore_easing_state();
+
+            itemClone.actor.connect('transition-stopped::', Lang.bind(this,
+                function(a, n, completed) {
+                    if (isLastItem)
+                        this._animating = false;
+                    item.actor.opacity = 255;
+                    itemClone.actor.destroy();                
+               }));
+            */
+
+    _animateSwarmSpring: function(items, animationDirection, sourcePosition, sourceSize) {
+        log("swarmSpring");
         let distances = items.map(Lang.bind(this, function(item) {
-            return this._distance(item.actor.get_transformed_position(), this._animationOrigin);
+            return this._distance(item.actor.get_transformed_position(), sourcePosition);
         }));
+        let maxDist = Math.max.apply(Math, distances);
+        let minDist = Math.min.apply(Math, distances);
+        let normalization = maxDist - minDist;
+
+        for (let index = 0; index < items.length; index++) {
+            // FIXME? Seems that putting the items at opacity 0
+            // for animating seems like it doesn't belongs here.
+            // But works well.
+            items[index].actor.opacity = 0;
+
+            let itemClone = items[index].clone();
+            Main.uiGroup.add_actor(itemClone.actor);
+
+            itemClone.actor.reactive = false;
+            //itemClone.actor.set_size(sourceSize, sourceSize);
+            // Defeat onComplete anonymous function closure
+            let item = items[index];
+            let isLastItem = index == items.length - 1;
+
+            let movementParams, fadeParams;
+            if (animationDirection == ANIMATION_DIRECTION_IN) {
+                itemClone.actor.set_position(sourcePosition[0], sourcePosition[1]);
+                itemClone.actor.opacity = 0;
+
+                let delay = (1 - (distances[index] - minDist) / normalization) * 
ANIMATION_MAX_DELAY_FOR_ITEM;
+                let [finalX, finalY]  = items[index].actor.get_transformed_position();
+                movementParams = { time: ANIMATION_TIME_IN,
+                                   transition: 'easeInOutQuad',
+                                   delay: delay,
+                                   x: finalX,
+                                   y: finalY,
+                                   onComplete: Lang.bind(this, function() {
+                                       if (isLastItem)
+                                           this._animating = false;
+                                       item.actor.opacity = 255;
+                                       itemClone.actor.destroy();
+                                   })};
+                fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
+                               transition: 'easeInOutQuad',
+                               delay: delay,
+                               opacity: 255 };
+            } else {
+                let [startX, startY]  = items[index].actor.get_transformed_position();
+                itemClone.actor.set_position(startX, startY);
+
+                let delay = (distances[index] - minDist) / normalization * ANIMATION_MAX_DELAY_OUT_FOR_ITEM;
+                let [finalX, finalY] = [sourcePosition[0], sourcePosition[1]];
+                movementParams = { time: ANIMATION_TIME_OUT,
+                                   transition: 'easeInOutQuad',
+                                   delay: delay,
+                                   x: finalX,
+                                   y: finalY,
+                                   onComplete: Lang.bind(this, function() {
+                                       if (isLastItem)
+                                           this._animating = false;
+                                       itemClone.actor.destroy();
+                                   })};
+                fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
+                               transition: 'easeInOutQuad',
+                               delay: ANIMATION_TIME_OUT + delay - ANIMATION_FADE_IN_TIME_FOR_ITEM,
+                               opacity: 0 };
+            }
+
 
-        let delay;
+            Tweener.addTween(itemClone.actor, movementParams);
+            Tweener.addTween(itemClone.actor, fadeParams);
+        }
+    },
+
+    _animateSwarmRandom: function(item, animationDirection, startPosition, startSize) {
+        let distances = items.map(Lang.bind(this, function(item) {
+            return this._distance(item.actor.get_transformed_position(), startPosition);
+        }));
         let maxDist = Math.max.apply(Math, distances);
         let minDist = Math.min.apply(Math, distances);
         let normalization = maxDist - minDist;
+
         for (let index = 0; index < items.length; index++) {
             // FIXME? Seems that putting the items at opacity 0
             // for animating seems like it doesn't belongs here.
             // But works well.
             items[index].actor.opacity = 0;
+            delay = (1 - (distances[index] - minDist) / normalization) * ANIMATION_MAX_DELAY_FOR_ITEM;
+
             let [finalX, finalY] = items[index].actor.get_transformed_position();
-            switch (this._animationType) {
-                case ANIMATION_TYPE_SWARM_FAR_FIRST:
-                    [startX, startY] = this._animationOrigin;
-                    delay = (1 - (distances[index] - minDist) / normalization) * 
ANIMATION_MAX_DELAY_FOR_ITEM;
-                    this._animateItem(items[index],
-                              this._animationOriginSize,
-                              [startX, startY],
-                              delay,
-                              index == items.length - 1);
-                    break;
-                case ANIMATION_TYPE_SWARM_RANDOM:
-                    [startX, startY] = this._animationOrigin;
-                    delay = Math.random() * ANIMATION_MAX_DELAY_FOR_ITEM;
-                    this._animateItem(items[index],
-                              this._animationOriginSize,
-                              [startX, startY],
-                              delay,
-                              index == items.length - 1);
-                    break;
-                case ANIMATION_TYPE_APPEAR:
-                    startX = finalX;
-                    startY = finalY;
-                    log("index " + index);
-                    log("items lenght " + items.length);
-                    delay = parseFloat(index) / items.length * ANIMATION_MAX_DELAY_FOR_ITEM;
-                    this._animateItemAppear(items[index],
-                                            0,
-                                            delay,
-                                            index == items.length - 1);
-                    break;
-                default:
-                    startX = finalX;
-                    startY = finalY;
-                    delay = 0;
-                    this._animateItem(items[index],
-                              this._animationOriginSize,
-                              [startX, startY],
-                              delay,
-                              index == items.length - 1);
-                    break;
-            }          
+
+            let itemClone = items[index].clone();
+            Main.uiGroup.add_actor(itemClone.actor);
+
+            itemClone.actor.reactive = false;
+            //itemClone.actor.set_size(startSize, startSize);
+            itemClone.actor.set_position(startPosition[0], startPosition[1]);
+            itemClone.actor.opacity = 0;
+
+            // Defeat onComplete anonymous function closure
+            let item = items[index];
+            let isLastItem = index == items.length - 1;
+            Tweener.addTween(itemClone.actor,
+                             { time: ANIMATION_TIME_IN,
+                               transition: 'easeInOutQuad',
+                               delay: delay,
+                               x: finalX,
+                               y: finalY,
+                               onComplete: Lang.bind(this, function() {
+                                    if (isLastItem)
+                                        this._animating = false;
+                                    item.actor.opacity = 255;
+                                    itemClone.actor.destroy();
+                                })});
+
+            Tweener.addTween(itemClone.actor,
+                             { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
+                               transition: 'easeInOutQuad',
+                               delay: delay,
+                               opacity: 255 });
         }
     },
 
@@ -458,128 +626,6 @@ const IconGrid = new Lang.Class({
         return [target[0] - item[0], target[1] - item[1]];
     },
 
-    _animateItemAppear: function(item, startSize, delay, isLastItem) {
-        let itemClone = item.clone();
-        let [originalX, originalY] = item.actor.get_transformed_position();
-        let [originalWidth, originalHeight] = item.actor.get_transformed_size();
-        item.actor.opacity = 0;
-
-        Main.uiGroup.add_actor(itemClone.actor);
-
-        itemClone.actor.reactive = false;
-        itemClone.actor.set_position(originalX, originalY);
-        itemClone.icon.icon.set_size(0, 0);
-        // Force to use the current size, so the label and the container
-        // of the actor doesnn't resize while the icon texture is 
-        // animating. That avoids to see the label wrapping the text and
-        // also avoids the container to be positioned top left while animating instead
-        // of center.
-        itemClone.actor.set_size(originalWidth, originalHeight);
-
-        let originalIconSize = itemClone.icon.iconSize;
-        /*Tweener.addTween(itemClone.icon.icon,
-                         { time: ANIMATION_TIME,
-                           transition: 'easeOutBack',
-                           delay: delay,
-                           width: originalIconSize,
-                           height: originalIconSize,
-                           onComplete: Lang.bind(this, function() {
-                                if (isLastItem)
-                                    this._animating = false;
-                                item.actor.opacity = 255;
-                                itemClone.actor.destroy();
-                            })});*/
-
-        Tweener.addTween(itemClone.icon.icon,
-                        { time: ANIMATION_TIME_TYPE_APPEAR / 4,
-                          transition: 'easeInOutQuad',
-                          delay: delay,
-                          width: originalIconSize * ANIMATION_APPEAR_ICON_SCALE,
-                          height: originalIconSize * ANIMATION_APPEAR_ICON_SCALE,
-                          onComplete: Lang.bind(this, function() {
-                              Tweener.addTween(itemClone.icon.icon,
-                                               { time: ANIMATION_TIME_TYPE_APPEAR - 
ANIMATION_TIME_TYPE_APPEAR / 4,
-                                                 transition: 'easeInOutQuad',
-                                                 width: originalIconSize,
-                                                 height: originalIconSize,
-                                                 onComplete: Lang.bind(this, function() {
-                                                    if (isLastItem)
-                                                        this._animating = false;
-                                                    item.actor.opacity = 255;
-                                                    itemClone.actor.destroy();
-                                                })
-                                               });
-                          })
-                        });
-    },
-
-    _animateItem: function(item, size, originPosition, delay, isLastItem) {
-        let itemClone = item.clone();
-        let [originalWidth, originalHeight] = item.actor.get_transformed_size();
-        let [iconWidth, iconHeight] = item.icon._iconBin.get_transformed_size();
-        let [originalX, originalY] = item.actor.get_transformed_position();
-        item.actor.opacity = 0;
-
-        Main.uiGroup.add_actor(itemClone.actor);
-
-        itemClone.actor.reactive = false;
-        itemClone.actor.set_size(originalWidth, originalHeight);
-        //itemClone.icon._iconBin.set_size(iconWidth, iconHeight);
-        itemClone.actor.set_position(originPosition[0], originPosition[1]);
-        itemClone.actor.opacity = 0;
-
-        /*
-        itemClone.actor.save_easing_state();
-        itemClone.icon._iconBin.save_easing_state();
-
-        itemClone.actor.set_easing_duration(ANIMATION_TIME * 3);
-        itemClone.actor.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
-        itemClone.actor.set_easing_delay(delay);
-        itemClone.icon._iconBin.set_easing_delay(delay);
-        itemClone.actor.set_position(originalX, originalY);
-        itemClone.actor.set_opacity(255);
-
-        if (this._animationType == ANIMATION_TYPE_APPEAR) {
-            itemClone.icon._iconBin.set_easing_mode(Clutter.AnimationMode.EASE_OUT_BACK);
-            itemClone.actor.set_easing_mode(Clutter.AnimationMode.EASE_OUT_BACK);
-        } else {
-            itemClone.icon._iconBin.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
-        }
-        itemClone.icon._iconBin.set_size(300-20, 300-20);
-        itemClone.actor.set_size(300, 300);
-
-        itemClone.actor.restore_easing_state();
-        itemClone.icon._iconBin.restore_easing_state();
-
-        itemClone.actor.connect('transition-stopped::', Lang.bind(this,
-            function(a, n, completed) {
-                if (isLastItem)
-                    this._animating = false;
-                item.actor.opacity = 255;
-                itemClone.actor.destroy();                
-           }));
-        */
-
-        Tweener.addTween(itemClone.actor,
-                         { time: ANIMATION_TIME,
-                           transition: 'easeInOutQuad',
-                           delay: delay,
-                           x: originalX,
-                           y: originalY,
-                           onComplete: Lang.bind(this, function() {
-                                if (isLastItem)
-                                    this._animating = false;
-                                item.actor.opacity = 255;
-                                itemClone.actor.destroy();
-                            })});
-
-        Tweener.addTween(itemClone.actor,
-                         { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
-                           transition: 'easeInOutQuad',
-                           delay: delay,
-                           opacity: 255 });
-    },
-
     _calculateChildBox: function(child, x, y, box) {
         let [childMinWidth, childMinHeight, childNaturalWidth, childNaturalHeight] =
              child.get_preferred_size();
@@ -856,12 +902,8 @@ const PaginatedIconGrid = new Lang.Class({
         }
     },
 
-    animateIn: function(origin, originSize, animationType) {
-        this._animationOrigin = origin;
-        this._animationOriginSize = originSize;
-        this._animationType = animationType;
-
-        this._animateInReal(this._getItemsInPage(0));
+    animate: function(animationType, animationDirection, params) {
+        this._animateReal(this._getItemsInPage(0), animationType, animationDirection, params);
     },
 
     _computePages: function (availWidthPerPage, availHeightPerPage) {
diff --git a/js/ui/viewSelector.js b/js/ui/viewSelector.js
index 15d0906..a5f0a9e 100644
--- a/js/ui/viewSelector.js
+++ b/js/ui/viewSelector.js
@@ -19,6 +19,7 @@ const Search = imports.ui.search;
 const ShellEntry = imports.ui.shellEntry;
 const Tweener = imports.ui.tweener;
 const WorkspacesView = imports.ui.workspacesView;
+const IconGrid = imports.ui.iconGrid;
 
 const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
 
@@ -211,10 +212,11 @@ const ViewSelector = new Lang.Class({
             oldPage.hide();
 
         this.emit('page-empty');
+        log("animation in " + this._activePage);
         if (this._activePage == this._appsPage) {
             this._activePage.opacity = 255;
             this._activePage.show();
-            this.appDisplay.animateIn();
+            this.appDisplay.animate(IconGrid.ANIMATION_DIRECTION_IN);
         } else {
             this._activePage.show();
             Tweener.addTween(this._activePage,
@@ -232,19 +234,33 @@ const ViewSelector = new Lang.Class({
         let oldPage = this._activePage;
         this._activePage = page;
         this.emit('page-changed');
-
-        if (oldPage && !noFade)
-            Tweener.addTween(oldPage,
-                             { opacity: 0,
-                               time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
-                               transition: 'easeOutQuad',
-                               onComplete: Lang.bind(this,
-                                   function() {
-                                       this._fadePageIn(oldPage);
-                                   })
-                             });
-        else
-            this._fadePageIn(oldPage);
+        log("animation out " + oldPage);
+        if (oldPage && !noFade) {
+            if (oldPage == this._appsPage) {
+                this.appDisplay.animate(IconGrid.ANIMATION_DIRECTION_OUT);
+                let time = IconGrid.ANIMATION_TIME_OUT + IconGrid.ANIMATION_MAX_DELAY_OUT_FOR_ITEM * 
St.get_slow_down_factor();
+                Mainloop.timeout_add(time * 1000, Lang.bind(this, function() { this._fadePageIn(oldPage); 
return GLib.SOURCE_REMOVE; }));
+            } else {
+                Tweener.addTween(oldPage,
+                                 { opacity: 0,
+                                   time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
+                                   transition: 'easeOutQuad',
+                                   onComplete: Lang.bind(this,
+                                       function() {
+                                           this._fadePageIn(oldPage);
+                                       })
+                                 });
+            }
+        }
+        else {
+            if (oldPage == this._appsPage) {
+                this.appDisplay.animate(IconGrid.ANIMATION_DIRECTION_OUT);
+                let time = IconGrid.ANIMATION_TIME_OUT + IconGrid.ANIMATION_MAX_DELAY_OUT_FOR_ITEM * 
St.get_slow_down_factor();
+                Mainloop.timeout_add(time * 1000, Lang.bind(this, function() { this._fadePageIn(oldPage); 
return GLib.SOURCE_REMOVE; }));
+            } else {
+                this._fadePageIn(oldPage);
+            }
+        }
 
         /*if (this._activePage == this._appsPage)
             this.appDisplay.animateIn();*/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]