[gnome-shell/wip/paging-release: 2/38] appDisplay, IconGrid: Added pagination
- From: Carlos Soriano <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/paging-release: 2/38] appDisplay, IconGrid: Added pagination
- Date: Tue, 13 Aug 2013 20:14:52 +0000 (UTC)
commit 1e3fe643dfba624a0986711e4bf04c90b2a4284e
Author: Carlos Soriano <carlos soriano89 gmail com>
Date: Mon Aug 12 19:09:10 2013 +0200
appDisplay, IconGrid: Added pagination
AppDisplay: Add max pages
AppDisplay: doesn't superpose dash and pagination indicator to allview
FrequentView: not overlap dash
data/theme/gnome-shell.css | 4 +-
js/ui/appDisplay.js | 434 ++++++++++++++++++++++++++++++++++----------
js/ui/iconGrid.js | 204 +++++++++++++++++----
3 files changed, 509 insertions(+), 133 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 84768b1..c1a3fcc 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -899,10 +899,10 @@ StScrollBar StButton#vhandle:active {
.search-display > StBoxLayout,
-.all-apps > StBoxLayout,
+.all-apps,
.frequent-apps > StBoxLayout {
/* horizontal padding to make sure scrollbars or dash don't overlap content */
- padding: 0px 88px;
+ padding: 8px 88px;
}
.app-folder-icon {
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 41ecddc..1573cda 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -34,6 +34,8 @@ const MAX_COLUMNS = 6;
const INACTIVE_GRID_OPACITY = 77;
const FOLDER_SUBICON_FRACTION = .4;
+const MAX_APPS_PAGES = 20;
+
// Recursively load a GMenuTreeDirectory; we could put this in ShellAppSystem too
function _loadCategory(dir, view) {
@@ -60,6 +62,7 @@ const AlphabeticalView = new Lang.Class({
_init: function() {
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.MIDDLE,
+ usePagination: true,
columnLimit: MAX_COLUMNS });
// Standard hack for ClutterBinLayout
@@ -113,11 +116,17 @@ const AlphabeticalView = new Lang.Class({
const FolderView = new Lang.Class({
Name: 'FolderView',
- Extends: AlphabeticalView,
_init: function() {
- this.parent();
+ 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) {
@@ -153,83 +162,46 @@ const FolderView = new Lang.Class({
}
return icon;
- }
-});
+ },
+
+ removeAll: function() {
+ this._grid.removeAll();
+ this._items = {};
+ this._allItems = [];
+ },
-const AllViewLayout = new Lang.Class({
- Name: 'AllViewLayout',
- Extends: Clutter.BinLayout,
+ _addItem: function(item) {
+ let id = this._getItemId(item);
+ if (this._items[id] !== undefined)
+ return null;
- vfunc_get_preferred_height: function(container, forWidth) {
- let minBottom = 0;
- let naturalBottom = 0;
+ let itemIcon = this._createItemIcon(item);
+ this._allItems.push(item);
+ this._items[id] = itemIcon;
- for (let child = container.get_first_child();
- child;
- child = child.get_next_sibling()) {
- let childY = child.y;
- let [childMin, childNatural] = child.get_preferred_height(forWidth);
+ return itemIcon;
+ },
- if (childMin + childY > minBottom)
- minBottom = childMin + childY;
+ loadGrid: function() {
+ this._allItems.sort(this._compareItems);
- if (childNatural + childY > naturalBottom)
- naturalBottom = childNatural + childY;
+ 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);
}
- return [minBottom, naturalBottom];
}
});
-const AllView = new Lang.Class({
- Name: 'AllView',
+const AppPages = new Lang.Class({
+ Name: 'AppPages',
Extends: AlphabeticalView,
-
- _init: function() {
+
+ _init: function(parent) {
this.parent();
-
- this._grid.actor.y_align = Clutter.ActorAlign.START;
- this._grid.actor.y_expand = true;
-
- let box = new St.BoxLayout({ vertical: true });
- this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
- this._stack.add_actor(this._grid.actor);
- this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
- this._stack.add_actor(this._eventBlocker);
- box.add(this._stack, { y_align: St.Align.START, expand: true });
-
- this.actor = new St.ScrollView({ x_fill: true,
- y_fill: false,
- y_align: St.Align.START,
- x_expand: true,
- y_expand: true,
- overlay_scrollbars: true,
- style_class: 'all-apps vfade' });
- this.actor.add_actor(box);
- this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
- let action = new Clutter.PanAction({ interpolate: true });
- action.connect('pan', Lang.bind(this, this._onPan));
- this.actor.add_action(action);
-
- this._clickAction = new Clutter.ClickAction();
- this._clickAction.connect('clicked', Lang.bind(this, function() {
- if (!this._currentPopup)
- return;
-
- let [x, y] = this._clickAction.get_coords();
- let actor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
- if (!this._currentPopup.actor.contains(actor))
- this._currentPopup.popdown();
- }));
- this._eventBlocker.add_action(this._clickAction);
- },
-
- _onPan: function(action) {
- this._clickAction.release();
-
- let [dist, dx, dy] = action.get_motion_delta(0);
- let adjustment = this.actor.vscroll.adjustment;
- adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
- return false;
+ this.actor = this._grid.actor;
+ this._parent = parent;
},
_getItemId: function(item) {
@@ -240,7 +212,7 @@ const AllView = new Lang.Class({
else
return null;
},
-
+
_createItemIcon: function(item) {
if (item instanceof Shell.App)
return new AppIcon(item);
@@ -257,41 +229,173 @@ const AllView = new Lang.Class({
let nameB = GLib.utf8_collate_key(itemB.get_name(), -1);
return (nameA > nameB) ? 1 : (nameA < nameB ? -1 : 0);
},
+
+ addItem: function(item) {
+ this._addItem(item);
+ },
+
+ nPages: function() {
+ return this._grid.nPages();
+ },
+
+ getPagePosition: function(pageNumber) {
+ return this._grid.getPagePosition(pageNumber);
+ },
+
+ setGridParentSize: function(size) {
+ this._grid._parentSize = size;
+ },
+
+ addFolderPopup: function(popup) {
+ this._parent.addFolderPopup(popup);
+ }
+});
+const PaginationScrollView = new Lang.Class({
+ Name: 'PaginationScrollView',
+ Extends: St.ScrollView,
+
+ _init: function(parent) {
+ this.parent();
+
+ this._stack = new St.Widget({layout_manager: new Clutter.BinLayout()});
+ this._box = new St.BoxLayout({vertical: true});
+ this._pages = new AppPages(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.add_actor(this._box);
+
+ this._currentPage = 0;
+ this._parent = parent;
+
+ this.connect('scroll-event', Lang.bind(this, this._onScroll));
- addApp: function(app) {
- let appIcon = this._addItem(app);
- if (appIcon)
- appIcon.actor.connect('key-focus-in',
- Lang.bind(this, this._ensureIconVisible));
+ this._clickAction = new Clutter.ClickAction();
+ this._clickAction.connect('clicked', Lang.bind(this, function() {
+ if (!this._currentPopup)
+ return;
+
+ let [x, y] = this._clickAction.get_coords();
+ let actor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
+ if (!this._currentPopup.actor.contains(actor))
+ this._currentPopup.popdown();
+ }));
+ this._eventBlocker.add_action(this._clickAction);
},
- addFolder: function(dir) {
- let folderIcon = this._addItem(dir);
- if (folderIcon)
- folderIcon.actor.connect('key-focus-in',
- Lang.bind(this, this._ensureIconVisible));
+ 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];
},
- addFolderPopup: function(popup) {
- this._stack.add_actor(popup.actor);
- popup.connect('open-state-changed', Lang.bind(this,
- function(popup, isOpen) {
- this._eventBlocker.reactive = isOpen;
- this._currentPopup = isOpen ? popup : null;
- this._updateIconOpacities(isOpen);
- if (isOpen) {
- this._ensureIconVisible(popup.actor);
- this._grid.actor.y = popup.parentOffset;
- } else {
- this._grid.actor.y = 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];
},
- _ensureIconVisible: function(icon) {
- Util.ensureActorVisibleInScrollView(this.actor, icon);
+ vfunc_allocate: function(box, flags) {
+ box = this.get_parent().allocation;
+ box = this.get_theme_node().get_content_box(box);
+ 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;
+
+ 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._pages.setGridParentSize([availWidth, availHeight]);
+ child.allocate(childBox, flags);
+ if(this._pages.nPages() > 0) {
+ this._parent.goToPage(0);
+ }
+ },
+
+ goToPage: function(pageNumber) {
+
+ if(pageNumber < this._pages.nPages() && pageNumber >= 0) {
+ this._currentPage = pageNumber;
+ this.vscroll.adjustment.set_value(this._pages.getPagePosition(this._currentPage)[1]);
+ }
+ },
+
+ nPages: function() {
+ return this._pages.nPages();
+ },
+
+ currentPage: function() {
+ return this._currentPage;
+ },
+
+ _onScroll: function(actor, event) {
+ let direction = event.get_scroll_direction();
+ if (direction == Clutter.ScrollDirection.UP)
+ this._parent.goToPage(this._currentPage - 1);
+ if (direction == Clutter.ScrollDirection.DOWN)
+ this._parent.goToPage(this._currentPage + 1);
+ },
+
+ addFolderPopup: function(popup) {
+ this._stack.add_actor(popup.actor);
+ popup.connect('open-state-changed', Lang.bind(this,
+ function(popup, isOpen) {
+ this._eventBlocker.reactive = isOpen;
+ this._currentPopup = isOpen ? popup : null;
+ this._updateIconOpacities(isOpen);
+ if (isOpen) {
+ this._pages._grid.actor.y = popup.parentOffset;
+ } else {
+ this._pages._grid.actor.y = 0;
+ }
+ }));
+ },
+
_updateIconOpacities: function(folderOpen) {
for (let id in this._items) {
if (folderOpen && !this._items[id].actor.checked)
@@ -302,6 +406,142 @@ const AllView = new Lang.Class({
}
});
+const PaginationIconIndicator = new Lang.Class({
+ Name: 'PaginationIconIndicator',
+
+ _init: function(parent, index) {
+
+ this.actor = new St.Button({ style_class: 'show-apps',
+ button_mask: St.ButtonMask.ONE || St.ButtonMask.TWO,
+ toggle_mode: true,
+ can_focus: true });
+ this._icon = new St.Icon({ icon_name: 'view-grid-symbolic',
+ icon_size: 32,
+ style_class: 'show-apps-icon',
+ track_hover: true});
+ this.actor.connect('clicked', Lang.bind(this, this._onClicked));
+ this.actor.set_child(this._icon);
+ this.actor._delegate = this;
+ this._parent = parent;
+ this._index = index;
+ },
+
+ _createIcon: function(size) {
+ this._icon = new St.Icon({ icon_name: 'view-grid-symbolic',
+ icon_size: size,
+ style_class: 'show-apps-icon',
+ track_hover: true });
+ return this._icon;
+ },
+
+ _onClicked: function(actor, button) {
+ this._parent.goToPage(this._index);
+ return false;
+ },
+
+ setChecked: function (checked) {
+ this.actor.set_checked(checked);
+ }
+});
+
+
+const AllView = new Lang.Class({
+ Name: 'AllView',
+
+ _init: function() {
+ this._paginationView = new PaginationScrollView(this);
+ let paginationIndicatorLayout = new Clutter.BoxLayout({orientation: Clutter.Orientation.VERTICAL});
+ //FIXME: hardcoded spacing
+ paginationIndicatorLayout.spacing = 40;
+ this._paginationIndicator = new St.Widget({layout_manager: paginationIndicatorLayout, x_align:3,
y_align: 2, x_expand:true, y_expand:true, style_class: 'pages-indicator'});
+
+ let layout = new Clutter.BinLayout();
+ this.actor = new Shell.GenericContainer({layout_manager: layout, x_expand:true, y_expand:true});
+
+ layout.add(this._paginationView, 2,2);
+ layout.add(this._paginationIndicator, 2,3);
+
+ for(let i = 0; i < MAX_APPS_PAGES; i++) {
+
+ let indicatorIcon = new PaginationIconIndicator(this, i);
+ if(i == 0) {
+ indicatorIcon.setChecked(true);
+ }
+ indicatorIcon.actor.hide();
+ this._paginationIndicator.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();
+
+ if(nPages > 1) {
+ for(let i = 0; i < nPages; i++) {
+ this._paginationIndicator.get_child_at_index(i).show();
+ }
+ }
+ this._paginationIndicator.allocate(box, flags);
+ },
+
+ _onKeyRelease: function(actor, event) {
+ if (event.get_key_symbol() == Clutter.KEY_Up) {
+ this._paginationView.goToNextPage();
+ return true;
+ } else if(event.get_key_symbol() == Clutter.KEY_Down) {
+ this._paginationView.goToPreviousPage();
+ return true;
+ }
+
+ return false;
+ },
+
+ _onPan: function(action) {
+ /*
+ this._clickAction.release();
+
+ let [dist, dx, dy] = action.get_motion_delta(0);
+ let adjustment = this.actor.vscroll.adjustment;
+ adjustment.value -= (dy / this.actor.height) * adjustment.page_size;*/
+ return false;
+ },
+
+ addApp: function(app) {
+ let appIcon = this._paginationView._pages.addItem(app);
+ /*if (appIcon)
+ appIcon.actor.connect('key-focus-in',
+ Lang.bind(this, this._ensureIconVisible));*/
+ },
+
+ addFolder: function(dir) {
+ let folderIcon = this._paginationView._pages.addItem(dir);
+ /*if (folderIcon)
+ folderIcon.actor.connect('key-focus-in',
+ Lang.bind(this, this._ensureIconVisible));*/
+ },
+
+ addFolderPopup: function(popup) {
+ this._paginationView.addFolderPopup(popup);
+ },
+
+ removeAll: function() {
+ this._paginationView._pages.removeAll();
+ },
+
+ loadGrid: function() {
+ this._paginationView._pages.loadGrid();
+ },
+
+ goToPage: function(index) {
+ this._paginationIndicator.get_child_at_index(this._paginationView.currentPage()).set_checked(false);
+ this._paginationView.goToPage(index);
+ this._paginationIndicator.get_child_at_index(this._paginationView.currentPage()).set_checked(true);
+ }
+});
+
const FrequentView = new Lang.Class({
Name: 'FrequentView',
@@ -327,8 +567,7 @@ const FrequentView = new Lang.Class({
continue;
let appIcon = new AppIcon(mostUsed[i]);
this._grid.addItem(appIcon.actor, -1);
- }
- }
+ } }
});
const Views = {
@@ -1027,3 +1266,4 @@ const AppIconMenu = new Lang.Class({
}
});
Signals.addSignalMethods(AppIconMenu.prototype);
+
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 416e659..3155cf3 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -177,12 +177,20 @@ const IconGrid = new Lang.Class({
params = Params.parse(params, { rowLimit: null,
columnLimit: null,
fillParent: false,
- xAlign: St.Align.MIDDLE });
+ xAlign: St.Align.MIDDLE,
+ usePagination: false});
this._rowLimit = params.rowLimit;
this._colLimit = params.columnLimit;
this._xAlign = params.xAlign;
this._fillParent = params.fillParent;
-
+ this._usePagination = params.usePagination;
+
+ if(this._usePagination) {
+ this._nPages = 0;
+ //Set this variable properly before getPreferredHeight function is called
+ this._parentSize = [0, 0];
+ this._firstPagesItems = [];
+ }
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
vertical: true });
@@ -196,6 +204,7 @@ const IconGrid = new Lang.Class({
this._grid.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this._grid.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this._grid.connect('allocate', Lang.bind(this, this._allocate));
+
},
_getPreferredWidth: function (grid, forHeight, alloc) {
@@ -236,7 +245,7 @@ const IconGrid = new Lang.Class({
nColumns = children.length;
spacing = this._spacing;
} else {
- [nColumns, , spacing] = this._computeLayout(forWidth);
+ [nColumns, , spacing] = this._computeLayoutOld(forWidth);
}
let nRows;
@@ -248,23 +257,39 @@ const IconGrid = new Lang.Class({
nRows = Math.min(nRows, this._rowLimit);
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;
+ return;
+ }
alloc.min_size = height;
alloc.natural_size = height;
},
_allocate: function (grid, box, flags) {
- if (this._fillParent) {
+ if(this._fillParent) {
// Reset the passed in box to fill the parent
let parentBox = this.actor.get_parent().allocation;
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._computeLayout(availWidth);
+ let [nColumns, usedWidth, spacing] = this._computeLayoutOld(availWidth);
+ if(this._usePagination) {
+ //Recalculate the space between pages with the new spacing
+ this._spaceBetweenPages = this._parentSize[1] - (this._rowsPerPage * (this._vItemSize +
spacing));
+ }
let leftPadding;
switch(this._xAlign) {
@@ -282,35 +307,25 @@ const IconGrid = new Lang.Class({
let y = box.y1;
let columnIndex = 0;
let rowIndex = 0;
+
+ if(children.length > 0) {
+ this._firstPagesItems = [children[0]];
+ }
for (let i = 0; i < children.length; i++) {
- let [childMinWidth, childMinHeight, childNaturalWidth, childNaturalHeight]
- = children[i].get_preferred_size();
-
- /* Center the item in its allocation horizontally */
- let width = Math.min(this._hItemSize, childNaturalWidth);
- let childXSpacing = Math.max(0, width - childNaturalWidth) / 2;
- let height = Math.min(this._vItemSize, childNaturalHeight);
- let childYSpacing = Math.max(0, height - childNaturalHeight) / 2;
-
- let childBox = new Clutter.ActorBox();
- if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
- let _x = box.x2 - (x + width);
- childBox.x1 = Math.floor(_x - childXSpacing);
- } else {
- childBox.x1 = Math.floor(x + childXSpacing);
- }
- childBox.y1 = Math.floor(y + childYSpacing);
- childBox.x2 = childBox.x1 + width;
- childBox.y2 = childBox.y1 + height;
-
- if (this._rowLimit && rowIndex >= this._rowLimit ||
- this._fillParent && childBox.y2 > availHeight) {
- this._grid.set_skip_paint(children[i], true);
+ let childBox = this._calculateChildrenBox(children[i], x, y);
+ if(!this._usePagination) {
+ if (this._rowLimit && rowIndex >= this._rowLimit ||
+ this._fillParent && childBox.y2 > availHeight) {
+ this._grid.set_skip_paint(children[i], true);
+ } else {
+ children[i].allocate(childBox, flags);
+ this._grid.set_skip_paint(children[i], false);
+ }
} else {
children[i].allocate(childBox, flags);
this._grid.set_skip_paint(children[i], false);
}
-
+
columnIndex++;
if (columnIndex == nColumns) {
columnIndex = 0;
@@ -319,22 +334,54 @@ const IconGrid = new Lang.Class({
if (columnIndex == 0) {
y += this._vItemSize + spacing;
+ if(this._usePagination) {
+ if((i + 1) % this._childrenPerPage == 0) {
+ y+= this._spaceBetweenPages;
+ if(i < children.length) {
+ this._firstPagesItems.push(children[i+1]);
+ }
+ }
+ }
x = box.x1 + leftPadding;
} else {
x += this._hItemSize + spacing;
}
}
+
},
+ _calculateChildrenBox: function(child, x, y) {
+ let [childMinWidth, childMinHeight, childNaturalWidth, childNaturalHeight]
+ = child.get_preferred_size();
+
+ /* Center the item in its allocation horizontally */
+ let width = Math.min(this._hItemSize, childNaturalWidth);
+ let childXSpacing = Math.max(0, width - childNaturalWidth) / 2;
+ let height = Math.min(this._vItemSize, childNaturalHeight);
+ let childYSpacing = Math.max(0, height - childNaturalHeight) / 2;
+
+ let childBox = new Clutter.ActorBox();
+ if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
+ let _x = box.x2 - (x + width);
+ childBox.x1 = Math.floor(_x - childXSpacing);
+ } else {
+ childBox.x1 = Math.floor(x + childXSpacing);
+ }
+ childBox.y1 = Math.floor(y + childYSpacing);
+ childBox.x2 = childBox.x1 + width;
+ childBox.y2 = childBox.y1 + height;
+ return childBox;
+ },
+
childrenInRow: function(rowWidth) {
- return this._computeLayout(rowWidth)[0];
+ return this._computeLayout(rowWidth)[0]
},
getRowLimit: function() {
return this._rowLimit;
},
-
- _computeLayout: function (forWidth) {
+
+ _computeLayoutOldOld: function (forWidth) {
let nColumns = 0;
let usedWidth = 0;
let spacing = this._spacing;
@@ -357,6 +404,81 @@ const IconGrid = new Lang.Class({
return [nColumns, usedWidth, spacing];
},
+
+ _computeLayoutOld: function (forWidth, forHeight) {
+ 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);
+ }
+
+ while ((this._colLimit == null || nColumns < this._colLimit) &&
+ (usedWidth + this._hItemSize <= forWidth)) {
+ usedWidth += this._hItemSize + spacing;
+ nColumns += 1;
+ }
+
+ 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];
+ },
_onStyleChanged: function() {
let themeNode = this.actor.get_theme_node();
@@ -383,5 +505,19 @@ const IconGrid = new Lang.Class({
visibleItemsCount: function() {
return this._grid.get_n_children() - this._grid.get_n_skip_paint();
+ },
+
+ nPages: function() {
+ return this._nPages;
+ },
+
+ getPagePosition: function(pageNumber) {
+ if(!this._nPages)
+ return;
+ if(pageNumber < 0 || pageNumber > this._nPages) {
+ throw new Error('Invalid page number ' + pageNumber);
+ }
+ let childBox = this._firstPagesItems[pageNumber].get_allocation_box();
+ return [childBox.x1, childBox.y1];
}
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]