[gnome-shell/gbsneto/custom-icon-positions: 9/17] appDisplay: Factor out draggable code into BaseAppIcon



commit 940f35f5ac17f7c16219e712e4f0bebad31604bc
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue May 26 18:05:40 2020 -0300

    appDisplay: Factor out draggable code into BaseAppIcon
    
    This will be shared by the FolderIcon.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284

 js/ui/appDisplay.js | 289 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 172 insertions(+), 117 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 9c78103ec8..ecb9fea5f0 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -1081,8 +1081,7 @@ class AppDisplay extends BaseAppView {
     }
 
     _canAccept(source) {
-        return (source instanceof AppIcon) ||
-            (source instanceof FolderIcon);
+        return source instanceof BaseAppIcon;
     }
 
     handleDragOver(source) {
@@ -1237,6 +1236,158 @@ var AppSearchProvider = class AppSearchProvider {
     }
 };
 
+var BaseAppIcon = GObject.registerClass({
+    Signals: {
+        'menu-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
+        'sync-tooltip': {},
+    },
+}, class BaseAppIcon extends St.Button {
+    _init(params = {}, isDraggable = true) {
+        params = Params.parse(params, {
+            pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
+            reactive: true,
+            button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
+            can_focus: true,
+        }, true);
+
+        super._init(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;
+    }
+
+    handleDragOver(source, _actor, x) {
+        if (source === this)
+            return DND.DragMotionResult.NO_DROP;
+
+        if (!this._canAccept(source))
+            return DND.DragMotionResult.CONTINUE;
+
+        if (x < IconGrid.LEFT_DIVIDER_LEEWAY ||
+            x + IconGrid.RIGHT_DIVIDER_LEEWAY > this.width)
+            return DND.DragMotionResult.CONTINUE;
+
+        this._setHoveringByDnd(true);
+
+        return DND.DragMotionResult.MOVE_DROP;
+    }
+
+    acceptDrop(source) {
+        this._setHoveringByDnd(false);
+
+        if (!this._canAccept(source))
+            return false;
+
+        return true;
+    }
+
+    get id() {
+        return this._id;
+    }
+
+    get name() {
+        return this._name;
+    }
+});
+
 var FolderGrid = GObject.registerClass(
 class FolderGrid extends IconGrid.IconGrid {
     _init() {
@@ -2030,34 +2181,26 @@ var AppIcon = GObject.registerClass({
         'menu-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
         'sync-tooltip': {},
     },
-}, class AppIcon extends St.Button {
+}, class AppIcon extends BaseAppIcon {
     _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);
@@ -2080,37 +2223,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;
@@ -2118,20 +2240,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);
     }
@@ -2277,19 +2394,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));
@@ -2314,24 +2418,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({
@@ -2360,14 +2446,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;
 
@@ -2379,8 +2460,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;
@@ -2390,33 +2469,9 @@ var AppIcon = GObject.registerClass({
         }
     }
 
-    _onDragMotion(dragEvent) {
-        if (!this.contains(dragEvent.targetActor))
-            this._setHoveringByDnd(false);
-
-        return DND.DragMotionResult.CONTINUE;
-    }
-
-    handleDragOver(source, _actor, x) {
-        if (source == this)
-            return DND.DragMotionResult.NO_DROP;
-
-        if (!this._canAccept(source))
-            return DND.DragMotionResult.CONTINUE;
-
-        if (x < IconGrid.LEFT_DIVIDER_LEEWAY ||
-            x + IconGrid.RIGHT_DIVIDER_LEEWAY > this.width)
-            return DND.DragMotionResult.CONTINUE;
-
-        this._setHoveringByDnd(true);
-
-        return DND.DragMotionResult.MOVE_DROP;
-    }
-
     acceptDrop(source) {
-        this._setHoveringByDnd(false);
-
-        if (!this._canAccept(source))
+        const accepted = super.acceptDrop(source);
+        if (!accepted)
             return false;
 
         let view = _getViewFromIcon(this);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]