[gnome-shell] Introduce a SlideLayout layout manager



commit 93bde0cae2c59b941b30c948834e9d17e60135b9
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Thu Feb 14 14:41:38 2013 -0500

    Introduce a SlideLayout layout manager
    
    SlideLayout is a fixed layout that takes care of requesting and
    allocating the right sizes so its contents can slide horizontally as the
    actor is resized.
    Sliding is controlled with a slideX and slideDirection properties, which
    do the right thing wrt. RTL automatically.
    
    Also add a SlidingControl base class that will be used by the overview
    to pack and slide the workspace thumbnail switcher and the dash.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=682050

 js/Makefile.am            |    1 +
 js/ui/overviewControls.js |  144 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+), 0 deletions(-)
---
diff --git a/js/Makefile.am b/js/Makefile.am
index 323cd1b..df389b8 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -68,6 +68,7 @@ nobase_dist_js_DATA =         \
        ui/shellMountOperation.js \
        ui/notificationDaemon.js \
        ui/overview.js          \
+       ui/overviewControls.js  \
        ui/panel.js             \
        ui/panelMenu.js         \
        ui/pointerWatcher.js    \
diff --git a/js/ui/overviewControls.js b/js/ui/overviewControls.js
new file mode 100644
index 0000000..2f03f87
--- /dev/null
+++ b/js/ui/overviewControls.js
@@ -0,0 +1,144 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Clutter = imports.gi.Clutter;
+const Lang = imports.lang;
+const St = imports.gi.St;
+
+const Main = imports.ui.main;
+
+const SIDE_CONTROLS_ANIMATION_TIME = 0.2;
+
+const SlideDirection = {
+    LEFT: 0,
+    RIGHT: 1
+};
+
+const SlideLayout = new Lang.Class({
+    Name: 'SlideLayout',
+    Extends: Clutter.FixedLayout,
+
+    _init: function(params) {
+        this._slideX = 1;
+        this._direction = SlideDirection.LEFT;
+
+        this.parent(params);
+    },
+
+    _getRealSlideDirection: function(child) {
+        let direction = this._direction;
+
+        let rtl = (child.text_direction == Clutter.TextDirection.RTL);
+        if (rtl)
+            direction = (direction == SlideDirection.LEFT) ?
+                SlideDirection.RIGHT : SlideDirection.LEFT;
+
+        return direction;
+    },
+
+    vfunc_get_preferred_width: function(container, forHeight) {
+        let child = container.get_first_child();
+
+        let [minWidth, natWidth] = child.get_preferred_width(forHeight);
+
+        minWidth *= this._slideX;
+        natWidth *= this._slideX;
+
+        return [minWidth, natWidth];
+    },
+
+    vfunc_allocate: function(container, box, flags) {
+        let child = container.get_first_child();
+
+        let [, , natWidth, natHeight] = child.get_preferred_size();
+        let availWidth = Math.round(box.x2 - box.x1);
+        let availHeight = Math.round(box.y2 - box.y1);
+
+        let realDirection = this._getRealSlideDirection(child);
+        let translationX = (realDirection == SlideDirection.LEFT) ?
+            (availWidth - natWidth) : (natWidth - availWidth);
+
+        let actorBox = new Clutter.ActorBox({ x1: translationX,
+                                              y1: 0,
+                                              x2: child.x_expand ? availWidth : natWidth,
+                                              y2: child.y_expand ? availHeight : natHeight });
+
+        child.allocate(actorBox, flags);
+    },
+
+    set slideX(value) {
+        this._slideX = value;
+        this.layout_changed();
+    },
+
+    get slideX() {
+        return this._slideX;
+    },
+
+    set slideDirection(direction) {
+        this._direction = direction;
+        this.layout_changed();
+    },
+
+    get slideDirection() {
+        return this._direction;
+    }
+});
+
+const SlidingControl = new Lang.Class({
+    Name: 'SlidingControl',
+
+    _init: function() {
+        this.visible = true;
+        this.inDrag = false;
+
+        this.layout = new SlideLayout();
+        this.actor = new St.Widget({ layout_manager: this.layout,
+                                     clip_to_allocation: true });
+
+        Main.overview.connect('showing', Lang.bind(this, this._onOverviewShowing));
+
+        Main.overview.connect('item-drag-begin', Lang.bind(this, this._onDragBegin));
+        Main.overview.connect('item-drag-end', Lang.bind(this, this._onDragEnd));
+        Main.overview.connect('item-drag-cancelled', Lang.bind(this, this._onDragEnd));
+        Main.overview.connect('window-drag-begin', Lang.bind(this, this._onDragBegin));
+        Main.overview.connect('window-drag-cancelled', Lang.bind(this, this._onDragEnd));
+        Main.overview.connect('window-drag-end', Lang.bind(this, this._onDragEnd));
+    },
+
+    getSlide: function() {
+        throw new Error('getSlide() must be overridden');
+    },
+
+    updateSlide: function() {
+        Tweener.addTween(this.layout, { slideX: this.getSlide(),
+                                        time: SIDE_CONTROLS_ANIMATION_TIME,
+                                        transition: 'easeOutQuad' });
+    },
+
+    _onOverviewShowing: function() {
+        // reset any translation and make sure the actor is visible when
+        // entering the overview
+        this.visible = true;
+        this.layout.slideX = this.getSlide();
+    },
+
+    _onDragBegin: function() {
+        this.inDrag = true;
+        this.updateSlide();
+    },
+
+    _onDragEnd: function() {
+        this.inDrag = false;
+        this.updateSlide();
+    },
+
+    slideIn: function() {
+        this.visible = true;
+        this.updateSlide();
+    },
+
+    slideOut: function() {
+        this.visible = false;
+        this.updateSlide();
+    }
+});


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