[gnome-shell/wip/carlosg/appgrid-navigation: 1/4] js/appDisplay: Implement side page previews while DnDing




commit 1b1ec3f025398b6fd7fcf2b420285303f4922109
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Feb 3 12:51:17 2021 +0100

    js/appDisplay: Implement side page previews while DnDing
    
    When DnDing an icon, we show both previous/next page, and optionally
    a "placeholder" actor to allow creating new pages. These sides on the
    scrollview are drop targets themselves, allowing to drop an app onto
    the next/prev page without further navigation.
    
    Still, preserve the checks to maybe switch to prev/next page without
    finishing the DnD operation, for finer grained operations.

 data/theme/gnome-shell-sass/widgets/_app-grid.scss |  4 ++
 js/ui/appDisplay.js                                | 52 ++++++++++++++++++++--
 2 files changed, 53 insertions(+), 3 deletions(-)
---
diff --git a/data/theme/gnome-shell-sass/widgets/_app-grid.scss 
b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
index eb9a3f4b91..c28bdb0e60 100644
--- a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
+++ b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
@@ -142,6 +142,10 @@ $app_grid_fg_color: #fff;
   background: rgba(255, 255, 255, 0.05);
   width: 88px;
 
+  &.dnd {
+    background: rgba(255, 255, 255, 0.1);
+  }
+
   &.next {
     &:ltr { border-radius: 15px 0px 0px 15px; }
     &:rtl { border-radius: 0px 15px 15px 0px; }
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 31de33d086..8a5e0fa851 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -56,6 +56,7 @@ var SidePages = {
     NONE: 0,
     PREVIOUS: 1 << 0,
     NEXT: 1 << 1,
+    DND: 1 << 2,
 };
 
 function _getCategories(info) {
@@ -154,6 +155,7 @@ var BaseAppView = GObject.registerClass({
             enable_mouse_scrolling: false,
         });
         this._scrollView.set_policy(St.PolicyType.EXTERNAL, St.PolicyType.NEVER);
+        this._scrollView._delegate = this;
 
         this._canScroll = true; // limiting scrolling speed
         this._scrollTimeoutId = 0;
@@ -621,6 +623,7 @@ var BaseAppView = GObject.registerClass({
             dragMotion: this._onDragMotion.bind(this),
         };
         DND.addDragMonitor(this._dragMonitor);
+        this._slideSidePages(SidePages.PREVIOUS | SidePages.NEXT | SidePages.DND);
     }
 
     _onDragMotion(dragEvent) {
@@ -637,7 +640,15 @@ var BaseAppView = GObject.registerClass({
 
         this._maybeMoveItem(dragEvent);
 
-        return DND.DragMotionResult.CONTINUE;
+        this._dropPage = this._pageForCoords(dragEvent.x, dragEvent.y);
+        if (!this._dropPage)
+            return DND.DragMotionResult.CONTINUE;
+
+        if (this._dropPage === SidePages.NEXT || this._grid.currentPage !== 0)
+            return DND.DragMotionResult.MOVE_DROP;
+
+        delete this._dropPage;
+        return DND.DragMotionResult.NO_DROP;
     }
 
     _onDragEnd() {
@@ -647,12 +658,15 @@ var BaseAppView = GObject.registerClass({
         }
 
         this._resetOvershoot();
+        this._slideSidePages(SidePages.NONE);
+        delete this._dropPage;
     }
 
     _onDragCancelled() {
         // At this point, the positions aren't stored yet, thus _redisplay()
         // will move all items to their original positions
         this._redisplay();
+        this._slideSidePages(SidePages.NONE);
     }
 
     _canAccept(source) {
@@ -676,6 +690,25 @@ var BaseAppView = GObject.registerClass({
 
             this._moveItem(source, page, position);
             this._removeDelayedMove();
+        } else if (this._dropPage) {
+            let page = this._grid.currentPage;
+
+            while (true) {
+                page = this._dropPage === SidePages.NEXT
+                    ? page + 1 : page - 1;
+                if (page < 0 || page >= this._grid.nPages)
+                    break;
+
+                const items = this._grid.getItemsAtPage(page);
+                const itemsPerPage =
+                      this._grid.layout_manager.rowsPerPage * this._grid.layout_manager.columnsPerPage;
+
+                if (items.length < itemsPerPage)
+                    break;
+            }
+
+            this._moveItem(source, Math.max(page, 0), -1);
+            this.goToPage(page);
         }
 
         return true;
@@ -1033,10 +1066,14 @@ var BaseAppView = GObject.registerClass({
             let translationX = (1 - adjustment.value) * 100 * multiplier;
             translationX = rtl ? -translationX : translationX;
             const nextPage = this._grid.currentPage + page;
-            if (nextPage >= 0 &&
-                nextPage < this._grid.nPages - 1) {
+            const hasFollowingPage = nextPage >= 0 &&
+                nextPage < this._grid.nPages;
+
+            if (hasFollowingPage) {
                 const items = this._grid.layout_manager.getItemsAtPage(nextPage);
                 items.forEach(item => (item.translation_x = translationX));
+            }
+            if (hasFollowingPage || (state & SidePages.DND) !== 0) {
                 indicator.visible = true;
                 indicator.opacity = adjustment.value * 255;
                 indicator.translation_x = translationX;
@@ -1071,6 +1108,15 @@ var BaseAppView = GObject.registerClass({
         this._pagesShown = state;
         const showingNextPage = state & SidePages.NEXT;
         const showingPrevPage = state & SidePages.PREVIOUS;
+        const dnd = state & SidePages.DND;
+
+        if (dnd) {
+            this._nextPageIndicator.add_style_class_name('dnd');
+            this._prevPageIndicator.add_style_class_name('dnd');
+        } else {
+            this._nextPageIndicator.remove_style_class_name('dnd');
+            this._nextPageIndicator.remove_style_class_name('dnd');
+        }
 
         if (showingNextPage) {
             this._setupPagePreview(1, state);


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