[gnome-shell/wip/paging-release: 2/90] Pagging with St.ScrollView
- From: Carlos Soriano <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/paging-release: 2/90] Pagging with St.ScrollView
- Date: Mon, 12 Aug 2013 13:46:11 +0000 (UTC)
commit 22cbe51e67c7df79c03b81341a32f59e16f59815
Author: Carlos Soriano <csoriano src gnome org>
Date: Fri Jun 14 11:58:50 2013 +0200
Pagging with St.ScrollView
js/ui/appDisplay.js | 221 ++++++++++++++++++++++++++++++++++++++-------------
js/ui/iconGrid.js | 90 +++++++++++++++------
2 files changed, 231 insertions(+), 80 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 41ecddc..bc54180 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -36,7 +36,7 @@ const FOLDER_SUBICON_FRACTION = .4;
// Recursively load a GMenuTreeDirectory; we could put this in ShellAppSystem too
-function _loadCategory(dir, view) {
+function _loadCategory(dir, list) {
let iter = dir.iter();
let appSystem = Shell.AppSystem.get_default();
let nextType;
@@ -45,11 +45,11 @@ function _loadCategory(dir, view) {
let entry = iter.get_entry();
let app = appSystem.lookup_app_by_tree_entry(entry);
if (!entry.get_app_info().get_nodisplay())
- view.addApp(app);
+ list.addApp(app);
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
let itemDir = iter.get_directory();
if (!itemDir.get_is_nodisplay())
- _loadCategory(itemDir, view);
+ _loadCategory(itemDir, list);
}
}
};
@@ -60,6 +60,7 @@ const AlphabeticalView = new Lang.Class({
_init: function() {
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.MIDDLE,
+
columnLimit: MAX_COLUMNS });
// Standard hack for ClutterBinLayout
@@ -161,6 +162,11 @@ const AllViewLayout = new Lang.Class({
Extends: Clutter.BinLayout,
vfunc_get_preferred_height: function(container, forWidth) {
+ if(this.parentSize)
+ {
+ return this.parentSize;
+ }
+ global.log("Parent size " + this.parentSize);
let minBottom = 0;
let naturalBottom = 0;
@@ -180,33 +186,134 @@ const AllViewLayout = new Lang.Class({
}
});
-const AllView = new Lang.Class({
- Name: 'AllView',
+const AppPage = new Lang.Class({
+ Name: 'AppPage',
Extends: AlphabeticalView,
-
+
_init: function() {
this.parent();
-
this._grid.actor.y_align = Clutter.ActorAlign.START;
- this._grid.actor.y_expand = true;
+ this._grid.actor.y_expand = false;
+ this.actor = this._grid.actor;
+ },
+
+ _getItemId: function(item) {
+ if (item instanceof Shell.App)
+ return item.get_id();
+ else if (item instanceof GMenu.TreeDirectory)
+ return item.get_menu_id();
+ else
+ return null;
+ },
+
+ _createItemIcon: function(item) {
+ if (item instanceof Shell.App)
+ return new AppIcon(item);
+ else if (item instanceof GMenu.TreeDirectory)
+ return new FolderIcon(item, this);
+ else
+ return null;
+ },
+
+ _compareItems: function(itemA, itemB) {
+ // bit of a hack: rely on both ShellApp and GMenuTreeDirectory
+ // having a get_name() method
+ let nameA = GLib.utf8_collate_key(itemA.get_name(), -1);
+ let nameB = GLib.utf8_collate_key(itemB.get_name(), -1);
+ return (nameA > nameB) ? 1 : (nameA < nameB ? -1 : 0);
+ },
+
+ addItem: function(item) {
+ this._addItem(item);
+ }
+});
+
+const PaginationScrollView = new Lang.Class({
+ Name: 'PaginationScrollView',
+ Extends: St.ScrollView,
+
+ _init: function(params) {
+
+ },
+
+ vfunc_allocate: function(box, flags) {
+ this.set_allocation(box, flags);
+ global.log("ALLOCATION DONE!!!");
+ }
+});
- let box = new St.BoxLayout({ vertical: true });
- this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
- this._stack.add_actor(this._grid.actor);
+
+const AllView = new Lang.Class({
+ Name: 'AllView',
+ Extends: St.ScrollView,
+
+ _init: function() {
+ this.parent({
+ 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._actorLayoutManager = new AllViewLayout();
+ this.actor = this;
+ global.log(" SERAAA?? " + this.actor.scroll_to_point);
+ this._box = new St.BoxLayout({vertical: true});
+ this._widgetLayoutManager = new AllViewLayout();
+
+
+ this._widgetForLayout = new St.Widget({ layout_manager: this._widgetLayoutManager });
+ this._page = new AppPage();
+ this._widgetForLayout.add_actor(this._page.actor);
+ this._box.add_actor(this._widgetForLayout);
+ this.actor.add_actor(this._box);
+ //this.clip_to_allocation = true;
+ //this.actor.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
+ /*let box = new St.BoxLayout({ vertical: true });
+ this._stack = new St.Widget();*/
+
+ /*this._stack.add_actor(this._page.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 });
+ box.add(this._stack, { y_align: St.Align.START, expand: true });*/
- this.actor = new St.ScrollView({ x_fill: 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 });
+ style_class: 'all-apps vfade' });*/
+
+ /*this._widgetForLayout2 = new St.Widget({ layout_manager: new AllViewLayout() });
+ this._widgetForLayout2.add_actor(this._page2.actor);
+ this._textLabel = new St.Label({text: "HOLAAA"});
+ this._textLabel2 = new St.Label({text: "HOLAAA"});
+ this._box.add_actor(this._textLabel);
+ this._box.add_actor(this._widgetForLayout);
+
+
+ this._box.add(this._textLabel2);
+ this._box.add(this._widgetForLayout2);*/
+
+
+ /*this.actor = new St.Bin({ style_class: 'all-apps vfade',
+ x_fill: true,
+ y_fill: false,
+ y_align: St.Align.START, x_expand: true, y_expand: true});
+
+ this.actor.add_actor(this._page.actor);*/
+ //this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+
+
+ this._pageControl = new St.Widget();
+
+ /*this.actor = new St.Widget({ style_class: 'frequent-apps',
+ x_expand: true, y_expand: true });*/
+
+
+ /* let action = new Clutter.PanAction({ interpolate: true });
action.connect('pan', Lang.bind(this, this._onPan));
this.actor.add_action(action);
@@ -220,59 +327,50 @@ const AllView = new Lang.Class({
if (!this._currentPopup.actor.contains(actor))
this._currentPopup.popdown();
}));
- this._eventBlocker.add_action(this._clickAction);
+ this._eventBlocker.add_action(this._clickAction);*/
+ global.log("PPP visible items after init " + this._page._grid.visibleItemsCount());
},
-
+
+ vfunc_allocate: function(box, flags) {
+ this.set_allocation(box, flags);
+ global.log("ALLOCATIONS!!!!!!");
+ global.log("Allocation width "+ this.clip_rect.size.width);
+ global.log("Allocation heithg "+ this.clip_rect.size.height);
+ global.log("Allocation box "+ [box.x2 - box.x1, box.y2 - box.y1]);
+ let availWidth = box.x2 - box.x1;
+ let availHeight = box.y2 - box.y1;
+ this._page._grid.parentSize = [availWidth, availHeight];
+ this._widgetLayoutManager.parentSize = [availWidth, availHeight];
+ this._actorLayoutManager.parentSize = [availWidth, availHeight];
+ this._box.allocate(box, flags);
+ },
+
_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;
+ adjustment.value -= (dy / this.actor.height) * adjustment.page_size;*/
return false;
},
- _getItemId: function(item) {
- if (item instanceof Shell.App)
- return item.get_id();
- else if (item instanceof GMenu.TreeDirectory)
- return item.get_menu_id();
- else
- return null;
- },
-
- _createItemIcon: function(item) {
- if (item instanceof Shell.App)
- return new AppIcon(item);
- else if (item instanceof GMenu.TreeDirectory)
- return new FolderIcon(item, this);
- else
- return null;
- },
-
- _compareItems: function(itemA, itemB) {
- // bit of a hack: rely on both ShellApp and GMenuTreeDirectory
- // having a get_name() method
- let nameA = GLib.utf8_collate_key(itemA.get_name(), -1);
- let nameB = GLib.utf8_collate_key(itemB.get_name(), -1);
- return (nameA > nameB) ? 1 : (nameA < nameB ? -1 : 0);
- },
-
addApp: function(app) {
- let appIcon = this._addItem(app);
- if (appIcon)
+ let appIcon = this._page.addItem(app);
+ /*if (appIcon)
appIcon.actor.connect('key-focus-in',
- Lang.bind(this, this._ensureIconVisible));
+ Lang.bind(this, this._ensureIconVisible));*/
},
addFolder: function(dir) {
- let folderIcon = this._addItem(dir);
- if (folderIcon)
+ let folderIcon = this._page.addItem(dir);
+ /*if (folderIcon)
folderIcon.actor.connect('key-focus-in',
- Lang.bind(this, this._ensureIconVisible));
+ Lang.bind(this, this._ensureIconVisible));*/
},
addFolderPopup: function(popup) {
+ /*
this._stack.add_actor(popup.actor);
popup.connect('open-state-changed', Lang.bind(this,
function(popup, isOpen) {
@@ -285,12 +383,12 @@ const AllView = new Lang.Class({
} else {
this._grid.actor.y = 0;
}
- }));
+ }));*/
},
- _ensureIconVisible: function(icon) {
+ /*_ensureIconVisible: function(icon) {
Util.ensureActorVisibleInScrollView(this.actor, icon);
- },
+ },*/
_updateIconOpacities: function(folderOpen) {
for (let id in this._items) {
@@ -299,6 +397,15 @@ const AllView = new Lang.Class({
else
this._items[id].actor.opacity = 255;
}
+ },
+
+ removeAll: function() {
+ this._page.removeAll();
+ },
+
+ loadGrid: function() {
+ this._page.loadGrid();
+ global.log("ZZZ visible items after load grid " + this._page._grid.visibleItemsCount());
}
});
@@ -312,6 +419,8 @@ const FrequentView = new Lang.Class({
this.actor = new St.Widget({ style_class: 'frequent-apps',
x_expand: true, y_expand: true });
this.actor.add_actor(this._grid.actor);
+
+ //global.log("Frequent visible items " + this._grid.visibleItemsCount());
this._usage = Shell.AppUsage.get_default();
},
@@ -328,6 +437,8 @@ const FrequentView = new Lang.Class({
let appIcon = new AppIcon(mostUsed[i]);
this._grid.addItem(appIcon.actor, -1);
}
+ global.log("Frequent visible items after " + this._grid.visibleItemsCount());
+ //global.log("Current frequent apps number "+mostUsed.length);
}
});
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 416e659..67f5689 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -196,6 +196,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));
+ this._currentPage = 0;
},
_getPreferredWidth: function (grid, forHeight, alloc) {
@@ -231,6 +232,7 @@ const IconGrid = new Lang.Class({
return;
let children = this._getVisibleChildren();
+ //global.log("Num children visible" + children.length);
let nColumns, spacing;
if (forWidth < 0) {
nColumns = children.length;
@@ -246,13 +248,19 @@ const IconGrid = new Lang.Class({
nRows = 0;
if (this._rowLimit)
nRows = Math.min(nRows, this._rowLimit);
+ //global.log("Rows "+nRows);
+ //global.log("Columns "+nColumns);
let totalSpacing = Math.max(0, nRows - 1) * spacing;
let height = nRows * this._vItemSize + totalSpacing;
+ //global.log("Heigth "+height);
alloc.min_size = height;
alloc.natural_size = height;
},
_allocate: function (grid, box, flags) {
+ let firstTime = true;
+ let maxChildsPerPage = 0;
+ let spacingBetweenPages = 0;
if (this._fillParent) {
// Reset the passed in box to fill the parent
let parentBox = this.actor.get_parent().allocation;
@@ -261,11 +269,14 @@ const IconGrid = new Lang.Class({
}
let children = this._getVisibleChildren();
+ //global.log("Allocate visible children " + children.length);
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
-
+ //global.log("Allocate availHeigth " + availHeight);
+ //global.log("Allocate availWidth " + availWidth);
let [nColumns, usedWidth, spacing] = this._computeLayout(availWidth);
-
+ //global.log("Allocate nColumnds " + nColumns);
+ //global.log("Allocate usedWidth " + nColumns);
let leftPadding;
switch(this._xAlign) {
case St.Align.START:
@@ -282,32 +293,29 @@ const IconGrid = new Lang.Class({
let y = box.y1;
let columnIndex = 0;
let rowIndex = 0;
+ let count1 = 0;
+ let count2 = 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;
-
+ let childBox = this._calculateChildrenBox(children[i], x, y);
+
if (this._rowLimit && rowIndex >= this._rowLimit ||
- this._fillParent && childBox.y2 > availHeight) {
- this._grid.set_skip_paint(children[i], true);
+ childBox.y2 > availHeight || this.parentSize && (childBox.y2 > this.parentSize[1]) ) {
+ if(firstTime && this.parentSize) {
+ maxChildsPerPage = count2;
+ firstTime = false;
+ spacingBetweenPages = this.parentSize[1] - ( children[i-1].y +
children[i-1].size.height);
+ y+= spacingBetweenPages;
+ global.log("Spacing between pages " + spacingBetweenPages);
+ //Recalculate child box
+ childBox = this._calculateChildrenBox(children[i], x, y);
+ }
+
+ count1 += 1;
+ children[i].allocate(childBox, flags);
+ this._grid.set_skip_paint(children[i], false);
} else {
children[i].allocate(childBox, flags);
+ count2 += 1;
this._grid.set_skip_paint(children[i], false);
}
@@ -319,15 +327,47 @@ const IconGrid = new Lang.Class({
if (columnIndex == 0) {
y += this._vItemSize + spacing;
+ if(!firstTime && count1 % maxChildsPerPage == 0)
+ {
+ y+= spacingBetweenPages;
+ }
x = box.x1 + leftPadding;
} else {
x += this._hItemSize + spacing;
}
}
+ /*global.log("Final count 1 " + count1);
+ global.log("Final count 2 " + count2);
+ global.log("Final n children " + this._grid.get_n_children());
+ global.log("Final n skip " + this._grid.get_n_skip_paint());*/
+ global.log("Allocation final visible count " + this.visibleItemsCount());
},
+ _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() {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]