[gnome-shell/wip/paging-release: 10/38] Creating new implementation of icongrid for spacing etc



commit 251e9804aece5f59500ec5b50d4205a321fdf7b3
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Fri Jun 28 19:39:29 2013 +0200

    Creating new implementation of icongrid for spacing etc
    
    test
    
    iconGrid: Spacing calculated fine with queue_relayout. Parent size from
    a variable. Update pages with a signal.
    appDisplay: Erase some custom allocations.
    
    appDisplay: really fix spacing
    
    apDisplay: clean up
    
    IconGrid: relayout if pages diferent
    
    Fixed RTL languages
    
    PAginationScroll with custom allocate. Allview with onyl stBin
    
    Calculation of spacing of the grid in parents
    
    t
    
    Calculation os spacing on each iconGrid parent
    
    spacing calculated on AppDisplay
    
    Spacing dynamic without hanging, using Clutter.BoxLayout instead of
    St.BoxLayout, since the last has some bug overriding the allocate
    function
    
    Fixed icongrid outside allocation
    
    Erased duplciated folder view
    
    FolderView adapts spacing.
    TODO:
    FolderView
    -set always the same width, the one of the parent
    -Fix the Side calculation of the arrow at fodlerView, since now it takes
    into account all the grid height. Maybe the best solution is knowing the
    parent height, with the updateSpacing(width), but with a
    updatedParentSize(width, height) and use that to calculate spacing and
    side of the arrow.
    
    popup aligned
    
    FolderView gets boxpointer padding from CSS
    
    appDisplay: Collections box pointer side calculation fixed using stage
    position
    
    FolderView/icon: clean up API
    
    Substract some padding from top, since we have now some spacing on the
    surrounding main grid

 data/theme/gnome-shell.css |    3 +-
 js/ui/appDisplay.js        |  612 +++++++++++++++++++++++++++++---------------
 js/ui/boxpointer.js        |    2 +-
 js/ui/iconGrid.js          |  222 ++++++++--------
 4 files changed, 515 insertions(+), 324 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index e08b954..7b65207 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -881,7 +881,6 @@ StScrollBar StButton#vhandle:active {
 }
 
 .app-display {
-    padding: 8px;
     spacing: 20px;
 }
 
@@ -902,7 +901,7 @@ StScrollBar StButton#vhandle:active {
 .all-apps,
 .frequent-apps > StBoxLayout{
     /* horizontal padding to make sure scrollbars or dash don't overlap content */
-    padding: 10px 88px;
+    padding: 0px 88px 10px 88px;
 }
 
 .pages-indicator {
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 864532a..14346ea 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -32,6 +32,7 @@ const MENU_POPUP_TIMEOUT = 600;
 const MAX_COLUMNS = 6;
 
 const INACTIVE_GRID_OPACITY = 77;
+const INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.15;
 const FOLDER_SUBICON_FRACTION = .4;
 
 const MAX_APPS_PAGES = 20;
@@ -118,86 +119,6 @@ const AlphabeticalView = new Lang.Class({
     }
 });
 
-const FolderView = new Lang.Class({
-    Name: 'FolderView',
-
-    _init: function() {
-        this._grid = new IconGrid.IconGrid({ xAlign: St.Align.MIDDLE,
-            columnLimit: MAX_COLUMNS });
-     
-        this.actor = this._grid.actor;
-        // Standard hack for ClutterBinLayout
-        this._grid.actor.x_expand = true;
-
-        this._items = {};
-        this._allItems = [];
-    },
-
-    _getItemId: function(item) {
-        return item.get_id();
-    },
-
-    _createItemIcon: function(item) {
-        return new AppIcon(item);
-    },
-
-    _compareItems: function(a, b) {
-        return a.compare_by_name(b);
-    },
-
-    addApp: function(app) {
-        this._addItem(app);
-    },
-
-    createFolderIcon: function(size) {
-        let icon = new St.Widget({ layout_manager: new Clutter.BinLayout(),
-                                   style_class: 'app-folder-icon',
-                                   width: size, height: size });
-        let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size);
-
-        let aligns = [ Clutter.ActorAlign.START, Clutter.ActorAlign.END ];
-        for (let i = 0; i < Math.min(this._allItems.length, 4); i++) {
-            let texture = this._allItems[i].create_icon_texture(subSize);
-            let bin = new St.Bin({ child: texture,
-                                   x_expand: true, y_expand: true });
-            bin.set_x_align(aligns[i % 2]);
-            bin.set_y_align(aligns[Math.floor(i / 2)]);
-            icon.add_actor(bin);
-        }
-
-        return icon;
-    },
-    
-    removeAll: function() {
-        this._grid.removeAll();
-        this._items = {};
-        this._allItems = [];
-    },
-
-    _addItem: function(item) {
-        let id = this._getItemId(item);
-        if (this._items[id] !== undefined)
-            return null;
-
-        let itemIcon = this._createItemIcon(item);
-        this._allItems.push(item);
-        this._items[id] = itemIcon;
-
-        return itemIcon;
-    },
-
-    loadGrid: function() {
-        this._allItems.sort(this._compareItems);
-
-        for (let i = 0; i < this._allItems.length; i++) {
-            let id = this._getItemId(this._allItems[i]);
-            if (!id)
-                continue;
-            this._grid.addItem(this._items[id].actor);
-        }
-    }
-});
-
 const AppPages = new Lang.Class({
     Name: 'AppPages',
     Extends: AlphabeticalView,
@@ -206,6 +127,7 @@ const AppPages = new Lang.Class({
         this.parent();
         this.actor = this._grid.actor;
         this._parent = parent;
+        this._folderIcons = [];
     },
 
     _getItemId: function(item) {
@@ -220,9 +142,11 @@ const AppPages = new Lang.Class({
     _createItemIcon: function(item) {
         if (item instanceof Shell.App)
             return new AppIcon(item);
-        else if (item instanceof GMenu.TreeDirectory)
-            return new FolderIcon(item, this);
-        else
+        else if (item instanceof GMenu.TreeDirectory) {
+            let folderIcon = new FolderIcon(item, this);
+            this._folderIcons.push(folderIcon);
+            return folderIcon;
+        } else
             return null;
     },
 
@@ -233,7 +157,26 @@ const AppPages = new Lang.Class({
         let nameB = GLib.utf8_collate_key(itemB.get_name(), -1);
         return (nameA > nameB) ? 1 : (nameA < nameB ? -1 : 0);
     },
-   
+    
+    updateIconOpacities: function(folderOpen) {
+        for (let id in this._items) {
+            if (folderOpen && !this._items[id].actor.checked) {
+                let params = { opacity: INACTIVE_GRID_OPACITY,
+                        time: INACTIVE_GRID_OPACITY_ANIMATION_TIME,
+                        transition: 'easeOutQuad'
+                       };
+                Tweener.addTween(this._items[id].actor, params);
+            }
+            else {
+                let params = { opacity: 255,
+                        time: INACTIVE_GRID_OPACITY_ANIMATION_TIME,
+                        transition: 'easeOutQuad'
+                       };
+                Tweener.addTween(this._items[id].actor, params);
+            }
+        }
+    },
+    
     addItem: function(item) {
         this._addItem(item);
     },
@@ -246,31 +189,65 @@ const AppPages = new Lang.Class({
         return this._grid.getPagePosition(pageNumber);
     },
     
-    setGridParentSize: function(size) {
-        this._grid._parentSize = size;
+    setViewForPageSize: function(view) {
+        this._grid._viewForPageSize= view;
     },
     
     addFolderPopup: function(popup) {
         this._parent.addFolderPopup(popup);
+    },
+    
+    removeAll: function() {
+        this._folderIcons = [];
+        this.parent();
+    },
+    
+    onUpdatedDisplaySize: function(width, height) {
+        let box = new Clutter.ActorBox();
+        box.x1 = 0;
+        box.x2 = width;
+        box.y1 = 0;
+        box.y2 = height;
+        box = this.actor.get_theme_node().get_content_box(box);
+        let availWidth = box.x2 - box.x1;
+        let availHeight = box.y2 - box.y1;
+        // Update grid dinamyc spacing based on display width
+        let spacing = this._grid.maxSpacingForWidthHeight(availWidth, availHeight, MIN_COLUMNS, MIN_ROWS, 
true);
+        this._grid.top_padding = spacing;
+        this._grid.bottom_padding = spacing;
+        this._grid.left_padding = spacing;
+        this._grid.right_padding = spacing;
+        this._grid.setSpacing(spacing);
+        // Update folder views
+        for(let id in this._folderIcons) {
+            this._folderIcons[id].onUpdatedDisplaySize(width, height);
+        }
     }
 });
+
 const PaginationScrollView = new Lang.Class({
     Name: 'PaginationScrollView',
-    Extends: St.ScrollView,
+    Extends: St.Bin,
     
-    _init: function(parent) {
-        this.parent();
+    _init: function(parent, params) {
+        params['reactive'] = true;
+        this.parent(params);
+        this._verticalAdjustment = new St.Adjustment();
+        this._horizontalAdjustment = new St.Adjustment();
+
         this._stack = new St.Widget({layout_manager: new Clutter.BinLayout()});        
         this._box = new St.BoxLayout({vertical: true});
         this._pages = new AppPages(this);
+        this._pages.setViewForPageSize(this);
         
         this._stack.add_actor(this._pages.actor);
         this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
         this._stack.add_actor(this._eventBlocker, {x_align:St.Align.MIDDLE});
         
         this._box.add_actor(this._stack);
+        this._box.set_adjustments(this._horizontalAdjustment, this._verticalAdjustment);
         this.add_actor(this._box);
-        
+
         this._currentPage = 0;
         this._parent = parent;
         
@@ -301,26 +278,10 @@ const PaginationScrollView = new Lang.Class({
     },
 
    vfunc_get_preferred_height: function (forWidht) {
-        global.log(this.get_parent().allocation.y2 - this.get_parent().allocation.y1);
-        
-        let parentBox = this.get_parent().allocation;
-        let gridBox = this.get_theme_node().get_content_box(parentBox);
-        global.log("padding " + this.get_theme_node().get_length('padding'));
-        let availWidth = gridBox.x2 - gridBox.x1;
-        let availHeight = gridBox.y2 - gridBox.y1;
-        global.log("availWidth " + availWidth);
-        
-        global.log("availHeight " + availHeight);
-        
         return [0, 0];
     },
 
     vfunc_get_preferred_width: function(forHeight) {
-        let parentBox = this.get_parent().allocation;
-        let gridBox = this.get_theme_node().get_content_box(parentBox);
-        global.log("padding " + this.get_theme_node().get_length('padding'));
-        let availWidth = gridBox.x2 - gridBox.x1;
-        let availHeight = gridBox.y2 - gridBox.y1;
         return [0, 0];
     },
 
@@ -330,40 +291,14 @@ const PaginationScrollView = new Lang.Class({
         let availWidth = box.x2 - box.x1;
         let availHeight = box.y2 - box.y1;
         let childBox = new Clutter.ActorBox();
-        // Get the boxLayout inside scrollView
-        let child = this.get_children()[2];
-        childBox.x1 = 0;
-        childBox.y1 = 0;
-        childBox.x2 = availWidth;
-        childBox.y2 = availHeight;   
-
-        child.allocate(childBox, flags);
-    },
-
-    vfunc_get_preferred_height: function (container, forWidht) {
-        return [0, 0];
-    },
-
-    vfunc_get_preferred_width: function(container, forHeight) {
-        return [0, 0];
-    },
-
-    vfunc_allocate: function(box, flags) {
-        box = this.get_parent().allocation;
-        this.set_allocation(box, flags);        
-        let availWidth = box.x2 - box.x1;
-        let availHeight = box.y2 - box.y1;
-        
-        let childBox = new Clutter.ActorBox();
-        // Get the boxLayout inside scrollView
-        let child = this.get_children()[2];
         childBox.x1 = 0;
         childBox.y1 = 0;
         childBox.x2 = availWidth;
         childBox.y2 = availHeight;   
+        this._box.allocate(childBox, flags);
         
-        this._pages.setGridParentSize([availWidth, availHeight]);
-        child.allocate(childBox, flags);
+        this._verticalAdjustment.page_size = availHeight;
+        this._verticalAdjustment.upper = this._stack.height;
     },
 
     goToPage: function(pageNumber, action) {
@@ -398,7 +333,7 @@ const PaginationScrollView = new Lang.Class({
                            time: time,
                            transition: 'easeOutQuad'
                           };
-            Tweener.addTween(this.vscroll.adjustment, params);
+            Tweener.addTween(this._verticalAdjustment, params);
         }
     },
 
@@ -411,7 +346,7 @@ const PaginationScrollView = new Lang.Class({
     },
 
     _diffToPage: function (pageNumber) {
-        let currentScrollPosition = this.vscroll.adjustment.value;
+        let currentScrollPosition = this._verticalAdjustment.value;
         return Math.abs(currentScrollPosition - this._pages._grid.getPagePosition(pageNumber)[1]);
     },
 
@@ -456,23 +391,14 @@ const PaginationScrollView = new Lang.Class({
                 function(popup, isOpen) {
                     this._eventBlocker.reactive = isOpen;
                     this._currentPopup = isOpen ? popup : null;
-                    this._updateIconOpacities(isOpen);
+                    this._pages.updateIconOpacities(isOpen);
                 }));
     },
-
-    _updateIconOpacities: function(folderOpen) {
-        for (let id in this._items) {
-            if (folderOpen && !this._items[id].actor.checked)
-                this._items[id].actor.opacity = INACTIVE_GRID_OPACITY;
-            else
-                this._items[id].actor.opacity = 255;
-        }
-    },
     
     _onPan: function(action) {
         this._clickAction.release();
         let [dist, dx, dy] = action.get_motion_delta(0);
-        let adjustment = this.vscroll.adjustment;
+        let adjustment = this._verticalAdjustment;
         adjustment.value -= (dy / this.height) * adjustment.page_size;
         return false;
     },
@@ -487,6 +413,18 @@ const PaginationScrollView = new Lang.Class({
             }
         } else
             this._parent.goToPage(this._currentPage, action);
+    },
+    
+    onUpdatedDisplaySize: function(width, height) {
+        let box = new Clutter.ActorBox();
+        box.x1 = 0;
+        box.x2 = width;
+        box.y1 = 0;
+        box.y2 = height;
+        box = this.get_theme_node().get_content_box(box);
+        let availWidth = box.x2 - box.x1;
+        let availHeight = box.y2 - box.y1;
+        this._pages.onUpdatedDisplaySize(availWidth, availHeight);
     }
     
 });
@@ -593,7 +531,7 @@ const PaginationIndicator = new Lang.Class({
         if(this._styleChangedId) {
             this._container.disconnect(this._styleChangedId);
             this._styleChangedId = 0;
-        }
+        }        
         if(container != null)
             this._styleChangedId = container.connect('style-changed', Lang.bind(this,
                     function() { this.spacing = this._container.get_theme_node().get_length('spacing'); }));
@@ -611,8 +549,8 @@ const AllView = new Lang.Class({
         this._paginationIndicator = new PaginationIndicator({style_class: 'pages-indicator'});
         this._paginationIndicator._nPages = 0;
         let layout = new Clutter.BinLayout();
-        this.actor = new Shell.GenericContainer({ layout_manager: layout, 
-                                                  x_expand:true, y_expand:true });
+        this.actor = new St.Widget({ layout_manager: layout, 
+                                     x_expand:true, y_expand:true });
         layout.add(this._paginationView, 2,2);
         if(Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
             layout.add(this._paginationIndicator.actor, 2,2);
@@ -625,26 +563,8 @@ const AllView = new Lang.Class({
             }
             this._paginationIndicator.actor.add_actor(indicatorIcon.actor);
         }
-        this.actor.connect('allocate', Lang.bind(this, this._allocate));
-    },
 
-    _allocate: function(widget, box, flags) {
-        let children = this.actor.get_children();
-        this._paginationView.allocate(box, flags);
-        
-        let nPages = this._paginationView.nPages();
-        this._paginationIndicatorLayout._nPages = nPages;
-        let availWidth = box.x2 - box.x1;
-        let availHeight = box.y2 - box.y1;
-        let childBox = new Clutter.ActorBox();
-        let [minWidth, natWidth] = this._paginationIndicator.get_preferred_width(availHeight);
-        childBox.x1 = availWidth - natWidth;
-        childBox.x2 = availWidth;
-        childBox.y1 = 0;
-        childBox.y2 = availHeight;
-
-        this._paginationIndicator.allocate(childBox, flags);
-        
+        this._paginationView._pages._grid.connect('n-pages-changed', Lang.bind(this, this._updatedNPages));
     },
 
     _updatedNPages: function(iconGrid, nPages) {
@@ -681,10 +601,6 @@ const AllView = new Lang.Class({
          * Lang.bind(this, this._ensureIconVisible));
          */
     },
-
-    addFolderPopup: function(popup) {
-        this._paginationView.addFolderPopup(popup);
-    },
    
     removeAll: function() {
         this._paginationView._pages.removeAll();
@@ -790,6 +706,30 @@ const ControlsBoxLayout = Lang.Class({
     }
 });
 
+const AppDisplayActor = new Lang.Class({
+    Name: 'AppDisplayActor',
+    Extends: Clutter.BoxLayout,
+    
+    vfunc_allocate: function (actor, box, flags) {
+        let availWidth = box.x2 - box.x1;
+        let availHeight = box.y2 - box.y1;
+        this.emit('allocated-size-changed', availWidth, availHeight);
+        this.parent(actor, box, flags);
+    },
+    
+    vfunc_set_container: function(container) {
+        if(this._styleChangedId) {
+            this._container.disconnect(this._styleChangedId);
+            this._styleChangedId = 0;
+        }
+        if(container != null)
+            this._styleChangedId = container.connect('style-changed', Lang.bind(this,
+                    function() { this.spacing = this._container.get_theme_node().get_length('spacing'); }));
+        this._container = container;
+    }
+});
+Signals.addSignalMethods(AppDisplayActor.prototype);
+
 const AppDisplay = new Lang.Class({
     Name: 'AppDisplay',
 
@@ -825,21 +765,22 @@ const AppDisplay = new Lang.Class({
                                  x_expand: true });
         this._views[Views.ALL] = { 'view': view, 'control': button };
 
-        this.actor = new St.BoxLayout({ style_class: 'app-display',
-                                        vertical: true,
+        this.actor = new St.Widget({ style_class: 'app-display',
                                         x_expand: true, y_expand: true });
+        this._actorLayout = new AppDisplayActor({vertical: true});
+        this.actor.set_layout_manager(this._actorLayout);
+        this._actorLayout.connect('allocated-size-changed', Lang.bind(this, this._onUpdatedDisplaySize));
 
         this._viewStack = new St.Widget({ layout_manager: new Clutter.BinLayout(),
                                           x_expand: true, y_expand: true });
-        this.actor.add(this._viewStack, { expand: true });
-
+        //FIXME
+        this.actor.add_actor(this._viewStack, { expand: true });
         let layout = new ControlsBoxLayout({ homogeneous: true });
         this._controls = new St.Widget({ style_class: 'app-view-controls',
                                          layout_manager: layout });
         layout.hookup_style(this._controls);
         this.actor.add_actor(new St.Bin({ child: this._controls }));
 
-
         for (let i = 0; i < this._views.length; i++) {
             this._viewStack.add_actor(this._views[i].view.actor);
             this._controls.add_actor(this._views[i].control);
@@ -858,9 +799,9 @@ const AppDisplay = new Lang.Class({
         // our real contents
         this._focusDummy = new St.Bin({ can_focus: true });
         this._viewStack.add_actor(this._focusDummy);
-
         this._allAppsWorkId = Main.initializeDeferredWork(this.actor, Lang.bind(this, 
this._redisplayAllApps));
         this._frequentAppsWorkId = Main.initializeDeferredWork(this.actor, Lang.bind(this, 
this._redisplayFrequentApps));
+        
     },
 
     _showView: function(activeIndex) {
@@ -941,9 +882,16 @@ const AppDisplay = new Lang.Class({
     },
     
     _onUpdatedDisplaySize: function(actor, width, height) {
-        //FIXME
+        let box = new Clutter.ActorBox();
+        box.x1 = 0;
+        box.x2 = width;
+        box.y1 = 0;
+        box.y2 = height;
+        box = this.actor.get_theme_node().get_content_box(box);
+        let availWidth = box.x2 - box.x1;
+        let availHeight = box.y2 - box.y1;
         for (let i = 0; i < this._views.length; i++) {
-            this._views[i].view.onUpdatedDisplaySize(width, height);
+            this._views[i].view.onUpdatedDisplaySize(availWidth, availHeight);
         }
     }
 });
@@ -1004,12 +952,150 @@ const AppSearchProvider = new Lang.Class({
     }
 });
 
+const FolderView = new Lang.Class({
+    Name: 'FolderView',
+
+    _init: function(parentView) {
+        this._grid = new IconGrid.IconGrid({ xAlign: St.Align.MIDDLE,
+            columnLimit: MAX_COLUMNS });
+        this._parentView = parentView;
+
+        this.actor = new St.ScrollView({overlay_scrollbars: true});
+        this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+        this._box = new St.BoxLayout({vertical:true, reactive: true});
+        this._widget = new St.Widget({layout_manager: new Clutter.BinLayout()});
+        this._widget.add_child(this._grid.actor);
+        this._box.add_actor(this._widget);
+        this.actor.add_actor(this._box);
+        this._items = {};
+        this._allItems = [];
+    },
+
+    _getItemId: function(item) {
+        return item.get_id();
+    },
+
+    _createItemIcon: function(item) {
+        return new AppIcon(item);
+    },
+
+    _compareItems: function(a, b) {
+        return a.compare_by_name(b);
+    },
+
+    addApp: function(app) {
+        this._addItem(app);
+    },
+
+    createFolderIcon: function(size) {
+        let icon = new St.Widget({ layout_manager: new Clutter.BinLayout(),
+                                   style_class: 'app-folder-icon',
+                                   width: size, height: size });
+        let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size);
+
+        let aligns = [ Clutter.ActorAlign.START, Clutter.ActorAlign.END ];
+        for (let i = 0; i < Math.min(this._allItems.length, 4); i++) {
+            let texture = this._allItems[i].create_icon_texture(subSize);
+            let bin = new St.Bin({ child: texture,
+                                   x_expand: true, y_expand: true });
+            bin.set_x_align(aligns[i % 2]);
+            bin.set_y_align(aligns[Math.floor(i / 2)]);
+            icon.add_actor(bin);
+        }
+
+        return icon;
+    },
+    
+    removeAll: function() {
+        this._grid.removeAll();
+        this._items = {};
+        this._allItems = [];
+    },
+
+    _addItem: function(item) {
+        let id = this._getItemId(item);
+        if (this._items[id] !== undefined)
+            return null;
+
+        let itemIcon = this._createItemIcon(item);
+        this._allItems.push(item);
+        this._items[id] = itemIcon;
+
+        return itemIcon;
+    },
+
+    loadGrid: function() {
+        this._allItems.sort(this._compareItems);
+
+        for (let i = 0; i < this._allItems.length; i++) {
+            let id = this._getItemId(this._allItems[i]);
+            if (!id)
+                continue;
+            this._grid.addItem(this._items[id].actor);
+        }
+    },
+    
+    onUpdatedDisplaySize: function(width, height) {
+        this._appDisplayWidth = width;
+        this._appDisplayHeight = height;
+        // Update grid dinamyc spacing based on display width
+        let itemWidth = this._grid._hItemSize * MAX_COLUMNS;
+        let emptyArea = width - itemWidth;
+        let spacing;
+        spacing = Math.max(this._grid._spacing, emptyArea / ( 2 *  MAX_COLUMNS));
+        spacing = Math.round(spacing);
+        this._grid.setSpacing(spacing);
+    },
+    
+    _containerBox: function() {
+        let pageBox = new Clutter.ActorBox();
+        pageBox.x1 = 0;
+        pageBox.y1 = 0;
+        pageBox.x2 = this._appDisplayWidth;
+        pageBox.y2 = this._appDisplayHeight;
+        return this.actor.get_theme_node().get_content_box(pageBox);
+    },
+    
+    usedWidth: function() {
+        let box = this._containerBox();
+        let availWidthPerPage = box.x2 - box.x1;
+        let maxUsedWidth = this._grid.usedWidth(availWidthPerPage);
+        global.log("maxUsedWidth " + maxUsedWidth);
+        return maxUsedWidth;
+    },
+    
+    usedHeight: function() {
+        // Then calculate the real maxUsedHeight
+        global.log("this.nRowsDisplayedAtOnce() " + this.nRowsDisplayedAtOnce());
+        return this._grid.usedHeightForNRows(this.nRowsDisplayedAtOnce());
+    },   
+    
+    nRowsDisplayedAtOnce: function() {
+        let box = this._containerBox();
+        let availHeightPerPage = box.y2 - box.y1;
+        let availWidthPerPage = box.x2 - box.x1;
+        let maxRowsDisplayedAtOnce = this.maxRowsDisplayedAtOnce();
+        let usedRows = this._grid.nUsedRows(availWidthPerPage);
+        usedRows = usedRows <= maxRowsDisplayedAtOnce ? usedRows : maxRowsDisplayedAtOnce;
+        return usedRows;
+    },
+    
+    maxRowsDisplayedAtOnce: function() {
+        let box = this._containerBox();
+        let availHeightPerPage = box.y2 - box.y1;
+        let availWidthPerPage = box.x2 - box.x1;
+        let maxRowsPerPage = this._grid.rowsForHeight(availHeightPerPage);
+        //Then, we can only show that rows least one.
+        maxRowsPerPage -= 1;
+        return maxRowsPerPage;
+    }
+});
+
 const FolderIcon = new Lang.Class({
     Name: 'FolderIcon',
 
     _init: function(dir, parentView) {
         this._dir = dir;
-        this._parentView = parentView;
 
         this.actor = new St.Button({ style_class: 'app-well-app app-folder',
                                      button_mask: St.ButtonMask.ONE,
@@ -1018,6 +1104,7 @@ const FolderIcon = new Lang.Class({
                                      x_fill: true,
                                      y_fill: true });
         this.actor._delegate = this;
+        this._parentView = parentView;
 
         let label = this._dir.get_name();
         this.icon = new IconGrid.BaseIcon(label,
@@ -1026,7 +1113,6 @@ const FolderIcon = new Lang.Class({
         this.actor.label_actor = this.icon.label;
 
         this.view = new FolderView();
-        this.view.actor.reactive = false;
         _loadCategory(dir, this.view);
         this.view.loadGrid();
 
@@ -1043,39 +1129,141 @@ const FolderIcon = new Lang.Class({
     },
 
     _createIcon: function(size) {
-        return this.view.createFolderIcon(size);
+        return this.view.createFolderIcon(size, this);
+    },
+    
+    _updatePopupPosition: function() {
+        if(this._popup) {
+            // Position the popup above or below the source icon
+            if (this._side == St.Side.BOTTOM) {
+                global.log("Bottom " + this.actor.y);
+                let closeButtonOffset = -this._popup.closeButton.translation_y;
+                let y = this.actor.y - this._popup.actor.fixed_height;
+                global.log("Bottom " + this._popup.actor.fixed_height);
+                let yWithButton = y - closeButtonOffset;
+                this._popup.parentOffset = yWithButton < 0 ? -yWithButton : 0;
+                this._popup.actor.y = Math.max(y, closeButtonOffset);
+            } else {
+                this._popup.actor.y = this.actor.y + this.actor.height;
+            }
+        }
+    },
+    
+    _popUpWidth: function() {
+        return this.view.usedWidth();
+    },
+    
+    _popUpHeight: function() {
+        /*
+         * To maintain the grid of the collection aligned to the main grid, we have to
+         * make the same spacing to each element of the collection as the main grid has, except
+         * for the last row which has to take less space, since the grid of collection is inside a view with 
padding (the popup)
+         * and, the arrow of the popup is rising some pixels the collection, we have to calculate how much 
real spacing
+         * we have to let under/above the last/first arrow to make let the collection grid aligned with the 
main grid
+         */
+        let arrowHeight = this._popup._boxPointer.actor.get_theme_node().get_length('-arrow-rise');
+        let popupPadding = this._popup._boxPointer.bin.get_theme_node().get_length('padding');
+        //It will be negative value, so we have to rest it, instead of plust it.
+        let closeButtonOverlap = 
this._popup.closeButton.get_theme_node().get_length('-shell-close-overlap-y');
+        let closeButtonHeight = this._popup.closeButton.height;
+        global.log("BUTTON OFFSET " + closeButtonOverlap);
+        let usedHeight = this.view.usedHeight();
+        // If we want it corrected aligned with the main grid the calculation will be: usedHeight - 
popupPadding - arrowHeight
+        // but, if we do that and the popup needs all the height, the popup will remain outside the 
allocation and then clipped. so:
+        if(this.view.nRowsDisplayedAtOnce() == this.view.maxRowsDisplayedAtOnce())
+            usedHeight = usedHeight - popupPadding * 2  - arrowHeight + closeButtonOverlap;
+        else
+            usedHeight =  usedHeight - popupPadding - arrowHeight;
+        return usedHeight;
+        
     },
 
+    makeSpaceForPopUp: function() {
+        //this._parentView.makeSpaceForPopUp(this._side, rows);
+    },
+    
+    onCompletemakeSpaceForPopUp: function() {
+        this._popup.toggle();
+    },
+    
     _ensurePopup: function() {
-        if (this._popup)
+        if(this._popup){
+            this.makeSpaceForPopUp();
             return;
-
-        let spaceTop = this.actor.y;
-        let spaceBottom = this._parentView.actor.height - (this.actor.y + this.actor.height);
-        let side = spaceTop > spaceBottom ? St.Side.BOTTOM : St.Side.TOP;
-
-        this._popup = new AppFolderPopup(this, side);
-        this._parentView.addFolderPopup(this._popup);
-
-        // Position the popup above or below the source icon
-        if (side == St.Side.BOTTOM) {
-            this._popup.actor.show();
-            let closeButtonOffset = -this._popup.closeButton.translation_y;
-            let y = this.actor.y - this._popup.actor.height;
-            let yWithButton = y - closeButtonOffset;
-            this._popup.parentOffset = yWithButton < 0 ? -yWithButton : 0;
-            this._popup.actor.y = Math.max(y, closeButtonOffset);
-            this._popup.actor.hide();
         } else {
-            this._popup.actor.y = this.actor.y + this.actor.height;
-        }
-
-        this._popup.connect('open-state-changed', Lang.bind(this,
-            function(popup, isOpen) {
+            let absoluteActorYPosition = this.actor.get_transformed_position()[1];
+            let spaceTop = absoluteActorYPosition;
+            let spaceBottom = this.actor.get_stage().height - (absoluteActorYPosition + this.actor.height);
+            global.log("absoluteActorYPosition " + absoluteActorYPosition);
+            this._side = spaceTop > spaceBottom ? St.Side.BOTTOM : St.Side.TOP;
+            global.log("this._side " + this._side);
+            this._popup = new AppFolderPopup(this, this._side);
+            this._parentView.addFolderPopup(this._popup);
+            /**
+             * Why we need that: AppDiplay update width for the spacing for all
+             * views Allview and frequent view and folder views calcualte spacing
+             * with the items of icongrid with harcoded values
+             * 
+             * Open overview, then iconSizes changes in allview and frequent view
+             * icongrids, which is the actors who are added to the main AppDisplay.
+             * Then a relayout occurs. AppDiplay update width for the spacing for
+             * all views Allview and frequent view and folder views calcualte
+             * spacing with the items of icongrid, which allview and frequetn view
+             * has the new values, but folderview has the hardcoded values, since
+             * folderview icongrid is not still added to the main Actor, and then,
+             * they didn't emitted style changed signal with new valuesw of item
+             * sizes. Then, frequent view and all view has correct spacing and item
+             * size values, and fodler view has incorrect size and spacing values.
+             * Then, we click icon folder, a folderIcon popup is created and added
+             * to the parent actor, then the style changes, and item size changes,
+             * but spacing is the old one. Then, we calculate the position of the
+             * popup, but, the required height is with the old spacing and new item
+             * sizes, so the height is bigger, then the position is bad. Then,
+             * appDisplay allocate all views updating spacing, and set the good
+             * spacing to folder view, then allocate the folder view, but the
+             * positoon of the boxpointer is already calcualted with the old
+             * spacing, so the boxpointer is displaced.
+             * 
+             * Solution: ensure style of the grid just after we add it to the parent
+             * and before the calculation of the position.
+             */
+            this.view._grid.actor.ensure_style();
+            this.view.onUpdatedDisplaySize(this._displayWidth, this._displayHeight);
+
+            /*
+             * Always make the grid (and therefore the boxpointer) to be the max
+             * width it can be if it use full icon rows, althougth there's less
+             * icons than necesary to full the row. In that manner the popup will be
+             * more eye pleasant, fulling the parent view
+             */
+            this.view.actor.set_width(this._popUpWidth());
+
+            /*
+             * A folder view can only be, at a maximum, one row less than the parent
+             * view, so calculate the maximum rows it can have, and then deduct one,
+             * then calculate the maxUsedHeigth and the current Used height, if it
+             * is more, strech to the maxUsedHeight
+             */
+            let usedHeight = this._popUpHeight();
+            global.log("Used height " + usedHeight);
+            this.view.actor.set_height(this._popUpHeight());
+
+            this._updatePopupPosition();
+
+            this._popup.connect('open-state-changed', Lang.bind(this,
+                    function(popup, isOpen) {
                 if (!isOpen)
                     this.actor.checked = false;
             }));
+        }
+    },
+
+    onUpdatedDisplaySize: function(width, height) {
+        this._displayWidth = width;
+        this._displayHeight = height;
+        this.view.onUpdatedDisplaySize(width, height);
     },
+
 });
 
 const AppFolderPopup = new Lang.Class({
@@ -1100,6 +1288,7 @@ const AppFolderPopup = new Lang.Class({
                                      y_expand: true,
                                      x_align: Clutter.ActorAlign.CENTER,
                                      y_align: Clutter.ActorAlign.START });
+
         this._boxPointer = new BoxPointer.BoxPointer(this._arrowSide,
                                                      { style_class: 'app-folder-popup-bin',
                                                        x_fill: true,
@@ -1151,10 +1340,8 @@ const AppFolderPopup = new Lang.Class({
 
         this.actor.show();
         this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
-
         this._boxPointer.setArrowActor(this._source.actor);
-        this._boxPointer.show(BoxPointer.PopupAnimation.FADE |
-                              BoxPointer.PopupAnimation.SLIDE);
+        this._boxPointer.show(BoxPointer.PopupAnimation.FADE);
 
         this._isOpen = true;
         this.emit('open-state-changed', true);
@@ -1164,8 +1351,7 @@ const AppFolderPopup = new Lang.Class({
         if (!this._isOpen)
             return;
 
-        this._boxPointer.hide(BoxPointer.PopupAnimation.FADE |
-                              BoxPointer.PopupAnimation.SLIDE);
+        this._boxPointer.hide(BoxPointer.PopupAnimation.FADE);
         this._isOpen = false;
         this.emit('open-state-changed', false);
     }
diff --git a/js/ui/boxpointer.js b/js/ui/boxpointer.js
index 2fd1a67..d6d3f84 100644
--- a/js/ui/boxpointer.js
+++ b/js/ui/boxpointer.js
@@ -219,7 +219,7 @@ const BoxPointer = new Lang.Class({
                 break;
         }
         this.bin.allocate(childBox, flags);
-
+        
         if (this._sourceActor && this._sourceActor.mapped) {
             this._reposition();
             this._updateFlip();
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 3155cf3..ed7a16b 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -3,7 +3,9 @@
 const Clutter = imports.gi.Clutter;
 const Shell = imports.gi.Shell;
 const St = imports.gi.St;
+const Meta = imports.gi.Meta;
 
+const Signals = imports.signals;
 const Lang = imports.lang;
 const Params = imports.misc.params;
 
@@ -187,8 +189,8 @@ const IconGrid = new Lang.Class({
         
         if(this._usePagination) {
             this._nPages = 0;
-            //Set this variable properly before getPreferredHeight function is called
-            this._parentSize = [0, 0];
+            //Set this variable properly before allocate function is called
+            this._viewForPageSize = null;
             this._firstPagesItems = [];
         }
         this.actor = new St.BoxLayout({ style_class: 'icon-grid',
@@ -217,7 +219,8 @@ const IconGrid = new Lang.Class({
         let nColumns = this._colLimit ? Math.min(this._colLimit,
                                                  nChildren)
                                       : nChildren;
-        let totalSpacing = Math.max(0, nColumns - 1) * this._spacing;
+        let spacing = this._fixedSpacing ? this._fixedSpacing : this._spacing;
+        let totalSpacing = Math.max(0, nColumns - 1) * spacing;
         // Kind of a lie, but not really an issue right now.  If
         // we wanted to support some sort of hidden/overflow that would
         // need higher level design
@@ -243,11 +246,12 @@ const IconGrid = new Lang.Class({
         let nColumns, spacing;
         if (forWidth < 0) {
             nColumns = children.length;
-            spacing = this._spacing;
         } else {
-            [nColumns, , spacing] = this._computeLayoutOld(forWidth);
+            [nColumns, ] = this._computeLayout(forWidth);
         }
-
+        
+        let spacing = this._fixedSpacing ? this._fixedSpacing : this._spacing;
+        
         let nRows;
         if (nColumns > 0)
             nRows = Math.ceil(children.length / nColumns);
@@ -258,16 +262,9 @@ const IconGrid = new Lang.Class({
         let totalSpacing = Math.max(0, nRows - 1) * spacing;
         let height = nRows * this._vItemSize + totalSpacing;
         
-        if(this._usePagination) {
-            
-            this._spacePerRow = this._vItemSize + spacing;
-            this._rowsPerPage = Math.floor(this._parentSize[1] / this._spacePerRow);
-            this._nPages = Math.ceil(nRows / this._rowsPerPage);
-            this._spaceBetweenPages = this._parentSize[1] - (this._rowsPerPage * (this._vItemSize + 
spacing));
-            let spaceBetweenPagesTotal = this._spaceBetweenPages * (this._nPages);
-            this._childrenPerPage = nColumns * this._rowsPerPage;
-            alloc.min_size = this._rowsPerPage * this._spacePerRow * this._nPages + spaceBetweenPagesTotal;
-            alloc.natural_size = this._rowsPerPage * this._spacePerRow * this._nPages + 
spaceBetweenPagesTotal;
+        if(this._usePagination && this._nPages) {
+            alloc.min_size = this._rowsPerPage * this._spacePerRow * this._nPages + 
this._spaceBetweenPagesTotal;
+            alloc.natural_size = this._rowsPerPage * this._spacePerRow * this._nPages + 
this._spaceBetweenPagesTotal;
             return;
         }
         alloc.min_size = height;
@@ -281,16 +278,36 @@ const IconGrid = new Lang.Class({
             let gridBox = this.actor.get_theme_node().get_content_box(parentBox);
             box = this._grid.get_theme_node().get_content_box(gridBox);
         }
-        
+
         let children = this._getVisibleChildren();
         let availWidth = box.x2 - box.x1;
         let availHeight = box.y2 - box.y1;
-        let [nColumns, usedWidth, spacing] = this._computeLayoutOld(availWidth);
+        let spacing = this._fixedSpacing ? this._fixedSpacing : this._spacing;
+        let [nColumns, usedWidth] = this._computeLayout(availWidth);        
         if(this._usePagination) {
-            //Recalculate the space between pages with the new spacing
-            this._spaceBetweenPages = this._parentSize[1] - (this._rowsPerPage * (this._vItemSize + 
spacing));
+            // ScrollView height
+            let parentBox = this._viewForPageSize.allocation;
+            let gridBox = this.actor.get_theme_node().get_content_box(parentBox);
+            let customBox = this._grid.get_theme_node().get_content_box(gridBox);
+            let availWidth = customBox.x2 - customBox.x1;
+            let availHeightPerPage = customBox.y2 - customBox.y1;
+            let nRows;
+            if (nColumns > 0)
+                nRows = Math.ceil(children.length / nColumns);
+            else
+                nRows = 0;
+            if (this._rowLimit)
+                nRows = Math.min(nRows, this._rowLimit);
+            let oldNPages = this._nPages;
+            this._calculatePaginationValues(availHeightPerPage, nColumns, nRows);
+            if(oldNPages != this._nPages) {
+                this.emit('n-pages-changed', this._nPages);
+                /*Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
+                    this._grid.queue_relayout();
+                    return false;
+                }));*/
+            }
         }
-
         let leftPadding;
         switch(this._xAlign) {
             case St.Align.START:
@@ -312,10 +329,14 @@ const IconGrid = new Lang.Class({
             this._firstPagesItems = [children[0]];
         }
         for (let i = 0; i < children.length; i++) {
-            let childBox = this._calculateChildrenBox(children[i], x, y);
+            let childBox = this._calculateChildrenBox(children[i], x, y, box);
+            if(children[i].translate_y) {
+                childBox.y1 += children[i].translate_y;
+                childBox.y2 += children[i].translate_y;
+            }
             if(!this._usePagination) {
                 if (this._rowLimit && rowIndex >= this._rowLimit ||
-                        this._fillParent && childBox.y2 > availHeight) {
+                        this._fillParent && childBox.y2 >= availHeight) {
                     this._grid.set_skip_paint(children[i], true);
                 } else {
                     children[i].allocate(childBox, flags);
@@ -349,8 +370,21 @@ const IconGrid = new Lang.Class({
         }
         
     },
-
-    _calculateChildrenBox: function(child, x, y) {
+    
+    _calculatePaginationValues: function (availHeightPerPage, nColumns, nRows) {
+        let spacing = this._fixedSpacing ? this._fixedSpacing : this._spacing;
+        this._spacePerRow = this._vItemSize + spacing;
+        this._rowsPerPage = Math.floor(availHeightPerPage / this._spacePerRow);
+        // Check if deleting spacing from bottom there's enough space for another row
+        let spaceWithOneMoreRow = (this._rowsPerPage + 1) * this._spacePerRow - spacing;
+        this._rowsPerPage = spaceWithOneMoreRow <= availHeightPerPage? this._rowsPerPage + 1 : 
this._rowsPerPage;
+        this._nPages = Math.ceil(nRows / this._rowsPerPage);
+        this._spaceBetweenPages = availHeightPerPage - (this._rowsPerPage * (this._vItemSize + spacing));
+        this._spaceBetweenPagesTotal = this._spaceBetweenPages * (this._nPages);
+        this._childrenPerPage = nColumns * this._rowsPerPage;
+    },
+    
+    _calculateChildrenBox: function(child, x, y, box) {
         let [childMinWidth, childMinHeight, childNaturalWidth, childNaturalHeight]
         = child.get_preferred_size();
 
@@ -374,55 +408,57 @@ const IconGrid = new Lang.Class({
     },
     
     childrenInRow: function(rowWidth) {
-        return this._computeLayout(rowWidth)[0]
+        return this._computeLayout(rowWidth)[0];
     },
 
     getRowLimit: function() {
         return this._rowLimit;
     },
     
-    _computeLayoutOldOld: function (forWidth) {
-        let nColumns = 0;
-        let usedWidth = 0;
-        let spacing = this._spacing;
-
-        if (this._colLimit) {
-            let itemWidth = this._hItemSize * this._colLimit;
-            let emptyArea = forWidth - itemWidth;
-            spacing = Math.max(this._spacing, emptyArea / (2 * this._colLimit));
-            spacing = Math.round(spacing);
-        }
-
-        while ((this._colLimit == null || nColumns < this._colLimit) &&
-               (usedWidth + this._hItemSize <= forWidth)) {
-            usedWidth += this._hItemSize + spacing;
-            nColumns += 1;
+    nUsedRows: function(forWidth) {
+        let children = this._getVisibleChildren();
+        let nColumns;
+        if (forWidth < 0) {
+            nColumns = children.length;
+        } else {
+            [nColumns, ] = this._computeLayout(forWidth);
         }
-
+        
+        let nRows;
         if (nColumns > 0)
-            usedWidth -= spacing;
-
-        return [nColumns, usedWidth, spacing];
+            nRows = Math.ceil(children.length / nColumns);
+        else
+            nRows = 0;
+        if (this._rowLimit)
+            nRows = Math.min(nRows, this._rowLimit);
+        return nRows;
+    },
+    
+    rowsForHeight: function(forHeight) {
+        let spacePerRow = this._vItemSize + this.getSpacing();
+        let rowsPerPage = Math.floor(forHeight / spacePerRow);
+        // Check if deleting spacing from bottom there's enough space for another row
+        let spaceWithOneMoreRow = (rowsPerPage + 1) * spacePerRow - this.getSpacing();
+        rowsPerPage = spaceWithOneMoreRow <= forHeight? rowsPerPage + 1 : rowsPerPage;
+        return rowsPerPage;
+    },
+    
+    usedHeightForNRows: function(nRows) {
+        let spacePerRow = this._vItemSize + this.getSpacing();
+        return spacePerRow * nRows;
+    },
+    
+    usedWidth: function(forWidth) {
+        let childrenInRow = this.childrenInRow(forWidth);
+        let usedWidth = childrenInRow  * (this._hItemSize + this.getSpacing());
+        usedWidth -= this.getSpacing();
+        return usedWidth;
     },
     
-    _computeLayoutOld: function (forWidth, forHeight) {
+    _computeLayout: function (forWidth) {
         let nColumns = 0;
         let usedWidth = 0;
-        let spacing = this._spacing;
-
-        if (this._colLimit) {
-            let itemWidth = this._hItemSize * this._colLimit;
-            let emptyArea = forWidth - itemWidth;
-            spacing = Math.max(this._spacing, emptyArea / (2 * this._colLimit));
-            // We have to care that new spacing must not change number of rows per page.
-            if(this._usePagination) {
-                let spaceBetweenPages = this._parentSize[1] - (this._rowsPerPage * (this._vItemSize + 
spacing));
-                if(spaceBetweenPages < 0) {
-                    spacing += spaceBetweenPages / this._rowsPerPage;
-                }
-            }
-            spacing = Math.floor(spacing);
-        }
+        let spacing = this._fixedSpacing ? this._fixedSpacing : this._spacing;
 
         while ((this._colLimit == null || nColumns < this._colLimit) &&
                (usedWidth + this._hItemSize <= forWidth)) {
@@ -433,51 +469,7 @@ const IconGrid = new Lang.Class({
         if (nColumns > 0)
             usedWidth -= spacing;
 
-        return [nColumns, usedWidth, spacing];
-    
-    },
-    _computeLayoutNew: function (forWidth, forHeight) {
-        global.log("############   START COMPUTE   ###############");
-        global.log("forWidth , forHEfith " + [forWidth, forHeight]);
-        //return [6, 800, 6];
-        let nColumns = 0;
-        let usedWidth = 0;
-        let spacing = this._spacing;
-        
-        let spacePerRow = this._vItemSize + spacing;
-        let rowsPerPage = Math.floor(forHeight / spacePerRow);
-        let itemHeithg = this._vItemSize * rowsPerPage;
-        let emptyHeigthArea = forHeight - itemHeithg;
-        let spacingForHeight = Math.max(this._spacing, emptyHeigthArea / (2 * rowsPerPage));
-        
-        let spacePerColumn = this._hItemSize + spacing;
-        let columnsPerPage;
-        if(this._colLimit) {
-            global.log("colLimit " + this._colLimit);
-            columnsPerPage = this._colLimit;
-        } else {
-            columnsPerPage = Math.floor(forWidth / spacePerColumn);
-            global.log("No colLimit "+ columnsPerPage);
-        }
-        if(columnsPerPage == 0) {
-            global.log("############   END COMPUTE 0 COLUMNS   ###############");
-            return [0, 0, this._spacing];
-        }
-        let itemWidth = this._hItemSize * columnsPerPage;
-        let emptyWidthArea = forWidth - itemWidth;
-        let spacingForWidth = Math.max(this._spacing, emptyWidthArea / (2 * columnsPerPage));
-        global.log("SpacingForWidth, spacingForHeigth " + [spacingForWidth, spacingForHeight]);
-        
-        spacing = Math.max(this._spacing, Math.min(spacingForHeight, spacingForWidth));
-        
-        usedWidth = columnsPerPage * (this._hItemSize + spacing);
-        nColumns = columnsPerPage;
-        global.log("nColumns, usedWidth, spacing " + [nColumns, usedWidth, spacing]);
-
-        if (nColumns > 0)
-            usedWidth -= spacing;
-
-        return [nColumns, usedWidth, spacing];
+        return [nColumns, usedWidth];
     },
 
     _onStyleChanged: function() {
@@ -519,5 +511,19 @@ const IconGrid = new Lang.Class({
         }
         let childBox = this._firstPagesItems[pageNumber].get_allocation_box();
         return [childBox.x1, childBox.y1];
-    }
+    },
+    
+    setSpacing: function(spacing) {
+            this._fixedSpacing = spacing;
+            /*Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
+                this._grid.queue_relayout();
+                return false;
+            }));*/
+    },
+    
+    getSpacing: function() {
+        return this._fixedSpacing ? this._fixedSpacing : this._spacing;
+    },
+    
 });
+Signals.addSignalMethods(IconGrid.prototype);


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