[gnome-shell/wip/exalm/gestures: 20/28] appDisplay: Use SwipeTracker



commit 83823b7f74c7b36275c45996fc27a0f51b2f9bd2
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date:   Sun Jun 30 17:15:37 2019 +0500

    appDisplay: Use SwipeTracker
    
    Replace existing panning and touchpad scrolling by SwipeTracker.
    
    Since SwipeTracker only references one actor, redirect scroll events
    from page indicators to the main scroll view.
    
    Change programmatic scroll animation to use easeOutCubic interpolator
    to match the gesture.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605

 js/ui/appDisplay.js | 133 +++++++++++++++++++++++++++-------------------------
 1 file changed, 69 insertions(+), 64 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 79c2f7e83a..bf5136d641 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -13,6 +13,7 @@ const Main = imports.ui.main;
 const PageIndicators = imports.ui.pageIndicators;
 const PopupMenu = imports.ui.popupMenu;
 const Search = imports.ui.search;
+const SwipeTracker = imports.ui.swipeTracker;
 const Params = imports.misc.params;
 const Util = imports.misc.util;
 const SystemActions = imports.misc.systemActions;
@@ -318,7 +319,9 @@ var AllView = GObject.registerClass({
             (indicators, pageIndex) => {
                 this.goToPage(pageIndex);
             });
-        this._pageIndicators.connect('scroll-event', this._onScroll.bind(this));
+        this._pageIndicators.connect('scroll-event', (actor, event) => {
+            this._scrollView.event (event, false);
+        });
         this.add_actor(this._pageIndicators);
 
         this.folderIcons = [];
@@ -336,13 +339,13 @@ var AllView = GObject.registerClass({
 
         this._scrollView.connect('scroll-event', this._onScroll.bind(this));
 
-        let panAction = new Clutter.PanAction({ interpolate: false });
-        panAction.connect('pan', this._onPan.bind(this));
-        panAction.connect('gesture-cancel', this._onPanEnd.bind(this));
-        panAction.connect('gesture-end', this._onPanEnd.bind(this));
-        this._panAction = panAction;
-        this._scrollView.add_action(panAction);
-        this._panning = false;
+        let allowedModes = Shell.ActionMode.OVERVIEW;
+        this._swipeTracker = new SwipeTracker.SwipeTracker(this._scrollView, allowedModes);
+        this._swipeTracker.connect('begin', this._swipeBegin.bind(this));
+        this._swipeTracker.connect('update', this._swipeUpdate.bind(this));
+        this._swipeTracker.connect('end', this._swipeEnd.bind(this));
+
+        this._animating = false;
         this._clickAction = new Clutter.ClickAction();
         this._clickAction.connect('clicked', () => {
             if (!this._currentPopup)
@@ -393,6 +396,7 @@ var AllView = GObject.registerClass({
         this._keyPressEventId =
             global.stage.connect('key-press-event',
                 this._onKeyPressEvent.bind(this));
+        this._swipeTracker.enabled = true;
         super.vfunc_map();
     }
 
@@ -401,6 +405,7 @@ var AllView = GObject.registerClass({
             global.stage.disconnect(this._keyPressEventId);
             this._keyPressEventId = 0;
         }
+        this._swipeTracker.enabled = false;
         super.vfunc_unmap();
     }
 
@@ -554,44 +559,20 @@ var AllView = GObject.registerClass({
             return;
         }
 
-        let velocity;
-        if (!this._panning)
-            velocity = 0;
-        else
-            velocity = Math.abs(this._panAction.get_velocity(0)[2]);
-        // Tween the change between pages.
-        // If velocity is not specified (i.e. scrolling with mouse wheel),
-        // use the same speed regardless of original position
-        // if velocity is specified, it's in pixels per milliseconds
-        let diffToPage = this._diffToPage(pageNumber);
-        let childBox = this._scrollView.get_allocation_box();
-        let totalHeight = childBox.y2 - childBox.y1;
-        let time;
-        // Only take the velocity into account on page changes, otherwise
-        // return smoothly to the current page using the default velocity
-        if (this._grid.currentPage != pageNumber) {
-            let minVelocity = totalHeight / PAGE_SWITCH_TIME;
-            velocity = Math.max(minVelocity, velocity);
-            time = diffToPage / velocity;
-        } else {
-            time = PAGE_SWITCH_TIME * diffToPage / totalHeight;
-        }
-        // When changing more than one page, make sure to not take
-        // longer than PAGE_SWITCH_TIME
-        time = Math.min(time, PAGE_SWITCH_TIME);
-
         this._grid.currentPage = pageNumber;
-        this._adjustment.ease(this._grid.getPageY(pageNumber), {
-            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
-            duration: time
-        });
 
-        this._pageIndicators.setCurrentPage(pageNumber);
-    }
+        if (!this._animating) {
+            this._animating = true;
+            // Tween the change between pages.
+            this._adjustment.ease(this._grid.getPageY(this._grid.currentPage), {
+                mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
+                duration: PAGE_SWITCH_TIME,
+                onComplete: () => (this._animating = false)
+            });
+        } else
+            this._adjustment.value = this._grid.getPageY(this._grid.currentPage);
 
-    _diffToPage(pageNumber) {
-        let currentScrollPosition = this._adjustment.value;
-        return Math.abs(currentScrollPosition - this._grid.getPageY(pageNumber));
+        this._pageIndicators.setCurrentPage(pageNumber);
     }
 
     openSpaceForPopup(item, side, nRows) {
@@ -614,6 +595,9 @@ var AllView = GObject.registerClass({
         if (this._displayingPopup || !this._scrollView.reactive)
             return Clutter.EVENT_STOP;
 
+        if (this._swipeTracker.canHandleScrollEvent(event))
+            return Clutter.EVENT_PROPAGATE;
+
         let direction = event.get_scroll_direction();
         if (direction == Clutter.ScrollDirection.UP)
             this.goToPage(this._grid.currentPage - 1);
@@ -623,34 +607,55 @@ var AllView = GObject.registerClass({
         return Clutter.EVENT_STOP;
     }
 
-    _onPan(action) {
-        if (this._displayingPopup)
-            return false;
-        this._panning = true;
-        this._clickAction.release();
-        let [dist_, dx_, dy] = action.get_motion_delta(0);
+    _swipeBegin(tracker, monitor) {
+        if (monitor != Main.layoutManager.primaryIndex)
+            return;
+
         let adjustment = this._adjustment;
-        adjustment.value -= (dy / this._scrollView.height) * adjustment.page_size;
-        return false;
-    }
+        if (this._animating)
+            adjustment.remove_transition('value');
 
-    _onPanEnd(action) {
-        if (this._displayingPopup)
-            return;
+        let progress = adjustment.value / adjustment.page_size - this._grid.currentPage;
+
+        let points = [];
+        if (this._grid.currentPage > 0)
+            points.push(-1);
+        points.push(0);
+        if (this._grid.currentPage < this._grid.nPages() - 1)
+            points.push(1);
 
-        let pageHeight = this._grid.getPageHeight();
+        tracker.confirmSwipe(this._scrollView.height, points, progress, 0);
 
-        // Calculate the scroll value we'd be at, which is our current
-        // scroll plus any velocity the user had when they released
-        // their finger.
+        this._animating = true;
+    }
 
-        let velocity = -action.get_velocity(0)[2];
-        let endPanValue = this._adjustment.value + velocity;
+    _swipeUpdate(_tracker, progress) {
+        let adjustment = this._adjustment;
+        adjustment.value = (this._grid.currentPage + progress) * adjustment.page_size;
+    }
 
-        let closestPage = Math.round(endPanValue / pageHeight);
-        this.goToPage(closestPage);
+    _swipeEnd(_tracker, duration, endProgress) {
+        let adjustment = this._adjustment;
+        let page = this._grid.currentPage + endProgress;
+        let value = page * adjustment.page_size;
+
+        if (duration == 0) {
+            adjustment.value = value;
+            if (endProgress != 0)
+                this.goToPage(page);
+            this._animating = false;
+            return;
+        }
 
-        this._panning = false;
+        this._adjustment.ease(value, {
+            mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
+            duration: duration,
+            onComplete: () => {
+                if (endProgress != 0)
+                    this.goToPage(page);
+                this._animating = false;
+            }
+        });
     }
 
     _onKeyPressEvent(actor, event) {


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