[gnome-shell/wip/paging-release2: 7/12] AppDisplay: FolderView and FolderIcon new implementation
- From: Carlos Soriano <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/paging-release2: 7/12] AppDisplay: FolderView and FolderIcon new implementation
- Date: Tue, 20 Aug 2013 20:32:22 +0000 (UTC)
commit ba507bc91caf43a946ebe4219a9eb9e7e901edc3
Author: Carlos Soriano <carlos soriano89 gmail com>
Date: Tue Aug 20 11:20:23 2013 +0200
AppDisplay: FolderView and FolderIcon new implementation
The popup of the FolderView is now contained inside
the parent view, solving the overflow with a ScrollView.
Also, solved a lot of bugs in popup/FolderView calculation
of position and size.
js/ui/appDisplay.js | 288 +++++++++++++++++++++++++++++++++++++++++++++-----
js/ui/boxpointer.js | 8 ++
js/ui/iconGrid.js | 100 ++++++++++++++-----
3 files changed, 343 insertions(+), 53 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index dcb6989..e343d32 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -292,6 +292,8 @@ const AllView = new Lang.Class({
this._grid.connect('n-pages-changed', Lang.bind(this, this._updatedNPages));
+ this._folderIcons = [];
+
this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._box = new St.BoxLayout({ vertical: true });
this._verticalAdjustment = new St.Adjustment();
@@ -464,7 +466,9 @@ const AllView = new Lang.Class({
if (item instanceof Shell.App)
return new AppIcon(item);
else if (item instanceof GMenu.TreeDirectory) {
- return new FolderIcon(item, this);
+ let folderIcon = new FolderIcon(item, this);
+ this._folderIcons.push(folderIcon);
+ return folderIcon;
} else
return null;
},
@@ -477,6 +481,11 @@ const AllView = new Lang.Class({
return (nameA > nameB) ? 1 : (nameA < nameB ? -1 : 0);
},
+ removeAll: function() {
+ this._folderIcons = [];
+ this.parent();
+ },
+
addApp: function(app) {
this._addItem(app);
},
@@ -549,6 +558,10 @@ const AllView = new Lang.Class({
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(availWidth, availHeight);
+ }
}
});
@@ -885,7 +898,19 @@ const FolderView = new Lang.Class({
_init: function() {
this.parent();
- this.actor = this._grid.actor;
+ // 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;
+
+ 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._boxPointerOffsets = {};
},
_getItemId: function(item) {
@@ -919,8 +944,89 @@ const FolderView = new Lang.Class({
bin.set_y_align(aligns[Math.floor(i / 2)]);
icon.add_actor(bin);
}
-
return icon;
+ },
+
+ onUpdatedDisplaySize: function(width, height) {
+ this._appDisplayWidth = width;
+ this._appDisplayHeight = height;
+ // Update grid dinamyc spacing based on display width
+ 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['paddingTop'] +
+ this._boxPointerOffsets['paddingBottom'] +
+ 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() {
+ 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;
+ // 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()) + 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;
+ return usedRows;
+ },
+
+ maxRowsDisplayedAtOnce: function() {
+ let box = this._containerBox();
+ let availHeightPerPage = box.y2 - box.y1;
+ // 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(boxPointerOffsets) {
+ // 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 = boxPointerOffsets;
}
});
@@ -938,6 +1044,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,
@@ -946,7 +1058,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();
@@ -963,39 +1074,138 @@ const FolderIcon = new Lang.Class({
},
_createIcon: function(size) {
- return this.view.createFolderIcon(size);
+ return this.view.createFolderIcon(size, this);
+ },
+
+ _popUpGridWidth: function() {
+ return this.view.usedWidth();
+ },
+
+ _popUpGridHeight: function() {
+ let usedHeight = this.view.usedHeight();
+ return usedHeight;
+ },
+
+ _popUpHeight: function() {
+ let usedHeight = this.view.usedHeight() + this._boxPointerOffsets['arrowHeight'] +
+ this._boxPointerOffsets['paddingTop'] + this._boxPointerOffsets['paddingBottom'];
+ return usedHeight;
+ },
+
+ _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.getOffset('arrowHeight');
+ this._boxPointerOffsets['paddingTop'] = this._popup.getOffset('padding', St.Side.TOP);
+ this._boxPointerOffsets['paddingBottom'] = this._popup.getOffset('padding', St.Side.BOTTOM);
+ //It will be negative value, so we have to substract it, instead of add it.
+ this._boxPointerOffsets['closeButtonOverlap'] = - this._popup.getOffset('closeButtonOverlap');
+
+ this.view.updateBoxPointerOffsets(this._boxPointerOffsets);
+ 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){
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._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;
+ }
+ }));
+ } else
+ this._popup.updateBoxPointer(this._boxPointerArrowside);
+ this._updatePopUpSize();
+ this._updatePopupPosition();
+ this.invalidatePopUp = false;
}
+ },
- 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);
+ this.invalidatePopUp = true;
},
+
});
const AppFolderPopup = new Lang.Class({
@@ -1025,6 +1235,7 @@ const AppFolderPopup = new Lang.Class({
{ style_class: 'app-folder-popup-bin',
x_fill: true,
y_fill: true,
+ x_expand: true,
x_align: St.Align.START });
this._boxPointer.actor.style_class = 'app-folder-popup';
@@ -1088,6 +1299,25 @@ 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();
+ },
+
+ getOffset: function (element, side) {
+ let offset;
+ if(element == 'closeButtonOverlap')
+ offset = this.closeButton.get_theme_node().get_length('-shell-close-overlap-y');
+ else
+ if(element == 'arrowHeight')
+ offset = this._boxPointer.getArrowHeight();
+ else
+ if(element == 'padding')
+ offset = this._boxPointer.getPadding(side);
+ return offset;
}
});
Signals.addSignalMethods(AppFolderPopup.prototype);
diff --git a/js/ui/boxpointer.js b/js/ui/boxpointer.js
index 2fd1a67..833d299 100644
--- a/js/ui/boxpointer.js
+++ b/js/ui/boxpointer.js
@@ -639,5 +639,13 @@ const BoxPointer = new Lang.Class({
get opacity() {
return this.actor.opacity;
+ },
+
+ getPadding: function(side) {
+ return this.bin.get_theme_node().get_padding(side);
+ },
+
+ getArrowHeight: function() {
+ return this.actor.get_theme_node().get_length('-arrow-rise');
}
});
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 6e71bd4..6add8ef 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -188,6 +188,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 });
@@ -217,8 +222,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) {
@@ -243,7 +248,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;
},
@@ -262,20 +267,20 @@ const IconGrid = new Lang.Class({
let spacing = this.getSpacing();
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;
@@ -286,7 +291,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);
@@ -301,7 +306,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;
}
@@ -333,7 +338,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) &&
@@ -372,6 +377,47 @@ const IconGrid = new Lang.Class({
return this._rowLimit;
},
+ 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)
+ nRows = Math.ceil(children.length / nColumns);
+ else
+ nRows = 0;
+ if (this._rowLimit)
+ nRows = Math.min(nRows, this._rowLimit);
+ return nRows;
+ },
+
+ 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
+ let spaceWithOneMoreRow = (rowsPerPage + 1) * spacePerRow - this.getSpacing();
+ rowsPerPage = spaceWithOneMoreRow <= forHeight? rowsPerPage + 1 : rowsPerPage;
+ return rowsPerPage;
+ },
+
+ usedHeightForNRows: function(nRows) {
+ let spacePerRow = this.rowHeight();
+ 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 + this.left_padding + this.right_padding;
+ },
+
removeAll: function() {
this._grid.destroy_all_children();
},
@@ -424,6 +470,10 @@ const IconGrid = new Lang.Class({
spacing = Math.max(this._spacing, spacingNotTooBig);
return spacing;
},
+
+ rowHeight: function() {
+ return this._vItemSize + this.getSpacing();
+ }
});
Signals.addSignalMethods(IconGrid.prototype);
@@ -458,20 +508,20 @@ const PaginatedIconGrid = new Lang.Class({
let spacing = this.getSpacing();
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;
@@ -492,8 +542,8 @@ const PaginatedIconGrid = new Lang.Class({
if (columnIndex == 0) {
y += this._vItemSize + spacing;
if((i + 1) % this._childrenPerPage == 0)
- y += this._spaceBetweenPages - spacing;
- x = box.x1 + leftPadding;
+ y+= - spacing + this._spaceBetweenPages + this.bottom_padding + this.top_padding ;
+ x = box.x1 + leftEmptySpace + this.left_padding;
} else
x += this._hItemSize + spacing;
}
@@ -514,13 +564,15 @@ const PaginatedIconGrid = new Lang.Class({
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._rowsPerPage * (this._vItemSize + spacing) -
spacing);
- this._spaceBetweenPagesTotal = this._spaceBetweenPages * (this._nPages);
+ this._spaceBetweenPages = availHeightPerPage - (this.usedHeightPerPage() - this.top_padding -
this.bottom_padding);
+ this._spaceBetweenPagesTotal = this._spaceBetweenPages * this._nPages;
this._childrenPerPage = nColumns * this._rowsPerPage;
// Take into account when the number of pages changed (then the height of the entire grid changed
for sure)
@@ -532,7 +584,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() {
@@ -547,6 +599,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]