[gnome-shell/wip/swarm: 51/51] nn



commit 63ad4d367e69a042f6f0e0f283420d9fbe629d29
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Mon Jun 9 21:30:29 2014 +0200

    nn

 js/ui/appDisplay.js   |   66 ++++++-------
 js/ui/iconGrid.js     |  266 +++++++++++++++++++++++++++++++++----------------
 js/ui/viewSelector.js |   23 +++--
 3 files changed, 225 insertions(+), 130 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 9861835..285df9d 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -144,7 +144,7 @@ const BaseAppView = new Lang.Class({
         return a.name.localeCompare(b.name);
     },
     
-    animateIn: function(origin, animationType) {
+    animateIn: function(origin, originSize, animationType) {
         throw new Error('Not implemented');
     },
     
@@ -445,10 +445,13 @@ const AllView = new Lang.Class({
         this._refilterApps();
     },
     
-    animateIn: function(origin, animationType) {
-        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
+    animateIn: function(origin, originSize, animationType) {
+        let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
             function() {
-                this._grid.animateIn(origin, animationType);
+                if (this._grid.actor.mapped) {
+                    this._grid.actor.disconnect(toAnimate);
+                    this._grid.animateIn(origin, originSize, animationType);
+                }
             }));
     },
     
@@ -698,10 +701,13 @@ const FrequentView = new Lang.Class({
         }
     },
     
-    animateIn: function(origin, animationType) {
-        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
+    animateIn: function(origin, originSize, animationType) {
+        let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
             function() {
-                this._grid.animateIn(origin, animationType);
+                if (this._grid.actor.mapped) {
+                    this._grid.actor.disconnect(toAnimate);
+                    this._grid.animateIn(origin, originSize, animationType);
+                }
             }));
     },
     
@@ -829,29 +835,14 @@ const AppDisplay = new Lang.Class({
             initialView = Views.ALL;
         this._showView(initialView);
         this._updateFrequentVisibility();
-        
-        // ViewSelector null in Main.overview, so we can't connect to page-changed
-        // signal. Manage all from view selector for now calling swamAnimation
-        /*
-        log(Main);
-        log(Main.overview);
-        log(Main.overview.viewSelector);
-        Main.overview.viewSelector.connect('page-changed', Lang.bind(this,
-            function() {
-                if (Main.overview.viewSelector.getActivePage() == ViewSelector.ViewPage.APPS) {
-                    this._views[global.settings.get_uint('app-picker-view')].swarmAnimation();
-                }
-            }));
-            */
     },
     
     animateIn: function() {
-        log("appDisplay");
-        log(this._views);
         let view = this._views[global.settings.get_uint('app-picker-view')].view;
-        log(view);
+        log("size " + Main.overview._dash._showAppsIcon.get_transformed_size());
         view.animateIn(Main.overview._dash._showAppsIcon.get_transformed_position(),
-                       IconGrid.ANIMATION_SWARM_FAR_FIRST);
+                       Main.overview._dash._showAppsIcon.get_transformed_size(),
+                       IconGrid.ANIMATION_TYPE_SWARM_FAR_FIRST);
     },
 
     _showView: function(activeIndex) {
@@ -983,7 +974,7 @@ const FolderView = new Lang.Class({
     Extends: BaseAppView,
 
     _init: function() {
-        this.parent(null, { animation: IconGrid.ANIMATION_APPEAR });
+        this.parent(null, { animation: IconGrid.ANIMATION_TYPE_APPEAR });
         // If it not expand, the parent doesn't take into account its preferred_width when allocating
         // the second time it allocates, so we apply the "Standard hack for ClutterBinLayout"
         this._grid.actor.x_expand = true;
@@ -1003,13 +994,8 @@ const FolderView = new Lang.Class({
         Util.ensureActorVisibleInScrollView(this.actor, actor);
     },
     
-    animateIn: function(origin, animationType) {
-        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
-            function() {
-                this._grid.animateIn(origin, animationType);
-            }));
-        
-        log("FolderView in");
+    animateIn: function(origin, originSize, animationType) {
+        this._grid.animateIn(origin, originSize, animationType);
     },
     
      animateOut: function(origin, animationType) {
@@ -1354,10 +1340,20 @@ const AppFolderPopup = new Lang.Class({
         this.actor.show();
 
         this._boxPointer.setArrowActor(this._source.actor);
-        this._boxPointer.show(BoxPointer.PopupAnimation.SLIDE, Lang.bind(this, 
+        // 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,
+                              Lang.bind(this, 
             function() {
+                // 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(),
-                                     IconGrid.ANIMATION_SWARM_FAR_FIRST);
+                                     this._source.actor.get_transformed_size(),
+                                     IconGrid.ANIMATION_TYPE_APPEAR);
             }));
 
         this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index a39f5a5..23aa2a5 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -17,14 +17,18 @@ const MIN_ICON_SIZE = 16;
 
 const EXTRA_SPACE_ANIMATION_TIME = 0.25;
 
-const SWARM_ANIMATION_TIME = 0.5;
-const SWARM_ANIMATION_MAX_DELAY_FOR_ITEM = 0.3;
-const SWARM_ANIMATION_FADE_IN_TIME_FOR_ITEM = 0.1;
+const ANIMATION_TIME = 0.400;
+const ANIMATION_MAX_DELAY_FOR_ITEM = 0.250;
+const ANIMATION_FADE_IN_TIME_FOR_ITEM = 0.100;
+
+const ANIMATION_TIME_TYPE_APPEAR = 0.400;
+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_NONE = 0;
-const ANIMATION_APPEAR = 1;
-const ANIMATION_SWARM_RANDOM = 2;
-const ANIMATION_SWARM_FAR_FIRST = 3;
 
 const BaseIcon = new Lang.Class({
     Name: 'BaseIcon',
@@ -35,7 +39,7 @@ const BaseIcon = new Lang.Class({
                                         showLabel: true });
         this.labelForClone = label;
         this.paramsForClone = params;
-        
+
         let styleClass = 'overview-icon';
         if (params.showLabel)
             styleClass += ' overview-icon-with-label';
@@ -199,7 +203,7 @@ const IconGrid = new Lang.Class({
                                         fillParent: false,
                                         xAlign: St.Align.MIDDLE,
                                         padWithSpacing: false,
-                                        animation: ANIMATION_NONE });
+                                        animation: ANIMATION_TYPE_NONE });
         this._rowLimit = params.rowLimit;
         this._colLimit = params.columnLimit;
         this._minRows = params.minRows;
@@ -230,14 +234,9 @@ const IconGrid = new Lang.Class({
         this._grid.connect('allocate', Lang.bind(this, this._allocate));
         this._grid.connect('actor-added', Lang.bind(this, this._childAdded));
         this._grid.connect('actor-removed', Lang.bind(this, this._childRemoved));
-        
+
         this._paintedItems = [];
         this._animating = false;
-        /*this._mappedId = this.actor.connect("notify::allocated", Lang.bind(this, 
-                function() {
-                    if (this.actor.mapped)
-                        this._animateInReal(this._paintedItems);
-                }));*/
     },
 
     _keyFocusIn: function(actor) {
@@ -279,12 +278,12 @@ const IconGrid = new Lang.Class({
     },
 
     _getVisibleItems: function() {;
-        items = this._items.filter(function(item) {
+        let items = this._items.filter(function(item) {
             return item.actor.visible;
         });
         return items;
     },
-    
+
     _getPaintedItems: function() {;
         return this._paintedItems;
     },
@@ -373,35 +372,32 @@ const IconGrid = new Lang.Class({
             }
         }
     },
-    
-        
-    animateIn: function(origin, animationType) {
-        this._animateInNextAllocation = true;
+
+
+    animateIn: function(origin, originSize, animationType) {
         this._animationOrigin = origin;
+        this._animationOriginSize = originSize;
         this._animationType = animationType;
+
         this._animateInReal(this._paintedItems);
-        log("Animating in");
     },
 
     _animateInReal: function(items) {
-        log("animate real " + this._animateInNextAllocation + " " + this._animating);
-        if (!this._animateInNextAllocation)
-            return;
-
-        this._animateInNextAllocation = false;
         log("items " + items.length);
         if (this._animating || items.length == 0)
             return;
+
         log("animating real to be done");
         this._animating = true;
-        let [startX, startY] = this._animationOrigin;
+
         let distances = items.map(Lang.bind(this, function(item) {
-            return this._distance(item.actor.get_transformed_position(), [startX, startY]);
+            return this._distance(item.actor.get_transformed_position(), this._animationOrigin);
         }));
-        
+
         let delay;
-        let normalization = Math.max.apply(Math, distances);
-        
+        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.
@@ -409,68 +405,179 @@ const IconGrid = new Lang.Class({
             items[index].actor.opacity = 0;
             let [finalX, finalY] = items[index].actor.get_transformed_position();
             switch (this._animationType) {
-                case ANIMATION_SWARM_FAR_FIRST:
-                    let distance = this._distance([startX, startY], [finalX, finalY]);
+                case ANIMATION_TYPE_SWARM_FAR_FIRST:
                     [startX, startY] = this._animationOrigin;
-                    delay = (1 - this._distance([startX, startY], [finalX, finalY]) / normalization) * 
SWARM_ANIMATION_MAX_DELAY_FOR_ITEM;
+                    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_SWARM_RANDOM:
+                case ANIMATION_TYPE_SWARM_RANDOM:
                     [startX, startY] = this._animationOrigin;
-                    delay = Math.random() * SWARM_ANIMATION_MAX_DELAY_FOR_ITEM;
+                    delay = Math.random() * ANIMATION_MAX_DELAY_FOR_ITEM;
+                    this._animateItem(items[index],
+                              this._animationOriginSize,
+                              [startX, startY],
+                              delay,
+                              index == items.length - 1);
                     break;
-                case ANIMATION_APPEAR:
+                case ANIMATION_TYPE_APPEAR:
                     startX = finalX;
                     startY = finalY;
-                    delay = 0;
+                    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], [startX, startY], [finalX, finalY], delay);
+                    this._animateItem(items[index],
+                              this._animationOriginSize,
+                              [startX, startY],
+                              delay,
+                              index == items.length - 1);
+                    break;
+            }          
         }
     },
-    
+
     _distance: function(point1, point2) {
         let x = point1[0] - point2[0];
         let y = point1[1] - point2[1];
         return Math.sqrt(x * x + y * y);
     },
 
-    _animateItem: function(item, origin, target, delay) {
+    _translation: function(item, target) {
+        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;
-        let [width, height] = item.actor.get_transformed_size();
-        itemClone.actor.set_size(width, height);
+        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();
+                            })});*/
 
-        itemClone.actor.set_position(origin[0], origin[1]);
-        itemClone.actor.opacity = 0;
-        
-        Tweener.addTween(itemClone.actor,
-                        { x: target[0],
-                          y: target[1],
-                          time: SWARM_ANIMATION_TIME,
+        Tweener.addTween(itemClone.icon.icon,
+                        { time: ANIMATION_TIME_TYPE_APPEAR / 4,
                           transition: 'easeInOutQuad',
                           delay: delay,
-                          onStart: function() {
-                              Tweener.addTween(itemClone.actor,
-                                               { opacity : 255,
-                                                 transition: 'easeInOutQuad',
-                                                 time: SWARM_ANIMATION_FADE_IN_TIME_FOR_ITEM });
-                            },
+                          width: originalIconSize * ANIMATION_APPEAR_ICON_SCALE,
+                          height: originalIconSize * ANIMATION_APPEAR_ICON_SCALE,
                           onComplete: Lang.bind(this, function() {
-                                item.actor.opacity = 255;
-                                itemClone.actor.destroy();
-                                // FIXME: Assume the random value of delay is not important,
-                                // and setting animating to true in the first finished
-                                // animation is fine.
-                                this._animating = false;
-                            })
+                              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) {
@@ -688,18 +795,6 @@ const PaginatedIconGrid = new Lang.Class({
         this._rowsPerPage = 0;
         this._spaceBetweenPages = 0;
         this._childrenPerPage = 0;
-        
-        log("#####################");
-        log("Already mappedId? " + this._mappedId);
-        /*this.actor.disconnect(this._mappedId);
-        this._mappedId = this.actor.connect("notify::allocated", Lang.bind(this, 
-                function() {
-                    if (this.actor.mapped) {
-                        let items = this._getItemsInPage(0);
-                        log("jsut before " + items.length);
-                        this._animateInReal(items);
-                    }
-                })); */
     },
 
     _getPreferredHeight: function (grid, forWidth, alloc) {
@@ -760,14 +855,13 @@ const PaginatedIconGrid = new Lang.Class({
                 x += this._getHItemSize() + spacing;
         }
     },
-    
-   _animateInReal: function(items) {
-        log("secundario " + this._getItemsInPage(0).length);
-        log("Animating paginated. Items " + items.length);
-        // FIXME
-        if (items.length == 0)
-            return;
-        this.parent(items);
+
+    animateIn: function(origin, originSize, animationType) {
+        this._animationOrigin = origin;
+        this._animationOriginSize = originSize;
+        this._animationType = animationType;
+
+        this._animateInReal(this._getItemsInPage(0));
     },
 
     _computePages: function (availWidthPerPage, availHeightPerPage) {
diff --git a/js/ui/viewSelector.js b/js/ui/viewSelector.js
index 941eaf4..15d0906 100644
--- a/js/ui/viewSelector.js
+++ b/js/ui/viewSelector.js
@@ -211,13 +211,18 @@ const ViewSelector = new Lang.Class({
             oldPage.hide();
 
         this.emit('page-empty');
-
-        this._activePage.show();
-        Tweener.addTween(this._activePage,
-            { opacity: 255,
-              time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
-              transition: 'easeOutQuad'
-            });
+        if (this._activePage == this._appsPage) {
+            this._activePage.opacity = 255;
+            this._activePage.show();
+            this.appDisplay.animateIn();
+        } else {
+            this._activePage.show();
+            Tweener.addTween(this._activePage,
+                { opacity: 255,
+                  time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
+                  transition: 'easeOutQuad'
+                });
+        }
     },
 
     _showPage: function(page, noFade) {
@@ -241,8 +246,8 @@ const ViewSelector = new Lang.Class({
         else
             this._fadePageIn(oldPage);
 
-        if (this._activePage == this._appsPage)
-            this.appDisplay.animateIn();
+        /*if (this._activePage == this._appsPage)
+            this.appDisplay.animateIn();*/
     },
 
     _a11yFocusPage: function(page) {


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