appDisplay: Move from instanceof-testing to polymorphic duck typing
Instead of having _compareItems, _getItemId, etc. on the view to pull out info about items, use the AppIcon / FolderIcon items we create as a place to track this additional info. We now require that these items have a '.id' property for deduplication, and a '.name' property to sort by.
This commit is contained in:
parent
cc4659f5c6
commit
2298ca8283
@ -97,40 +97,22 @@ const BaseAppView = new Lang.Class({
|
|||||||
this._allItems = [];
|
this._allItems = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
_getItemId: function(item) {
|
_addItem: function(icon) {
|
||||||
throw new Error('Not implemented');
|
let id = icon.id;
|
||||||
},
|
|
||||||
|
|
||||||
_createItemIcon: function(item) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
_compareItems: function(a, b) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
_addItem: function(item) {
|
|
||||||
let id = this._getItemId(item);
|
|
||||||
if (this._items[id] !== undefined)
|
if (this._items[id] !== undefined)
|
||||||
return null;
|
return;
|
||||||
|
|
||||||
let itemIcon = this._createItemIcon(item);
|
this._allItems.push(icon);
|
||||||
this._allItems.push(item);
|
this._items[id] = icon;
|
||||||
this._items[id] = itemIcon;
|
|
||||||
|
|
||||||
return itemIcon;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadGrid: function() {
|
loadGrid: function() {
|
||||||
this._allItems.sort(Lang.bind(this, this._compareItems));
|
this._allItems.sort(Lang.bind(this, function(a, b) {
|
||||||
|
return a.name.localeCompare(b.name);
|
||||||
for (let i = 0; i < this._allItems.length; i++) {
|
}));
|
||||||
let id = this._getItemId(this._allItems[i]);
|
this._allItems.forEach(Lang.bind(this, function(item) {
|
||||||
if (!id)
|
this._grid.addItem(item);
|
||||||
continue;
|
}));
|
||||||
this._grid.addItem(this._items[id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emit('view-loaded');
|
this.emit('view-loaded');
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -467,50 +449,26 @@ const AllView = new Lang.Class({
|
|||||||
return Clutter.EVENT_PROPAGATE;
|
return Clutter.EVENT_PROPAGATE;
|
||||||
},
|
},
|
||||||
|
|
||||||
_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);
|
|
||||||
},
|
|
||||||
|
|
||||||
removeAll: function() {
|
removeAll: function() {
|
||||||
this._folderIcons = [];
|
this._folderIcons = [];
|
||||||
this.parent();
|
this.parent();
|
||||||
},
|
},
|
||||||
|
|
||||||
addApp: function(app) {
|
addApp: function(app) {
|
||||||
let appIcon = this._addItem(app);
|
let icon = new AppIcon(app);
|
||||||
if (appIcon)
|
this._addItem(icon);
|
||||||
appIcon.actor.connect('key-focus-in',
|
if (icon)
|
||||||
Lang.bind(this, this._ensureIconVisible));
|
icon.actor.connect('key-focus-in',
|
||||||
|
Lang.bind(this, this._ensureIconVisible));
|
||||||
},
|
},
|
||||||
|
|
||||||
addFolder: function(dir) {
|
addFolder: function(dir) {
|
||||||
let folderIcon = this._addItem(dir);
|
let icon = new FolderIcon(dir, this);
|
||||||
this._folderIcons.push(folderIcon);
|
this._addItem(icon);
|
||||||
if (folderIcon)
|
this._folderIcons.push(icon);
|
||||||
folderIcon.actor.connect('key-focus-in',
|
if (icon)
|
||||||
Lang.bind(this, this._ensureIconVisible));
|
icon.actor.connect('key-focus-in',
|
||||||
|
Lang.bind(this, this._ensureIconVisible));
|
||||||
},
|
},
|
||||||
|
|
||||||
addFolderPopup: function(popup) {
|
addFolderPopup: function(popup) {
|
||||||
@ -956,20 +914,9 @@ const FolderView = new Lang.Class({
|
|||||||
this.actor.add_action(action);
|
this.actor.add_action(action);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getItemId: function(item) {
|
|
||||||
return item.get_id();
|
|
||||||
},
|
|
||||||
|
|
||||||
_createItemIcon: function(item) {
|
|
||||||
return new AppIcon(item);
|
|
||||||
},
|
|
||||||
|
|
||||||
_compareItems: function(a, b) {
|
|
||||||
return a.compare_by_name(b);
|
|
||||||
},
|
|
||||||
|
|
||||||
addApp: function(app) {
|
addApp: function(app) {
|
||||||
this._addItem(app);
|
let icon = new AppIcon(app);
|
||||||
|
this._addItem(icon);
|
||||||
},
|
},
|
||||||
|
|
||||||
createFolderIcon: function(size) {
|
createFolderIcon: function(size) {
|
||||||
@ -980,7 +927,7 @@ const FolderView = new Lang.Class({
|
|||||||
|
|
||||||
let aligns = [ Clutter.ActorAlign.START, Clutter.ActorAlign.END ];
|
let aligns = [ Clutter.ActorAlign.START, Clutter.ActorAlign.END ];
|
||||||
for (let i = 0; i < Math.min(this._allItems.length, 4); i++) {
|
for (let i = 0; i < Math.min(this._allItems.length, 4); i++) {
|
||||||
let texture = this._allItems[i].create_icon_texture(subSize);
|
let texture = this._allItems[i].app.create_icon_texture(subSize);
|
||||||
let bin = new St.Bin({ child: texture,
|
let bin = new St.Bin({ child: texture,
|
||||||
x_expand: true, y_expand: true });
|
x_expand: true, y_expand: true });
|
||||||
bin.set_x_align(aligns[i % 2]);
|
bin.set_x_align(aligns[i % 2]);
|
||||||
@ -1059,6 +1006,9 @@ const FolderIcon = new Lang.Class({
|
|||||||
|
|
||||||
_init: function(dir, parentView) {
|
_init: function(dir, parentView) {
|
||||||
this._dir = dir;
|
this._dir = dir;
|
||||||
|
this.id = dir.get_menu_id();
|
||||||
|
this.name = dir.get_name();
|
||||||
|
|
||||||
this._parentView = parentView;
|
this._parentView = parentView;
|
||||||
|
|
||||||
this.actor = new St.Button({ style_class: 'app-well-app app-folder',
|
this.actor = new St.Button({ style_class: 'app-well-app app-folder',
|
||||||
@ -1071,8 +1021,7 @@ const FolderIcon = new Lang.Class({
|
|||||||
// whether we need to update arrow side, position etc.
|
// whether we need to update arrow side, position etc.
|
||||||
this._popupInvalidated = false;
|
this._popupInvalidated = false;
|
||||||
|
|
||||||
let label = this._dir.get_name();
|
this.icon = new IconGrid.BaseIcon(this.name,
|
||||||
this.icon = new IconGrid.BaseIcon(label,
|
|
||||||
{ createIcon: Lang.bind(this, this._createIcon), setSizeManually: true });
|
{ createIcon: Lang.bind(this, this._createIcon), setSizeManually: true });
|
||||||
this.actor.set_child(this.icon.actor);
|
this.actor.set_child(this.icon.actor);
|
||||||
this.actor.label_actor = this.icon.label;
|
this.actor.label_actor = this.icon.label;
|
||||||
@ -1288,6 +1237,9 @@ const AppIcon = new Lang.Class({
|
|||||||
|
|
||||||
_init : function(app, iconParams) {
|
_init : function(app, iconParams) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
this.id = app.get_id();
|
||||||
|
this.name = app.get_name();
|
||||||
|
|
||||||
this.actor = new St.Button({ style_class: 'app-well-app',
|
this.actor = new St.Button({ style_class: 'app-well-app',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
|
||||||
|
Loading…
Reference in New Issue
Block a user