[gnome-shell/wip/paging-release2: 18/23] iconGrid: Add openExtraSpace()/closeExtraSpace() methods



commit 7b087c63d2bc0b498dbd04c88820824700d67ed0
Author: Florian Müllner <fmuellner gnome org>
Date:   Sun Sep 1 21:49:57 2013 +0200

    iconGrid: Add openExtraSpace()/closeExtraSpace() methods
    
    Add methods to open/close extra space for n rows. The app picker
    will use those to make AppFolder popups appear inline with the
    main grid rather than on top of it.
    
    With access to all internals, we can determine the set of children
    that need translation without going through an intermediate array;
    as a bonus, we no longer have to special-case empty rows on the last
    page, as all calculations are now based on our internal knowledge
    of the grid rather than actual rows.

 js/ui/iconGrid.js |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 101 insertions(+), 0 deletions(-)
---
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 8e79227..178a841 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -1,14 +1,18 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
 const Clutter = imports.gi.Clutter;
+const Gtk = imports.gi.Gtk;
 const Shell = imports.gi.Shell;
+const Signals = imports.signals;
 const St = imports.gi.St;
 
 const Lang = imports.lang;
 const Params = imports.misc.params;
+const Tweener = imports.ui.tweener;
 
 const ICON_SIZE = 48;
 
+const EXTRA_SPACE_ANIMATION_TIME = 0.25;
 
 const BaseIcon = new Lang.Class({
     Name: 'BaseIcon',
@@ -573,5 +577,102 @@ const PaginatedIconGrid = new Lang.Class({
             return 0;
         }
         return Math.floor(index / this._childrenPerPage);
+    },
+
+    /**
+    * openExtraSpace:
+    * @sourceItem: the item for which to create extra space
+    * @side: where @sourceItem should be located relative to the created space
+    * @nRows: the amount of space to create
+    *
+    * Pan view to create extra space for @nRows above or below @sourceItem.
+    */
+    openExtraSpace: function(sourceItem, side, nRows) {
+        let children = this._getVisibleChildren();
+        let index = children.indexOf(sourceItem.actor);
+        if (index == -1) {
+            throw new Error('Item not found.');
+            return;
+        }
+        let pageIndex = Math.floor(index / this._childrenPerPage);
+        let pageOffset = pageIndex * this._childrenPerPage;
+
+        let childrenPerRow = this._childrenPerPage / this._rowsPerPage;
+        let sourceRow = Math.floor((index - pageOffset) / childrenPerRow);
+
+        let nRowsAbove = (side == St.Side.TOP) ? sourceRow + 1
+                                               : sourceRow;
+        let nRowsBelow = this._rowsPerPage - nRowsAbove;
+
+        let nRowsUp, nRowsDown;
+        if (side == St.Side.TOP) {
+            nRowsDown = Math.min(nRowsBelow, nRows);
+            nRowsUp = nRows - nRowsDown;
+        } else {
+            nRowsUp = Math.min(nRowsAbove, nRows);
+            nRowsDown = nRows - nRowsUp;
+        }
+
+        let childrenDown = children.splice(pageOffset +
+                                           nRowsAbove * childrenPerRow,
+                                           nRowsBelow * childrenPerRow);
+        let childrenUp = children.splice(pageOffset,
+                                         nRowsAbove * childrenPerRow);
+
+        // Special case: On the last row with no rows below the icon,
+        // there's no need to move any rows either up or down
+        if (childrenDown.length == 0 && nRowsUp == 0) {
+            this._translatedChildren = [];
+            this.emit('space-opened');
+        } else {
+            this._translateChildren(childrenUp, Gtk.DirectionType.UP, nRowsUp);
+            this._translateChildren(childrenDown, Gtk.DirectionType.DOWN, nRowsDown);
+            this._translatedChildren = childrenUp.concat(childrenDown);
+        }
+    },
+
+    _translateChildren: function(children, direction, nRows) {
+        let translationY = nRows * (this._vItemSize + this._getSpacing());
+        if (translationY == 0)
+            return;
+
+        if (direction == Gtk.DirectionType.UP)
+            translationY *= -1;
+
+        for (let i = 0; i < children.length; i++) {
+            children[i].translation_y = 0;
+            let params = { translation_y: translationY,
+                           time: EXTRA_SPACE_ANIMATION_TIME,
+                           transition: 'easeInOutQuad'
+                         };
+            if (i == (children.length - 1))
+                params.onComplete = Lang.bind(this,
+                    function() {
+                        this.emit('space-opened');
+                    });
+            Tweener.addTween(children[i], params);
+        }
+    },
+
+    closeExtraSpace: function() {
+        if (!this._translatedChildren || !this._translatedChildren.length) {
+            this.emit('space-closed');
+            return;
+        }
+
+        for (let i = 0; i < this._translatedChildren.length; i++) {
+            if (!this._translatedChildren[i].translation_y)
+                continue;
+            Tweener.addTween(this._translatedChildren[i],
+                             { translation_y: 0,
+                               time: EXTRA_SPACE_ANIMATION_TIME,
+                               transition: 'easeInOutQuad',
+                               onComplete: Lang.bind(this,
+                                   function() {
+                                       this.emit('space-closed');
+                                   })
+                             });
+        }
     }
 });
+Signals.addSignalMethods(PaginatedIconGrid.prototype);


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