[gnome-shell/gbsneto/icon-grid-dnd: 108/117] allView, folderView: Implement moving icons



commit 436d7a03176f070aaf59a440606c4575f1ef395e
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Jul 2 17:42:29 2019 -0300

    allView, folderView: Implement moving icons
    
    This makes use of the new BaseAppIcon.moveItem() API.
    
    WIP: write a proper commit message
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/603

 js/ui/appDisplay.js | 107 +++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 90 insertions(+), 17 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index f29cc8c15..17e2179eb 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -510,6 +510,37 @@ var AllView = class AllView extends BaseAppView {
         return newApps;
     }
 
+    moveItem(item, position) {
+        let visibleApps = this._allItems.filter(icon => icon.actor.visible);
+        let oldPosition = visibleApps.indexOf(item);
+
+        if (oldPosition == position)
+            return;
+
+        super.moveItem(item, position);
+
+        if (position > oldPosition)
+            position -= 1;
+
+        // Update all custom icon positions to match what's visible
+        visibleApps = this._allItems.filter(icon => icon.actor.visible);
+        let iconsData = this._gridSettings.get_value('icons-data').deep_unpack();
+        visibleApps.forEach((icon, index) => {
+            if (!iconsData[icon.id] || icon.id == item.id)
+                return;
+
+            iconsData[icon.id] = new GLib.Variant('a{sv}', {
+                'position': GLib.Variant.new_uint32(index),
+            });
+        });
+
+        iconsData[item.id] = new GLib.Variant('a{sv}', {
+            'position': GLib.Variant.new_uint32(position),
+        });
+        this._gridSettings.set_value('icons-data',
+            new GLib.Variant('a{sv}', iconsData));
+    }
+
     _loadGrid() {
         super._loadGrid();
         this._refilterApps();
@@ -810,41 +841,53 @@ var AllView = class AllView extends BaseAppView {
     }
 
     _onDragEnd() {
+        this.removeNudges();
+
         if (this._dragMonitor) {
             DND.removeDragMonitor(this._dragMonitor);
             this._dragMonitor = null;
         }
     }
 
-    _canDropAt(source) {
-        if (!(source instanceof AppIcon))
-            return false;
+    handleDragOver(source, actor, x, y, time) {
+        let sourceIndex = -1;
+        if (source.view == this) {
+            let visibleItems = this._allItems.filter(item => item.actor.visible);
+            sourceIndex = visibleItems.indexOf(source);
+        }
 
-        if (!global.settings.is_writable('favorite-apps'))
-            return false;
+        let [index, dragLocation] = this.canDropAt(x, y);
 
-        if (!(source.view instanceof FolderView))
-            return false;
+        this.removeNudges();
+        if (source.view && source.view != this)
+            source.view.removeNudges();
 
-        return true;
-    }
+        if (index != -1) {
+            if (sourceIndex == -1 || (index != sourceIndex && index != sourceIndex + 1))
+                this.nudgeItemsAtIndex(index, dragLocation);
 
-    handleDragOver(source, actor, x, y, time) {
-        if (!this._canDropAt(source))
-            return DND.DragMotionResult.NO_DROP;
+            return DND.DragMotionResult.MOVE_DROP;
+        }
 
-        return DND.DragMotionResult.MOVE_DROP;
+        return DND.DragMotionResult.NO_DROP;
     }
 
     acceptDrop(source, actor, x, y, time) {
-        if (!this._canDropAt(source))
+        let [index, dragLocation] = this.canDropAt(x, y);
+
+        if (index == -1)
             return false;
 
-        source.view.removeApp(source.app);
+        if (source.view instanceof FolderView) {
+            source.view.removeApp(source.app);
+            source = this._items[source.id];
 
-        if (this._currentPopup)
-            this._currentPopup.popdown();
+            if (this._currentPopup)
+                this._currentPopup.popdown();
+        }
 
+        this.moveItem(source, index);
+        this.removeNudges();
         return true;
     }
 
@@ -1292,6 +1335,29 @@ var FolderView = class FolderView extends BaseAppView {
         this.actor.set_height(this.usedHeight());
     }
 
+    handleDragOver(source, actor, x, y, time) {
+        let [index, dragLocation] = this.canDropAt(x, y);
+        let sourceIndex = this._allItems.indexOf(source);
+
+        this._parentView.removeNudges();
+        this.removeNudges();
+        if (index != -1 && index != sourceIndex && index != sourceIndex + 1)
+            this.nudgeItemsAtIndex(index, dragLocation);
+
+        return DND.DragMotionResult.MOVE_DROP;
+    }
+
+    acceptDrop(source, actor, x, y, time) {
+        let [index, dragLocation] = this.canDropAt(x, y);
+        let success = index != -1;
+
+        if (success)
+            this.moveItem(source, index);
+
+        this.removeNudges();
+        return success;
+    }
+
     _getPageAvailableSize() {
         let pageBox = new Clutter.ActorBox();
         pageBox.x1 = pageBox.y1 = 0;
@@ -1373,6 +1439,13 @@ var FolderView = class FolderView extends BaseAppView {
 
         return true;
     }
+
+    moveItem(item, newPosition) {
+        super.moveItem(item, newPosition);
+
+        let appIds = this._allItems.map(icon => icon.id);
+        this._folder.set_strv('apps', appIds);
+    }
 };
 
 var FolderIcon = class FolderIcon {


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