[gnome-shell/wip/paging-release: 5/74] PaginationScrollView: Added pan action



commit a091c3e2e3691553a689a0a42a93a4baca8fbcbb
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Mon Aug 12 16:36:45 2013 +0200

    PaginationScrollView: Added pan action
    
    PaginationScrollView: take into account velocity on paning
    
    PagionationScrollView, allview: take into account velocity when panning
    
    PAginationScrollView: time when changin more than 1 page is the same as 1

 js/ui/appDisplay.js |  115 ++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 96 insertions(+), 19 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 06dae5b..d877ae9 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -39,7 +39,7 @@ const MAX_APPS_PAGES = 20;
 //fraction of page height the finger or mouse must reach before
 //change page
 const PAGE_SWITCH_TRESHOLD = 0.2;
-const PAGE_SWITCH_TIME = 0.25;
+const PAGE_SWITCH_TIME = 0.3;
 
 // Recursively load a GMenuTreeDirectory; we could put this in ShellAppSystem too
 function _loadCategory(dir, view) {
@@ -276,6 +276,17 @@ const PaginationScrollView = new Lang.Class({
         this._parent = parent;
         
         this.connect('scroll-event', Lang.bind(this, this._onScroll));
+        
+        let panAction = new Clutter.PanAction({ interpolate: false });
+        panAction.connect('pan', Lang.bind(this, this._onPan));
+        panAction.connect('gesture-cancel', Lang.bind(this, function() {
+            this._onPanEnd(this._panAction);
+        }));
+        panAction.connect('gesture-end', Lang.bind(this, function() {
+            this._onPanEnd(this._panAction);
+        }));
+        this._panAction = panAction;
+        this.add_action(panAction);
     },
 
    vfunc_get_preferred_height: function (forWidht) {
@@ -344,13 +355,37 @@ const PaginationScrollView = new Lang.Class({
         this._pages.setGridParentSize([availWidth, availHeight]);
         child.allocate(childBox, flags);
     },
-    
-    goToPage: function(pageNumber) {
-        
+
+    goToPage: function(pageNumber, action) {
+        let velocity;
+        if(!action)
+            velocity = 0;
+        else
+            velocity = Math.abs(action.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 diffFromPage =  this._diffToPage(pageNumber);
+        let childBox = this.get_allocation_box();
+        let totalHeight = childBox.y2 - childBox.y1;
+        let time;
+        // Only take into account the velocity if we change of page, if not,
+        // we returns smoothly with default velocity to the current page
+        if(this._currentPage != pageNumber) {
+            let min_velocity = totalHeight / (PAGE_SWITCH_TIME * 1000);
+            velocity = Math.max(min_velocity, velocity);
+            time = (diffFromPage / velocity) / 1000;
+            
+        } else
+            time = PAGE_SWITCH_TIME * diffFromPage / totalHeight;
+        // Take care when we are changing more than one page, maximum time
+        // regardless the velocity is the default one
+        time = Math.min(time, PAGE_SWITCH_TIME);
         if(pageNumber < this._pages.nPages() && pageNumber >= 0) {
             this._currentPage = pageNumber;
             let params = { value: this._pages.getPagePosition(this._currentPage)[1],
-                           time: PAGE_SWITCH_TIME,
+                           time: time,
                            transition: 'easeOutQuad'
                           };
             Tweener.addTween(this.vscroll.adjustment, params);
@@ -365,12 +400,44 @@ const PaginationScrollView = new Lang.Class({
         return this._currentPage;
     },
     
+    _diffToPage: function (pageNumber) {
+        let currentScrollPosition = this.vscroll.adjustment.value;
+        return Math.abs(currentScrollPosition - this._pages._grid.getPagePosition(pageNumber)[1]);
+    },
+    
+    _nearestPage: function() {
+        let currentNearestPage = 0;
+        let diff = this._diffToPage(currentNearestPage);
+        let oldDiff = diff;
+        
+        while(diff <= oldDiff && currentNearestPage < (this._pages.nPages() - 1)) {
+            currentNearestPage++;
+            oldDiff = diff;
+            diff = this._diffToPage(currentNearestPage);            
+        }
+        if(diff > oldDiff)
+            currentNearestPage--;
+
+        return currentNearestPage; 
+    },
+
+    _goToNearestPage: function(action) {
+        this._parent.goToPage(this._nearestPage(), action);
+    },
+    
     _onScroll: function(actor, event) {
         let direction = event.get_scroll_direction();
+        let nextPage;
         if (direction == Clutter.ScrollDirection.UP)
-            this._parent.goToPage(this._currentPage - 1);
+            if(this._currentPage > 0) {
+                nextPage = this._currentPage - 1;
+                this._parent.goToPage(nextPage);
+            }
         if (direction == Clutter.ScrollDirection.DOWN)
-            this._parent.goToPage(this._currentPage + 1);
+            if(this._currentPage < (this.nPages() - 1)) {
+                nextPage = this._currentPage + 1;
+                this._parent.goToPage(nextPage);
+            }
     },
     
     addFolderPopup: function(popup) {
@@ -390,7 +457,27 @@ const PaginationScrollView = new Lang.Class({
             else
                 this._items[id].actor.opacity = 255;
         }
+    },
+    
+    _onPan: function(action) {
+        let [dist, dx, dy] = action.get_motion_delta(0);
+        let adjustment = this.vscroll.adjustment;
+        adjustment.value -= (dy / this.height) * adjustment.page_size;
+        return false;
+    },
+    
+    _onPanEnd: function(action) {
+        let diffCurrentPage = this._diffToPage(this._currentPage);
+        if(diffCurrentPage > this.height * PAGE_SWITCH_TRESHOLD) {
+            if(action.get_velocity(0)[2] > 0 && this._currentPage > 0) {
+                this._parent.goToPage(this._currentPage - 1, action);
+            } else if(this._currentPage < this.nPages() - 1) {
+                this._parent.goToPage(this._currentPage + 1, action);
+            }
+        } else
+            this._parent.goToPage(this._currentPage, action);
     }
+    
 });
 
 const PaginationIconIndicator = new Lang.Class({
@@ -542,16 +629,6 @@ const AllView = new Lang.Class({
 
         return false;
     },
-   
-    _onPan: function(action) {
-        /*
-        this._clickAction.release();
-
-        let [dist, dx, dy] = action.get_motion_delta(0);
-        let adjustment = this.actor.vscroll.adjustment;
-        adjustment.value -= (dy / this.actor.height) * adjustment.page_size;*/
-        return false;
-    },
 
     addApp: function(app) {
        let appIcon = this._paginationView._pages.addItem(app);
@@ -579,9 +656,9 @@ const AllView = new Lang.Class({
         this._paginationView._pages.loadGrid();
     },
     
-    goToPage: function(index) {
+    goToPage: function(index, action) {
         this._paginationIndicator.get_child_at_index(this._paginationView.currentPage()).set_checked(false);
-        this._paginationView.goToPage(index);
+        this._paginationView.goToPage(index, action);
         this._paginationIndicator.get_child_at_index(this._paginationView.currentPage()).set_checked(true);
     }
 });


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