appDisplay: Factor out draggable code into AppViewItem

This will be shared by the FolderIcon.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
This commit is contained in:
Georges Basile Stavracas Neto 2020-05-26 18:05:40 -03:00 committed by Florian Müllner
parent 18234ea91a
commit 40de201056

View File

@ -1093,8 +1093,7 @@ class AppDisplay extends BaseAppView {
} }
_canAccept(source) { _canAccept(source) {
return (source instanceof AppIcon) || return source instanceof AppViewItem;
(source instanceof FolderIcon);
} }
handleDragOver(source) { handleDragOver(source) {
@ -1249,6 +1248,162 @@ var AppSearchProvider = class AppSearchProvider {
} }
}; };
var AppViewItem = GObject.registerClass(
class AppViewItem extends St.Button {
_init(params = {}, isDraggable = true) {
super._init({
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
reactive: true,
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
can_focus: true,
...params,
});
this._delegate = this;
if (isDraggable) {
this._draggable = DND.makeDraggable(this);
this._draggable.connect('drag-begin', this._onDragBegin.bind(this));
this._draggable.connect('drag-cancelled', this._onDragCancelled.bind(this));
this._draggable.connect('drag-end', this._onDragEnd.bind(this));
}
this._otherIconIsHovering = false;
this.connect('destroy', this._onDestroy.bind(this));
}
_onDestroy() {
if (this._dragMonitor) {
DND.removeDragMonitor(this._dragMonitor);
this._dragMonitor = null;
}
if (this._draggable) {
if (this._dragging)
Main.overview.endItemDrag(this);
this._draggable = null;
}
}
_onDragBegin() {
this._dragging = true;
this.scaleAndFade();
Main.overview.beginItemDrag(this);
}
_onDragCancelled() {
this._dragging = false;
Main.overview.cancelledItemDrag(this);
}
_onDragEnd() {
this._dragging = false;
this.undoScaleAndFade();
Main.overview.endItemDrag(this);
}
scaleIn() {
this.scale_x = 0;
this.scale_y = 0;
this.ease({
scale_x: 1,
scale_y: 1,
duration: APP_ICON_SCALE_IN_TIME,
delay: APP_ICON_SCALE_IN_DELAY,
mode: Clutter.AnimationMode.EASE_OUT_QUINT,
});
}
scaleAndFade() {
this.reactive = false;
this.ease({
scale_x: 0.75,
scale_y: 0.75,
opacity: 128,
});
}
undoScaleAndFade() {
this.reactive = true;
this.ease({
scale_x: 1.0,
scale_y: 1.0,
opacity: 255,
});
}
_canAccept(source) {
return source !== this;
}
_setHoveringByDnd(hovering) {
if (this._otherIconIsHovering === hovering)
return;
this._otherIconIsHovering = hovering;
if (hovering) {
this._dragMonitor = {
dragMotion: this._onDragMotion.bind(this),
};
DND.addDragMonitor(this._dragMonitor);
} else {
DND.removeDragMonitor(this._dragMonitor);
}
}
_onDragMotion(dragEvent) {
if (!this.contains(dragEvent.targetActor))
this._setHoveringByDnd(false);
return DND.DragMotionResult.CONTINUE;
}
_withinLeeways(x) {
return x < IconGrid.LEFT_DIVIDER_LEEWAY ||
x > this.width - IconGrid.RIGHT_DIVIDER_LEEWAY;
}
handleDragOver(source, _actor, x) {
if (source === this)
return DND.DragMotionResult.NO_DROP;
if (!this._canAccept(source))
return DND.DragMotionResult.CONTINUE;
if (this._withinLeeways(x)) {
this._setHoveringByDnd(false);
return DND.DragMotionResult.CONTINUE;
}
this._setHoveringByDnd(true);
return DND.DragMotionResult.MOVE_DROP;
}
acceptDrop(source, _actor, x) {
this._setHoveringByDnd(false);
if (!this._canAccept(source))
return false;
if (this._withinLeeways(x))
return DND.DragMotionResult.CONTINUE;
return true;
}
get id() {
return this._id;
}
get name() {
return this._name;
}
});
var FolderGrid = GObject.registerClass( var FolderGrid = GObject.registerClass(
class FolderGrid extends IconGrid.IconGrid { class FolderGrid extends IconGrid.IconGrid {
_init() { _init() {
@ -2042,34 +2197,26 @@ var AppIcon = GObject.registerClass({
'menu-state-changed': { param_types: [GObject.TYPE_BOOLEAN] }, 'menu-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
'sync-tooltip': {}, 'sync-tooltip': {},
}, },
}, class AppIcon extends St.Button { }, class AppIcon extends AppViewItem {
_init(app, iconParams = {}) { _init(app, iconParams = {}) {
super._init({ // Get the isDraggable property without passing it on to the BaseIcon:
style_class: 'app-well-app', const appIconParams = Params.parse(iconParams, { isDraggable: true }, true);
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }), const isDraggable = appIconParams['isDraggable'];
reactive: true, delete iconParams['isDraggable'];
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
can_focus: true, super._init({ style_class: 'app-well-app' }, isDraggable);
});
this.app = app; this.app = app;
this.id = app.get_id(); this._id = app.get_id();
this.name = app.get_name(); this._name = app.get_name();
this._iconContainer = new St.Widget({ layout_manager: new Clutter.BinLayout(), this._iconContainer = new St.Widget({ layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true }); x_expand: true, y_expand: true });
this.set_child(this._iconContainer); this.set_child(this._iconContainer);
this._delegate = this;
this._folderPreviewId = 0; this._folderPreviewId = 0;
// Get the isDraggable property without passing it on to the BaseIcon:
let appIconParams = Params.parse(iconParams, { isDraggable: true }, true);
let isDraggable = appIconParams['isDraggable'];
delete iconParams['isDraggable'];
iconParams['createIcon'] = this._createIcon.bind(this); iconParams['createIcon'] = this._createIcon.bind(this);
iconParams['setSizeManually'] = true; iconParams['setSizeManually'] = true;
this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams); this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
@ -2092,37 +2239,16 @@ var AppIcon = GObject.registerClass({
this._menu = null; this._menu = null;
this._menuManager = new PopupMenu.PopupMenuManager(this); this._menuManager = new PopupMenu.PopupMenuManager(this);
if (isDraggable) {
this._draggable = DND.makeDraggable(this);
this._draggable.connect('drag-begin', () => {
this._dragging = true;
this.scaleAndFade();
this._removeMenuTimeout();
Main.overview.beginItemDrag(this);
});
this._draggable.connect('drag-cancelled', () => {
this._dragging = false;
Main.overview.cancelledItemDrag(this);
});
this._draggable.connect('drag-end', () => {
this._dragging = false;
this.undoScaleAndFade();
Main.overview.endItemDrag(this);
});
}
this._otherIconIsHovering = false;
this._menuTimeoutId = 0; this._menuTimeoutId = 0;
this._stateChangedId = this.app.connect('notify::state', () => { this._stateChangedId = this.app.connect('notify::state', () => {
this._updateRunningStyle(); this._updateRunningStyle();
}); });
this._updateRunningStyle(); this._updateRunningStyle();
this.connect('destroy', this._onDestroy.bind(this));
} }
_onDestroy() { _onDestroy() {
super._onDestroy();
if (this._folderPreviewId > 0) { if (this._folderPreviewId > 0) {
GLib.source_remove(this._folderPreviewId); GLib.source_remove(this._folderPreviewId);
this._folderPreviewId = 0; this._folderPreviewId = 0;
@ -2130,20 +2256,15 @@ var AppIcon = GObject.registerClass({
if (this._stateChangedId > 0) if (this._stateChangedId > 0)
this.app.disconnect(this._stateChangedId); this.app.disconnect(this._stateChangedId);
if (this._dragMonitor) {
DND.removeDragMonitor(this._dragMonitor);
this._dragMonitor = null;
}
if (this._draggable) {
if (this._dragging)
Main.overview.endItemDrag(this);
this._draggable = null;
}
this._stateChangedId = 0; this._stateChangedId = 0;
this._removeMenuTimeout(); this._removeMenuTimeout();
} }
_onDragBegin() {
this._removeMenuTimeout();
super._onDragBegin();
}
_createIcon(iconSize) { _createIcon(iconSize) {
return this.app.create_icon_texture(iconSize); return this.app.create_icon_texture(iconSize);
} }
@ -2289,19 +2410,6 @@ var AppIcon = GObject.registerClass({
this.icon.animateZoomOutAtPos(x, y); this.icon.animateZoomOutAtPos(x, y);
} }
scaleIn() {
this.scale_x = 0;
this.scale_y = 0;
this.ease({
scale_x: 1,
scale_y: 1,
duration: APP_ICON_SCALE_IN_TIME,
delay: APP_ICON_SCALE_IN_DELAY,
mode: Clutter.AnimationMode.EASE_OUT_QUINT,
});
}
shellWorkspaceLaunch(params) { shellWorkspaceLaunch(params) {
let { stack } = new Error(); let { stack } = new Error();
log('shellWorkspaceLaunch is deprecated, use app.open_new_window() instead\n%s'.format(stack)); log('shellWorkspaceLaunch is deprecated, use app.open_new_window() instead\n%s'.format(stack));
@ -2326,24 +2434,6 @@ var AppIcon = GObject.registerClass({
return this.hover && (!this._menu || !this._menu.isOpen); return this.hover && (!this._menu || !this._menu.isOpen);
} }
scaleAndFade() {
this.reactive = false;
this.ease({
scale_x: 0.75,
scale_y: 0.75,
opacity: 128,
});
}
undoScaleAndFade() {
this.reactive = true;
this.ease({
scale_x: 1.0,
scale_y: 1.0,
opacity: 255,
});
}
_showFolderPreview() { _showFolderPreview() {
this.icon.label.opacity = 0; this.icon.label.opacity = 0;
this.icon.icon.ease({ this.icon.icon.ease({
@ -2372,14 +2462,9 @@ var AppIcon = GObject.registerClass({
if (this._otherIconIsHovering == hovering) if (this._otherIconIsHovering == hovering)
return; return;
this._otherIconIsHovering = hovering; super._setHoveringByDnd(hovering);
if (hovering) { if (hovering) {
this._dragMonitor = {
dragMotion: this._onDragMotion.bind(this),
};
DND.addDragMonitor(this._dragMonitor);
if (this._folderPreviewId > 0) if (this._folderPreviewId > 0)
return; return;
@ -2391,8 +2476,6 @@ var AppIcon = GObject.registerClass({
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}); });
} else { } else {
DND.removeDragMonitor(this._dragMonitor);
if (this._folderPreviewId > 0) { if (this._folderPreviewId > 0) {
GLib.source_remove(this._folderPreviewId); GLib.source_remove(this._folderPreviewId);
this._folderPreviewId = 0; this._folderPreviewId = 0;
@ -2402,42 +2485,9 @@ var AppIcon = GObject.registerClass({
} }
} }
_onDragMotion(dragEvent) { acceptDrop(source, actor, x) {
if (!this.contains(dragEvent.targetActor)) const accepted = super.acceptDrop(source, actor, x);
this._setHoveringByDnd(false); if (!accepted)
return DND.DragMotionResult.CONTINUE;
}
_withinLeeways(x) {
return x < IconGrid.LEFT_DIVIDER_LEEWAY ||
x > this.width - IconGrid.RIGHT_DIVIDER_LEEWAY;
}
handleDragOver(source, _actor, x) {
if (source == this)
return DND.DragMotionResult.NO_DROP;
if (!this._canAccept(source))
return DND.DragMotionResult.CONTINUE;
if (this._withinLeeways(x)) {
this._setHoveringByDnd(false);
return DND.DragMotionResult.CONTINUE;
}
this._setHoveringByDnd(true);
return DND.DragMotionResult.MOVE_DROP;
}
acceptDrop(source, _actor, x) {
this._setHoveringByDnd(false);
if (!this._canAccept(source))
return false;
if (this._withinLeeways(x))
return false; return false;
let view = _getViewFromIcon(this); let view = _getViewFromIcon(this);