dash: Calculate icon size changes without reallocation

The current approach to adjust the icon size of dash items is rather
expensive: the size of each item is changed from largest to smallest,
until the height of the dash fits the maximum available height, so
quite some ClutterTextures are created and disposed.
A better approach is to calculate the required size beforehand and
only change the icon size when necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=636156
This commit is contained in:
Florian Müllner 2010-11-27 22:31:14 +01:00
parent 4d474e2f9c
commit 5aab878e75

View File

@ -203,9 +203,51 @@ Dash.prototype = {
Lang.bind(this, function() { Lang.bind(this, function() {
display.actor.opacity = 255; display.actor.opacity = 255;
})); }));
display.icon.setIconSize(this._iconSize);
this._box.add(display.actor); this._box.add(display.actor);
}, },
_adjustIconSize: function() {
let children = this._box.get_children();
if (children.length == 0) {
this._box.add_style_pseudo_class('empty');
return;
}
this._box.remove_style_pseudo_class('empty');
if (this._maxHeight == -1)
return;
let iconChildren = children.filter(function(actor) {
return actor.visible && actor._delegate && actor._delegate.icon;
});
// Compute the amount of extra space (or missing space) we have
// per icon with the current icon size
let [minHeight, natHeight] = this.actor.get_preferred_height(-1);
let diff = (this._maxHeight - natHeight) / iconChildren.length;
let iconSizes = [ 16, 22, 24, 32, 48 ];
let newIconSize = 16;
for (let i = 0; i < iconSizes.length; i++) {
if (iconSizes[i] < this._iconSize + diff)
newIconSize = iconSizes[i];
}
if (newIconSize == this._iconSize)
return;
this._iconSize = newIconSize;
for (let i = 0; i < iconChildren.length; i++) {
let icon = iconChildren[i]._delegate.icon;
icon.setIconSize(this._iconSize);
}
},
_redisplay: function () { _redisplay: function () {
this._box.hide(); this._box.hide();
this._box.destroy_children(); this._box.destroy_children();
@ -229,29 +271,7 @@ Dash.prototype = {
this._addApp(app); this._addApp(app);
} }
let children = this._box.get_children(); this._adjustIconSize();
if (children.length == 0) {
this._box.add_style_pseudo_class('empty');
} else {
this._box.remove_style_pseudo_class('empty');
if (this._maxHeight > -1) {
let iconSizes = [ 48, 32, 24, 22, 16 ];
for (let i = 0; i < iconSizes.length; i++) {
let minHeight, natHeight;
this._iconSize = iconSizes[i];
for (let j = 0; j < children.length; j++)
children[j]._delegate.icon.setIconSize(this._iconSize);
[minHeight, natHeight] = this.actor.get_preferred_height(-1);
if (natHeight <= this._maxHeight)
break;
}
}
}
this._box.show(); this._box.show();
}, },