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




commit 4e31332925eff901d9e8bae6d2e3733fb94c4dbd
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 |  8 ++++
 js/ui/appDisplay.js                                | 46 +++++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)
---
diff --git a/data/theme/gnome-shell-sass/widgets/_app-grid.scss 
b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
index 76358d1988..9b85468064 100644
--- a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
+++ b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
@@ -137,3 +137,11 @@ $app_grid_fg_color: #fff;
   border-radius: 99px;
   icon-size: $app_icon_size * 0.5;
 }
+
+.dnd-placeholder {
+  background: #fff;
+  width: 80px;
+
+  &: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 8c4facbe30..9429c48299 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -52,6 +52,7 @@ var SidePages = {
     NONE: 0,
     PREVIOUS: 1 << 0,
     NEXT: 1 << 1,
+    EMPTY_PLACEHOLDER: 1 << 2,
 };
 
 function _getCategories(info) {
@@ -150,6 +151,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;
@@ -230,6 +232,14 @@ var BaseAppView = GObject.registerClass({
         this._dragCancelledId = 0;
 
         this.connect('destroy', this._onDestroy.bind(this));
+
+        this._emptyPageIndicator = new St.Widget({
+            opacity: 0,
+            reactive: false,
+            visible: false,
+        });
+        this._emptyPageIndicator.add_style_class_name('dnd-placeholder');
+        this.add_actor(this._emptyPageIndicator);
     }
 
     _onDestroy() {
@@ -570,6 +580,7 @@ var BaseAppView = GObject.registerClass({
             dragMotion: this._onDragMotion.bind(this),
         };
         DND.addDragMonitor(this._dragMonitor);
+        this._slideSidePages(SidePages.PREVIOUS | SidePages.NEXT | SidePages.EMPTY_PLACEHOLDER);
     }
 
     _onDragMotion(dragEvent) {
@@ -586,6 +597,16 @@ var BaseAppView = GObject.registerClass({
 
         this._maybeMoveItem(dragEvent);
 
+        this._dropPage = this._pageForCoords(dragEvent.x, dragEvent.y);
+        if (this._dropPage) {
+            if (this._dropPage === SidePages.NEXT || this._grid.currentPage !== 0) {
+                return DND.DragMotionResult.MOVE_DROP;
+            } else {
+                this._dropPage = null;
+                return DND.DragMotionResult.NO_DROP;
+            }
+        }
+
         return DND.DragMotionResult.CONTINUE;
     }
 
@@ -596,12 +617,15 @@ var BaseAppView = GObject.registerClass({
         }
 
         this._resetOvershoot();
+        this._slideSidePages(SidePages.NONE);
+        this._dropPage = null;
     }
 
     _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) {
@@ -625,6 +649,11 @@ var BaseAppView = GObject.registerClass({
 
             this._moveItem(source, page, position);
             this._removeDelayedMove();
+        } else if (this._dropPage) {
+            if (this._dropPage === SidePages.NEXT)
+                this._moveItem(source, this._grid.currentPage + 1, 1);
+            else if (this._dropPage === SidePages.PREVIOUS)
+                this._moveItem(source, this._grid.currentPage - 1, 1);
         }
 
         return true;
@@ -892,6 +921,16 @@ var BaseAppView = GObject.registerClass({
         this.adaptToSize(width, height);
 
         super.vfunc_allocate(box);
+
+        this._emptyPageIndicator.set_height(this._grid.get_height());
+        const rtl = this.get_text_direction() === Clutter.TextDirection.RTL;
+        if (rtl) {
+            this._emptyPageIndicator.set_position(0, this._grid.get_y());
+        } else {
+            this._emptyPageIndicator.set_position(
+                width - this._emptyPageIndicator.width,
+                this._grid.get_y());
+        }
     }
 
     vfunc_map() {
@@ -980,7 +1019,12 @@ var BaseAppView = GObject.registerClass({
                 this._nextPageAdjustmentId = this._nextPageAdjustment.connect('notify::value', () => {
                     let translation_x = (1 - this._nextPageAdjustment.value) * 100;
                     translation_x = rtl ? -translation_x : translation_x;
-                    if (this._grid.currentPage < this._grid.nPages - 1) {
+                    if ((pages & SidePages.EMPTY_PLACEHOLDER) !== 0 &&
+                        this._grid.currentPage === this._grid.nPages - 1) {
+                        this._emptyPageIndicator.visible = true;
+                        this._emptyPageIndicator.translation_x = translation_x;
+                        this._emptyPageIndicator.opacity = this._nextPageAdjustment.value * 128;
+                    } else if (this._grid.currentPage < this._grid.nPages - 1) {
                         let items = this._grid.layout_manager.getItemsAtPage(this._grid.currentPage + 1);
                         items.forEach(item => {
                             item.translation_x = translation_x;


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