[gnome-shell/wip/paging-release2: 7/9] Collections contained inside parent view



commit 9508b32878c79c269f1017b041f94c3eadb275d4
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Mon Aug 19 17:03:26 2013 +0200

    Collections contained inside parent view

 js/ui/appDisplay.js |  269 +++++++++++++++++++++++++++++++--------------------
 js/ui/iconGrid.js   |   62 +++++++-----
 2 files changed, 197 insertions(+), 134 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 735b44d..3c043fe 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -1046,6 +1046,8 @@ const FolderView = new Lang.Class({
         this._widget.add_child(this._grid.actor);
         this._box.add_actor(this._widget);
         this.actor.add_actor(this._box);
+
+        this._boxPointerOffsets = {};
     },
 
     _getItemId: function(item) {
@@ -1086,12 +1088,20 @@ const FolderView = new Lang.Class({
         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);
+        let spacing = this._grid.maxSpacingForWidthHeight(width, height, MIN_COLUMNS, MIN_ROWS, true);
         this._grid.setSpacing(spacing);
+        if(!Object.keys(this._boxPointerOffsets).length)
+            return;
+
+        let boxPointerTotalOffset = this._boxPointerOffsets['arrowHeight'] +
+                                    this._boxPointerOffsets['padding'] * 2 +
+                                    this._boxPointerOffsets['closeButtonOverlap'];
+        let offsetForEachSide = Math.ceil(boxPointerTotalOffset / 2);
+        this._offsetForEachSide = offsetForEachSide;
+        this._grid.top_padding = spacing - offsetForEachSide;
+        this._grid.bottom_padding = spacing - offsetForEachSide;
+        this._grid.left_padding = spacing - offsetForEachSide;
+        this._grid.right_padding = spacing - offsetForEachSide;
     },
 
     _containerBox: function() {
@@ -1106,19 +1116,29 @@ const FolderView = new Lang.Class({
     usedWidth: function() {
         let box = this._containerBox();
         let availWidthPerPage = box.x2 - box.x1;
+        // We only can show icons inside the collection view boxPointer
+        // so we have to substract the required padding etc of the boxpointer
+        // to make the calculation of used width right
+        availWidthPerPage -= 2 * this._offsetForEachSide;
         let maxUsedWidth = this._grid.usedWidth(availWidthPerPage);
         return maxUsedWidth;
     },
 
     usedHeight: function() {
         // Then calculate the real maxUsedHeight
-        return this._grid.usedHeightForNRows(this.nRowsDisplayedAtOnce());
+        return this._grid.usedHeightForNRows(this.nRowsDisplayedAtOnce()) + this._grid.top_padding + 
this._grid.bottom_padding;
     },
 
     nRowsDisplayedAtOnce: function() {
         let box = this._containerBox();
         let availHeightPerPage = box.y2 - box.y1;
         let availWidthPerPage = box.x2 - box.x1;
+        // We only can show icons inside the collection view boxPointer
+        // so we have to substract the required padding etc of the boxpointer
+        // to make the calculation of the rows we can show right
+        availWidthPerPage -= 2 * this._offsetForEachSide;
+        availHeightPerPage -= 2 * this._offsetForEachSide;
+
         let maxRowsDisplayedAtOnce = this.maxRowsDisplayedAtOnce();
         let usedRows = this._grid.nUsedRows(availWidthPerPage);
         usedRows = usedRows <= maxRowsDisplayedAtOnce ? usedRows : maxRowsDisplayedAtOnce;
@@ -1128,13 +1148,26 @@ const FolderView = new Lang.Class({
     maxRowsDisplayedAtOnce: function() {
         let box = this._containerBox();
         let availHeightPerPage = box.y2 - box.y1;
-        let availWidthPerPage = box.x2 - box.x1;
+        // We only can show icons inside the collection view boxPointer
+        // so we have to substract the required padding etc of the boxpointer
+        // to make the calculation of the rows we can show right
+        availHeightPerPage -= 2 * this._offsetForEachSide;
         let maxRowsPerPage = this._grid.rowsForHeight(availHeightPerPage);
         //Then, we can only show that rows least one.
         maxRowsPerPage -= 1;
         return maxRowsPerPage;
     },
     
+    updateBoxPointerOffsets: function(arrowHeight, padding, closeButtonOverlap) {
+        // We have to ensure the folder view boxpointer and the close button
+        // doesn't go outside boundary, so we have to take into account the
+        // arrow size, the padding of the boxpointer and the close button displacement
+        this._boxPointerOffsets['arrowHeight'] = arrowHeight;
+        this._boxPointerOffsets['padding'] = padding;
+        this._boxPointerOffsets['closeButtonOverlap'] = closeButtonOverlap;
+        
+    },
+
     setScrollToStart: function() {
         this.actor.vscroll.adjustment.value = 0;
     }
@@ -1154,6 +1187,12 @@ const FolderIcon = new Lang.Class({
                                      x_fill: true,
                                      y_fill: true });
         this.actor._delegate = this;
+        // when changing screen resolution or during clutter "false" allocations
+        // we have to tell collection view that the calculated values of boxpointer arrow side, position, 
etc 
+        // are not correct (since the allocated size of pagination changed)
+        // For that problem we calculate everything again and apply it maintaining current popup.
+        this.invalidatePopUp = false;
+        this._boxPointerOffsets = {};
 
         let label = this._dir.get_name();
         this.icon = new IconGrid.BaseIcon(label,
@@ -1185,51 +1224,22 @@ const FolderIcon = new Lang.Class({
         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) {
-                let closeButtonOffset = -this._popup.closeButton.translation_y;
-                let y = this.actor.y - 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;
-            }
-        }
+    _popUpGridWidth: function() {
+        return this.view.usedWidth();
     },
 
-    _popUpWidth: function() {
-        return this.view.usedWidth();
+    _popUpGridHeight: function() {
+        let usedHeight = this.view.usedHeight();
+        return usedHeight;   
     },
 
     _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;
-        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;
-        
+        let usedHeight = this.view.usedHeight() + this._boxPointerOffsets['arrowHeight'] + 
this._boxPointerOffsets['padding'] * 2;
+        return usedHeight;   
     },
 
     makeSpaceForPopUp: function() {
-        this._parentView.makeSpaceForPopUp(this, this._side, this.view.nRowsDisplayedAtOnce());
+        this._parentView.makeSpaceForPopUp(this, this._boxPointerArrowside, 
this.view.nRowsDisplayedAtOnce());
     },
 
     returnSpaceToOriginalPosition: function() {
@@ -1240,74 +1250,112 @@ const FolderIcon = new Lang.Class({
         this._popup.popup();
     },
 
+    _calculateBoxPointerArrowSide: function() {
+        let absoluteActorYPosition = this.actor.get_transformed_position()[1];
+        let spaceTop = absoluteActorYPosition;
+        // Be careful, we don't take into account the top panel height etc,
+        // So maybe we put an arrow side "wrong", but anyway, the expanding of colelction view will
+        // do the required space and all will go fine
+        let spaceBottom = this.actor.get_stage().height - (absoluteActorYPosition + this.actor.height);
+        return spaceTop > spaceBottom ? St.Side.BOTTOM : St.Side.TOP;
+    },
+
+    _updatePopUpSize: function() {
+        /**
+         * 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._boxPointerOffsets['arrowHeight'] = 
this._popup._boxPointer.actor.get_theme_node().get_length('-arrow-rise');
+        this._boxPointerOffsets['padding'] = 
this._popup._boxPointer.bin.get_theme_node().get_length('padding');
+        //It will be negative value, so we have to substract it, instead of add it.
+        this._boxPointerOffsets['closeButtonOverlap'] = - 
this._popup.closeButton.get_theme_node().get_length('-shell-close-overlap-y');
+
+        this.view.updateBoxPointerOffsets(this._boxPointerOffsets['arrowHeight'], 
this._boxPointerOffsets['padding'], this._boxPointerOffsets['closeButtonOverlap']);
+        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, filling the parent view
+         */
+        this.view.actor.set_width(this._popUpGridWidth());
+        /*
+         * 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 substract one,
+         * then calculate the maxUsedHeigth and the current used height, if it
+         * is more, strech to the maxUsedHeight
+         */
+        this.view.actor.set_height(this._popUpGridHeight());
+    },
+
+    _updatePopupPosition: function() {
+        if(this._popup) {
+            // Position the popup above or below the source icon
+            if (this._boxPointerArrowside == St.Side.BOTTOM) {
+                let closeButtonOffset = -this._popup.closeButton.translation_y;
+                // We have to use this function, since this._popup.actor.height not always return a good 
value (32 px??)
+                // and then all this calculation of position fails. To solve this in this function we 
calculate the used height with the grid
+                // since we know all of the properties of grid. Then we add the padding, arrowheigth etc of 
boxpointer, and we have the
+                // used height of the popup
+                let y = this.actor.y - this._popUpHeight();
+                let yWithButton = y - closeButtonOffset;
+                this._popup.parentOffset = yWithButton < 0 ? -yWithButton : 0;
+                this._popup.actor.y = Math.max(y, closeButtonOffset);
+                this._popup.actor.y = y
+            } else {
+                this._popup.actor.y = this.actor.y + this.actor.height;
+            }
+        }
+    },
+
     _ensurePopup: function() {
-        if(this._popup){
+        if(this._popup && !this.invalidatePopUp){
             this.makeSpaceForPopUp();
             return;
         } else {
-            let absoluteActorYPosition = this.actor.get_transformed_position()[1];
-            let spaceTop = absoluteActorYPosition;
-            let spaceBottom = this.actor.get_stage().height - (absoluteActorYPosition + this.actor.height);
-            this._side = spaceTop > spaceBottom ? St.Side.BOTTOM : St.Side.TOP;
-            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();
-            this.view.actor.set_height(this._popUpHeight());
-            this._popup.actor.fixed_height = this._popup.actor.height;
-
+            this._boxPointerArrowside = this._calculateBoxPointerArrowSide();
+            if(!this._popup) {
+                this._popup = new AppFolderPopup(this, this._boxPointerArrowside);
+                this._parentView.addFolderPopup(this._popup);
+                this._popup.connect('open-state-changed', Lang.bind(this,
+                        function(popup, isOpen) {
+                    if (!isOpen) {
+                        this.actor.checked = false;
+                        this.returnSpaceToOriginalPosition();
+                    }
+                }));
+            } else
+                this._popup.updateBoxPointer(this._boxPointerArrowside);
+            this._updatePopUpSize();
+            this._updatePopupPosition();
             this.makeSpaceForPopUp();
-            this._popup.connect('open-state-changed', Lang.bind(this,
-                    function(popup, isOpen) {
-                if (!isOpen) {
-                    this.actor.checked = false;
-                    this.returnSpaceToOriginalPosition();
-                }
-            }));
+            this.invalidatePopUp = false; 
         }
     },
 
@@ -1315,6 +1363,7 @@ const FolderIcon = new Lang.Class({
         this._displayWidth = width;
         this._displayHeight = height;
         this.view.onUpdatedDisplaySize(width, height);
+        this.invalidatePopUp = true;
     },
 
 });
@@ -1410,6 +1459,12 @@ const AppFolderPopup = new Lang.Class({
                               BoxPointer.PopupAnimation.SLIDE);
         this._isOpen = false;
         this.emit('open-state-changed', false);
+    },
+
+    updateBoxPointer: function (side) {
+        this._arrowSide = side;
+        this._boxPointer._arrowSide = side;
+        this._boxPointer._border.queue_repaint();
     }
 });
 Signals.addSignalMethods(AppFolderPopup.prototype);
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 0985eef..8f74b1d 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -189,6 +189,11 @@ const IconGrid = new Lang.Class({
         this._xAlign = params.xAlign;
         this._fillParent = params.fillParent;
 
+        this.top_padding = 0;
+        this.bottom_padding = 0;
+        this.right_padding = 0;
+        this.left_padding = 0;
+
         this.actor = new St.BoxLayout({ style_class: 'icon-grid',
                                         vertical: true });
 
@@ -218,8 +223,8 @@ const IconGrid = new Lang.Class({
         // 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
-        alloc.min_size = this._hItemSize;
-        alloc.natural_size = nColumns * this._hItemSize + totalSpacing;
+        alloc.min_size = this._hItemSize + this.left_padding + this.right_padding;
+        alloc.natural_size = nColumns * this._hItemSize + totalSpacing + this.left_padding + 
this.right_padding;
     },
 
     _getPreferredHeight: function (grid, forWidth, alloc) {
@@ -244,7 +249,7 @@ const IconGrid = new Lang.Class({
         if (this._rowLimit)
             nRows = Math.min(nRows, this._rowLimit);
         let totalSpacing = Math.max(0, nRows - 1) * this.getSpacing();
-        let height = nRows * this._vItemSize + totalSpacing;
+        let height = nRows * this._vItemSize + totalSpacing + this.top_padding + this.bottom_padding;
         alloc.min_size = height;
         alloc.natural_size = height;
     },
@@ -261,22 +266,22 @@ const IconGrid = new Lang.Class({
         let availWidth = box.x2 - box.x1;
         let availHeight = box.y2 - box.y1;
         let spacing = this.getSpacing();
-        let [nColumns, usedWidth] = this._computeLayout(availWidth);        
+        let [nColumns, usedWidth] = this._computeLayout(availWidth);
 
-        let leftPadding;
+        let leftEmptySpace;
         switch(this._xAlign) {
             case St.Align.START:
-                leftPadding = 0;
+                leftEmptySpace = 0;
                 break;
             case St.Align.MIDDLE:
-                leftPadding = Math.floor((availWidth - usedWidth) / 2);
+                leftEmptySpace = Math.floor((availWidth - usedWidth) / 2);
                 break;
             case St.Align.END:
-                leftPadding = availWidth - usedWidth;
+                leftEmptySpace = availWidth - usedWidth;
         }
 
-        let x = box.x1 + leftPadding;
-        let y = box.y1;
+        let x = box.x1 + leftEmptySpace + this.left_padding;
+        let y = box.y1 + this.top_padding;
         let columnIndex = 0;
         let rowIndex = 0;
 
@@ -287,7 +292,7 @@ const IconGrid = new Lang.Class({
                 childBox.y2 += children[i].translate_y;
             }
             if (this._rowLimit && rowIndex >= this._rowLimit ||
-                this._fillParent && childBox.y2 >= availHeight) {
+                this._fillParent && childBox.y2 > availHeight - this.bottom_padding) {
                 this._grid.set_skip_paint(children[i], true);
             } else {
                 children[i].allocate(childBox, flags);
@@ -302,7 +307,7 @@ const IconGrid = new Lang.Class({
 
             if (columnIndex == 0) {
                 y += this._vItemSize + spacing;
-                x = box.x1 + leftPadding;
+                x = box.x1 + leftEmptySpace + this.left_padding;
             } else {
                 x += this._hItemSize + spacing;
             }
@@ -334,7 +339,7 @@ const IconGrid = new Lang.Class({
 
     _computeLayout: function (forWidth) {
         let nColumns = 0;
-        let usedWidth = 0;
+        let usedWidth = this.left_padding + this.right_padding;
         let spacing = this.getSpacing();
 
         while ((this._colLimit == null || nColumns < this._colLimit) &&
@@ -392,6 +397,7 @@ const IconGrid = new Lang.Class({
     },
 
     rowsForHeight: function(forHeight) {
+        forHeight -= this.top_padding + this.bottom_padding;
         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
@@ -402,14 +408,14 @@ const IconGrid = new Lang.Class({
 
     usedHeightForNRows: function(nRows) {
         let spacePerRow = this.rowHeight();
-        return spacePerRow * nRows;
+        return spacePerRow * nRows - this.getSpacing();
     },
 
     usedWidth: function(forWidth) {
         let childrenInRow = this.childrenInRow(forWidth);
         let usedWidth = childrenInRow  * (this._hItemSize + this.getSpacing());
         usedWidth -= this.getSpacing();
-        return usedWidth;
+        return usedWidth + this.left_padding + this.right_padding;
     },
 
     removeAll: function() {
@@ -514,7 +520,7 @@ const PaginatedIconGrid = new Lang.Class({
         let spacing = this.getSpacing();
         let [nColumns, usedWidth] = this._computeLayout(availWidth);
 
-        // ScrollView height
+        // Calculate icongrid box inside the scrollView
         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);
@@ -541,20 +547,20 @@ const PaginatedIconGrid = new Lang.Class({
             }));
         }
 
-        let leftPadding;
+        let leftEmptySpace;
         switch(this._xAlign) {
             case St.Align.START:
-                leftPadding = 0;
+                leftEmptySpace = 0;
                 break;
             case St.Align.MIDDLE:
-                leftPadding = Math.floor((availWidth - usedWidth) / 2);
+                leftEmptySpace = Math.floor((availWidth - usedWidth) / 2);
                 break;
             case St.Align.END:
-                leftPadding = availWidth - usedWidth;
+                leftEmptySpace = availWidth - usedWidth;
         }
 
-        let x = box.x1 + leftPadding;
-        let y = box.y1;
+        let x = box.x1 + leftEmptySpace + this.left_padding;
+        let y = box.y1 + this.top_padding;
         let columnIndex = 0;
         let rowIndex = 0;
 
@@ -575,9 +581,9 @@ const PaginatedIconGrid = new Lang.Class({
             if (columnIndex == 0) {
                 y += this._vItemSize + spacing;
                 if((i + 1) % this._childrenPerPage == 0) {
-                    y+= this._spaceBetweenPages - spacing;
+                    y+= - spacing + this._spaceBetweenPages + this.bottom_padding + this.top_padding ;
                 }
-                x = box.x1 + leftPadding;
+                x = box.x1 + leftEmptySpace + this.left_padding;
             } else {
                 x += this._hItemSize + spacing;
             }
@@ -587,12 +593,14 @@ const PaginatedIconGrid = new Lang.Class({
     _calculatePaginationValues: function (availHeightPerPage, nColumns, nRows) {
         let spacing = this.getSpacing();
         this._spacePerRow = this._vItemSize + spacing;
+        // We want to contain the grid inside the parent box with padding
+        availHeightPerPage -= this.top_padding + this.bottom_padding;
         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.usedHeightPerPage();
+        this._spaceBetweenPages = availHeightPerPage - (this.usedHeightPerPage() - this.top_padding - 
this.bottom_padding);
         this._spaceBetweenPagesTotal = this._spaceBetweenPages * this._nPages;
         this._childrenPerPage = nColumns * this._rowsPerPage;
     },
@@ -620,7 +628,7 @@ const PaginatedIconGrid = new Lang.Class({
     },
 
     usedHeightPerPage: function() {
-        return this._rowsPerPage * this._spacePerRow - this.getSpacing();
+        return this._rowsPerPage * this._spacePerRow - this.getSpacing() + this.top_padding + 
this.bottom_padding;
     },
 
     nPages: function() {
@@ -635,6 +643,6 @@ const PaginatedIconGrid = new Lang.Class({
         }
         let childBox = this._getVisibleChildren()[pageNumber *
                         this._childrenPerPage].get_allocation_box();
-        return [childBox.x1, childBox.y1];
+        return [childBox.x1 - this.top_padding, childBox.y1 - this.top_padding];
     }
 });


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