[gnome-shell] iconGrid: Add openExtraSpace()/closeExtraSpace() methods



commit dd9f8021ff25f7c67e9e8d97fb0ea8bcaa9b5735
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.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=706081

 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]