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:
parent
18234ea91a
commit
40de201056
@ -1093,8 +1093,7 @@ class AppDisplay extends BaseAppView {
|
||||
}
|
||||
|
||||
_canAccept(source) {
|
||||
return (source instanceof AppIcon) ||
|
||||
(source instanceof FolderIcon);
|
||||
return source instanceof AppViewItem;
|
||||
}
|
||||
|
||||
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(
|
||||
class FolderGrid extends IconGrid.IconGrid {
|
||||
_init() {
|
||||
@ -2042,34 +2197,26 @@ var AppIcon = GObject.registerClass({
|
||||
'menu-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
|
||||
'sync-tooltip': {},
|
||||
},
|
||||
}, class AppIcon extends St.Button {
|
||||
}, class AppIcon extends AppViewItem {
|
||||
_init(app, iconParams = {}) {
|
||||
super._init({
|
||||
style_class: 'app-well-app',
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||
reactive: true,
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
|
||||
can_focus: true,
|
||||
});
|
||||
// Get the isDraggable property without passing it on to the BaseIcon:
|
||||
const appIconParams = Params.parse(iconParams, { isDraggable: true }, true);
|
||||
const isDraggable = appIconParams['isDraggable'];
|
||||
delete iconParams['isDraggable'];
|
||||
|
||||
super._init({ style_class: 'app-well-app' }, isDraggable);
|
||||
|
||||
this.app = app;
|
||||
this.id = app.get_id();
|
||||
this.name = app.get_name();
|
||||
this._id = app.get_id();
|
||||
this._name = app.get_name();
|
||||
|
||||
this._iconContainer = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true, y_expand: true });
|
||||
|
||||
this.set_child(this._iconContainer);
|
||||
|
||||
this._delegate = this;
|
||||
|
||||
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['setSizeManually'] = true;
|
||||
this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
|
||||
@ -2092,37 +2239,16 @@ var AppIcon = GObject.registerClass({
|
||||
this._menu = null;
|
||||
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._stateChangedId = this.app.connect('notify::state', () => {
|
||||
this._updateRunningStyle();
|
||||
});
|
||||
this._updateRunningStyle();
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
super._onDestroy();
|
||||
|
||||
if (this._folderPreviewId > 0) {
|
||||
GLib.source_remove(this._folderPreviewId);
|
||||
this._folderPreviewId = 0;
|
||||
@ -2130,20 +2256,15 @@ var AppIcon = GObject.registerClass({
|
||||
if (this._stateChangedId > 0)
|
||||
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._removeMenuTimeout();
|
||||
}
|
||||
|
||||
_onDragBegin() {
|
||||
this._removeMenuTimeout();
|
||||
super._onDragBegin();
|
||||
}
|
||||
|
||||
_createIcon(iconSize) {
|
||||
return this.app.create_icon_texture(iconSize);
|
||||
}
|
||||
@ -2289,19 +2410,6 @@ var AppIcon = GObject.registerClass({
|
||||
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) {
|
||||
let { stack } = new Error();
|
||||
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);
|
||||
}
|
||||
|
||||
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() {
|
||||
this.icon.label.opacity = 0;
|
||||
this.icon.icon.ease({
|
||||
@ -2372,14 +2462,9 @@ var AppIcon = GObject.registerClass({
|
||||
if (this._otherIconIsHovering == hovering)
|
||||
return;
|
||||
|
||||
this._otherIconIsHovering = hovering;
|
||||
super._setHoveringByDnd(hovering);
|
||||
|
||||
if (hovering) {
|
||||
this._dragMonitor = {
|
||||
dragMotion: this._onDragMotion.bind(this),
|
||||
};
|
||||
DND.addDragMonitor(this._dragMonitor);
|
||||
|
||||
if (this._folderPreviewId > 0)
|
||||
return;
|
||||
|
||||
@ -2391,8 +2476,6 @@ var AppIcon = GObject.registerClass({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
} else {
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
|
||||
if (this._folderPreviewId > 0) {
|
||||
GLib.source_remove(this._folderPreviewId);
|
||||
this._folderPreviewId = 0;
|
||||
@ -2402,42 +2485,9 @@ var AppIcon = GObject.registerClass({
|
||||
}
|
||||
}
|
||||
|
||||
_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))
|
||||
acceptDrop(source, actor, x) {
|
||||
const accepted = super.acceptDrop(source, actor, x);
|
||||
if (!accepted)
|
||||
return false;
|
||||
|
||||
let view = _getViewFromIcon(this);
|
||||
|
Loading…
Reference in New Issue
Block a user