iconGrid: Stop using Shell.GenericContainer
Removing Shell.GenericContainer from the IconGrid class was challenging because it needs the "skip paint" API from it. This API was added, too, as a workaround to the inability to override vfuncs from GJS. The overrides are largely copy-pasted and translated versions of the Shell.GenericContainer code. The IconGrid:key-focus-in signal was renamed to :child-focused to avoid clashing with ClutterActor:key-focus-in. In GridSearchResults, the internal IconGrid had it's y_expand set to false, so it doesn't push other search elements (the list results mainly) to the bottom of the screen. Because skip paint wasn't and still isn't a GObject property, rename it to _skipPaint to reflect that. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/153
This commit is contained in:
parent
034a723677
commit
197c0eee29
@ -130,7 +130,7 @@ var BaseAppView = new Lang.Class({
|
||||
this._childFocused(actor);
|
||||
});
|
||||
// Standard hack for ClutterBinLayout
|
||||
this._grid.actor.x_expand = true;
|
||||
this._grid.x_expand = true;
|
||||
|
||||
this._items = {};
|
||||
this._allItems = [];
|
||||
@ -203,7 +203,7 @@ var BaseAppView = new Lang.Class({
|
||||
},
|
||||
|
||||
_doSpringAnimation(animationDirection) {
|
||||
this._grid.actor.opacity = 255;
|
||||
this._grid.opacity = 255;
|
||||
this._grid.animateSpring(animationDirection,
|
||||
Main.overview.getShowAppsButton());
|
||||
},
|
||||
@ -217,8 +217,8 @@ var BaseAppView = new Lang.Class({
|
||||
}
|
||||
|
||||
if (animationDirection == IconGrid.AnimationDirection.IN) {
|
||||
let id = this._grid.actor.connect('paint', () => {
|
||||
this._grid.actor.disconnect(id);
|
||||
let id = this._grid.connect('paint', () => {
|
||||
this._grid.disconnect(id);
|
||||
this._doSpringAnimation(animationDirection);
|
||||
});
|
||||
} else {
|
||||
@ -228,7 +228,7 @@ var BaseAppView = new Lang.Class({
|
||||
|
||||
animateSwitch(animationDirection) {
|
||||
Tweener.removeTweens(this.actor);
|
||||
Tweener.removeTweens(this._grid.actor);
|
||||
Tweener.removeTweens(this._grid);
|
||||
|
||||
let params = { time: VIEWS_SWITCH_TIME,
|
||||
transition: 'easeOutQuad' };
|
||||
@ -242,7 +242,7 @@ var BaseAppView = new Lang.Class({
|
||||
params.onComplete = () => { this.actor.hide(); };
|
||||
}
|
||||
|
||||
Tweener.addTween(this._grid.actor, params);
|
||||
Tweener.addTween(this._grid, params);
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(BaseAppView.prototype);
|
||||
@ -396,7 +396,7 @@ var AllView = new Lang.Class({
|
||||
let box = new St.BoxLayout({ vertical: true });
|
||||
|
||||
this._grid.currentPage = 0;
|
||||
this._stack.add_actor(this._grid.actor);
|
||||
this._stack.add_actor(this._grid);
|
||||
this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
|
||||
this._stack.add_actor(this._eventBlocker);
|
||||
|
||||
@ -745,7 +745,7 @@ var AllView = new Lang.Class({
|
||||
box.y2 = height;
|
||||
box = this.actor.get_theme_node().get_content_box(box);
|
||||
box = this._scrollView.get_theme_node().get_content_box(box);
|
||||
box = this._grid.actor.get_theme_node().get_content_box(box);
|
||||
box = this._grid.get_theme_node().get_content_box(box);
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
let oldNPages = this._grid.nPages();
|
||||
@ -794,9 +794,9 @@ var FrequentView = new Lang.Class({
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
y_expand: true });
|
||||
|
||||
this._grid.actor.y_expand = true;
|
||||
this._grid.y_expand = true;
|
||||
|
||||
this.actor.add_actor(this._grid.actor);
|
||||
this.actor.add_actor(this._grid);
|
||||
this.actor.add_actor(this._noFrequentAppsLabel);
|
||||
this._noFrequentAppsLabel.hide();
|
||||
|
||||
@ -843,7 +843,7 @@ var FrequentView = new Lang.Class({
|
||||
box.x2 = width;
|
||||
box.y2 = height;
|
||||
box = this.actor.get_theme_node().get_content_box(box);
|
||||
box = this._grid.actor.get_theme_node().get_content_box(box);
|
||||
box = this._grid.get_theme_node().get_content_box(box);
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
this._grid.adaptToSize(availWidth, availHeight);
|
||||
@ -1141,12 +1141,12 @@ var FolderView = new Lang.Class({
|
||||
this.parent(null, null);
|
||||
// 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._grid.x_expand = true;
|
||||
|
||||
this.actor = new St.ScrollView({ overlay_scrollbars: true });
|
||||
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||
let scrollableContainer = new St.BoxLayout({ vertical: true, reactive: true });
|
||||
scrollableContainer.add_actor(this._grid.actor);
|
||||
scrollableContainer.add_actor(this._grid);
|
||||
this.actor.add_actor(scrollableContainer);
|
||||
|
||||
let action = new Clutter.PanAction({ interpolate: true });
|
||||
@ -1369,7 +1369,7 @@ var FolderIcon = new Lang.Class({
|
||||
|
||||
_updatePopupSize() {
|
||||
// StWidget delays style calculation until needed, make sure we use the correct values
|
||||
this.view._grid.actor.ensure_style();
|
||||
this.view._grid.ensure_style();
|
||||
|
||||
let offsetForEachSide = Math.ceil((this._popup.getOffset(St.Side.TOP) +
|
||||
this._popup.getOffset(St.Side.BOTTOM) -
|
||||
|
@ -189,8 +189,16 @@ function zoomOutActor(actor) {
|
||||
|
||||
var IconGrid = new Lang.Class({
|
||||
Name: 'IconGrid',
|
||||
Extends: St.Widget,
|
||||
Signals: {'animation-done': {},
|
||||
'child-focused': { param_types: [Clutter.Actor.$gtype]} },
|
||||
|
||||
_init(params) {
|
||||
this.parent({ style_class: 'icon-grid',
|
||||
y_align: Clutter.ActorAlign.START });
|
||||
|
||||
this.actor = this;
|
||||
|
||||
params = Params.parse(params, { rowLimit: null,
|
||||
columnLimit: null,
|
||||
minRows: 1,
|
||||
@ -211,30 +219,23 @@ var IconGrid = new Lang.Class({
|
||||
this.rightPadding = 0;
|
||||
this.leftPadding = 0;
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
|
||||
vertical: true });
|
||||
this._items = [];
|
||||
this._clonesAnimating = [];
|
||||
// Pulled from CSS, but hardcode some defaults here
|
||||
this._spacing = 0;
|
||||
this._hItemSize = this._vItemSize = ICON_SIZE;
|
||||
this._fixedHItemSize = this._fixedVItemSize = undefined;
|
||||
this._grid = new Shell.GenericContainer();
|
||||
this.actor.add(this._grid, { expand: true, y_align: St.Align.START });
|
||||
this.actor.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
this.connect('style-changed', this._onStyleChanged.bind(this));
|
||||
|
||||
// Cancel animations when hiding the overview, to avoid icons
|
||||
// swarming into the void ...
|
||||
this.actor.connect('notify::mapped', () => {
|
||||
if (!this.actor.mapped)
|
||||
this.connect('notify::mapped', () => {
|
||||
if (!this.mapped)
|
||||
this._cancelAnimation();
|
||||
});
|
||||
|
||||
this._grid.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this._grid.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this._grid.connect('allocate', this._allocate.bind(this));
|
||||
this._grid.connect('actor-added', this._childAdded.bind(this));
|
||||
this._grid.connect('actor-removed', this._childRemoved.bind(this));
|
||||
this.connect('actor-added', this._childAdded.bind(this));
|
||||
this.connect('actor-removed', this._childRemoved.bind(this));
|
||||
},
|
||||
|
||||
_keyFocusIn(actor) {
|
||||
@ -249,13 +250,13 @@ var IconGrid = new Lang.Class({
|
||||
child.disconnect(child._iconGridKeyFocusInId);
|
||||
},
|
||||
|
||||
_getPreferredWidth(grid, forHeight, alloc) {
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
if (this._fillParent)
|
||||
// Ignore all size requests of children and request a size of 0;
|
||||
// later we'll allocate as many children as fit the parent
|
||||
return;
|
||||
return [0, 0];
|
||||
|
||||
let nChildren = this._grid.get_n_children();
|
||||
let nChildren = this.get_n_children();
|
||||
let nColumns = this._colLimit ? Math.min(this._colLimit,
|
||||
nChildren)
|
||||
: nChildren;
|
||||
@ -263,22 +264,28 @@ var 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._getHItemSize() + this.leftPadding + this.rightPadding;
|
||||
alloc.natural_size = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
|
||||
let minSize = this._getHItemSize() + this.leftPadding + this.rightPadding;
|
||||
let natSize = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
|
||||
|
||||
return this.get_theme_node().adjust_preferred_width(minSize, natSize);
|
||||
},
|
||||
|
||||
_getVisibleChildren() {
|
||||
return this._grid.get_children().filter(actor => actor.visible);
|
||||
return this.get_children().filter(actor => actor.visible);
|
||||
},
|
||||
|
||||
_getPreferredHeight(grid, forWidth, alloc) {
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
if (this._fillParent)
|
||||
// Ignore all size requests of children and request a size of 0;
|
||||
// later we'll allocate as many children as fit the parent
|
||||
return;
|
||||
return [0, 0];
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
let children = this._getVisibleChildren();
|
||||
let nColumns;
|
||||
|
||||
forWidth = themeNode.adjust_for_width(forWidth);
|
||||
|
||||
if (forWidth < 0)
|
||||
nColumns = children.length;
|
||||
else
|
||||
@ -293,16 +300,21 @@ var IconGrid = new Lang.Class({
|
||||
nRows = Math.min(nRows, this._rowLimit);
|
||||
let totalSpacing = Math.max(0, nRows - 1) * this._getSpacing();
|
||||
let height = nRows * this._getVItemSize() + totalSpacing + this.topPadding + this.bottomPadding;
|
||||
alloc.min_size = height;
|
||||
alloc.natural_size = height;
|
||||
|
||||
return themeNode.adjust_preferred_height(height, height);
|
||||
},
|
||||
|
||||
_allocate(grid, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
box = themeNode.get_content_box(box);
|
||||
|
||||
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 parentBox = this.get_parent().allocation;
|
||||
let gridBox = themeNode.get_content_box(parentBox);
|
||||
box = themeNode.get_content_box(gridBox);
|
||||
}
|
||||
|
||||
let children = this._getVisibleChildren();
|
||||
@ -332,10 +344,10 @@ var IconGrid = new Lang.Class({
|
||||
|
||||
if (this._rowLimit && rowIndex >= this._rowLimit ||
|
||||
this._fillParent && childBox.y2 > availHeight - this.bottomPadding) {
|
||||
this._grid.set_skip_paint(children[i], true);
|
||||
children[i]._skipPaint = true;
|
||||
} else {
|
||||
children[i].allocate(childBox, flags);
|
||||
this._grid.set_skip_paint(children[i], false);
|
||||
children[i]._skipPaint = false;
|
||||
}
|
||||
|
||||
columnIndex++;
|
||||
@ -353,6 +365,66 @@ var IconGrid = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
vfunc_paint() {
|
||||
this.paint_background();
|
||||
|
||||
this.get_children().forEach(c => {
|
||||
if (!c._skipPaint)
|
||||
c.paint();
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_pick(color) {
|
||||
this.parent(color);
|
||||
|
||||
this.get_children().forEach(c => {
|
||||
if (!c._skipPaint)
|
||||
c.paint();
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_get_paint_volume(paintVolume) {
|
||||
// Setting the paint volume does not make sense when we don't have
|
||||
// any allocation
|
||||
if (!this.has_allocation())
|
||||
return false;
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
let allocationBox = this.get_allocation_box();
|
||||
let paintBox = themeNode.get_paint_box(allocationBox);
|
||||
|
||||
let origin = new Clutter.Vertex();
|
||||
origin.x = paintBox.x1 - allocationBox.x1;
|
||||
origin.y = paintBox.y1 - allocationBox.y1;
|
||||
origin.z = 0.0;
|
||||
|
||||
paintVolume.set_origin(origin);
|
||||
paintVolume.set_width(paintBox.x2 - paintBox.x1);
|
||||
paintVolume.set_height(paintBox.y2 - paintBox.y1);
|
||||
|
||||
if (this.get_clip_to_allocation())
|
||||
return true;
|
||||
|
||||
for (let child = this.get_first_child();
|
||||
child != null;
|
||||
child = child.get_next_sibling()) {
|
||||
|
||||
if (!child.visible)
|
||||
continue;
|
||||
|
||||
if (child._skipPaint)
|
||||
continue;
|
||||
|
||||
let childVolume = child.get_transformed_paint_volume(this);
|
||||
if (!childVolume)
|
||||
return false
|
||||
|
||||
paintVolume.union(childVolume);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Intended to be override by subclasses if they need a different
|
||||
* set of items to be animated.
|
||||
@ -589,11 +661,11 @@ var IconGrid = new Lang.Class({
|
||||
},
|
||||
|
||||
_onStyleChanged() {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let themeNode = this.get_theme_node();
|
||||
this._spacing = themeNode.get_length('spacing');
|
||||
this._hItemSize = themeNode.get_length('-shell-grid-horizontal-item-size') || ICON_SIZE;
|
||||
this._vItemSize = themeNode.get_length('-shell-grid-vertical-item-size') || ICON_SIZE;
|
||||
this._grid.queue_relayout();
|
||||
this.queue_relayout();
|
||||
},
|
||||
|
||||
nRows(forWidth) {
|
||||
@ -625,12 +697,12 @@ var IconGrid = new Lang.Class({
|
||||
|
||||
removeAll() {
|
||||
this._items = [];
|
||||
this._grid.remove_all_children();
|
||||
this.remove_all_children();
|
||||
},
|
||||
|
||||
destroyAll() {
|
||||
this._items = [];
|
||||
this._grid.destroy_all_children();
|
||||
this.destroy_all_children();
|
||||
},
|
||||
|
||||
addItem(item, index) {
|
||||
@ -639,21 +711,21 @@ var IconGrid = new Lang.Class({
|
||||
|
||||
this._items.push(item);
|
||||
if (index !== undefined)
|
||||
this._grid.insert_child_at_index(item.actor, index);
|
||||
this.insert_child_at_index(item.actor, index);
|
||||
else
|
||||
this._grid.add_actor(item.actor);
|
||||
this.add_actor(item.actor);
|
||||
},
|
||||
|
||||
removeItem(item) {
|
||||
this._grid.remove_child(item.actor);
|
||||
this.remove_child(item.actor);
|
||||
},
|
||||
|
||||
getItemAtIndex(index) {
|
||||
return this._grid.get_child_at_index(index);
|
||||
return this.get_child_at_index(index);
|
||||
},
|
||||
|
||||
visibleItemsCount() {
|
||||
return this._grid.get_n_children() - this._grid.get_n_skip_paint();
|
||||
return this.get_children().filter(c => !c._skipPaint).length;
|
||||
},
|
||||
|
||||
setSpacing(spacing) {
|
||||
@ -739,11 +811,12 @@ var IconGrid = new Lang.Class({
|
||||
}
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(IconGrid.prototype);
|
||||
|
||||
var PaginatedIconGrid = new Lang.Class({
|
||||
Name: 'PaginatedIconGrid',
|
||||
Extends: IconGrid,
|
||||
Signals: {'space-opened': {},
|
||||
'space-closed': {} },
|
||||
|
||||
_init(params) {
|
||||
this.parent(params);
|
||||
@ -754,20 +827,22 @@ var PaginatedIconGrid = new Lang.Class({
|
||||
this._childrenPerPage = 0;
|
||||
},
|
||||
|
||||
_getPreferredHeight(grid, forWidth, alloc) {
|
||||
alloc.min_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
|
||||
alloc.natural_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let height = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
|
||||
return [height, height];
|
||||
},
|
||||
|
||||
_allocate(grid, box, flags) {
|
||||
vfunc_allocate(box, flags) {
|
||||
if (this._childrenPerPage == 0)
|
||||
log('computePages() must be called before allocate(); pagination will not work.');
|
||||
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
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 parentBox = this.get_parent().allocation;
|
||||
let gridBox = this.get_theme_node().get_content_box(parentBox);
|
||||
box = this.get_theme_node().get_content_box(gridBox);
|
||||
}
|
||||
let children = this._getVisibleChildren();
|
||||
let availWidth = box.x2 - box.x1;
|
||||
@ -795,7 +870,7 @@ var PaginatedIconGrid = new Lang.Class({
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let childBox = this._calculateChildBox(children[i], x, y, box);
|
||||
children[i].allocate(childBox, flags);
|
||||
this._grid.set_skip_paint(children[i], false);
|
||||
children[i]._skipPaint = false;
|
||||
|
||||
columnIndex++;
|
||||
if (columnIndex == nColumns) {
|
||||
@ -966,4 +1041,3 @@ var PaginatedIconGrid = new Lang.Class({
|
||||
}
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(PaginatedIconGrid.prototype);
|
||||
|
@ -363,8 +363,9 @@ var GridSearchResults = new Lang.Class({
|
||||
|
||||
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
|
||||
xAlign: St.Align.START });
|
||||
|
||||
this._bin = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||
this._bin.set_child(this._grid.actor);
|
||||
this._bin.set_child(this._grid);
|
||||
|
||||
this._resultDisplayBin.set_child(this._bin);
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user