[gnome-documents] searchbar: animate move in and move out of the searchbar



commit 30ad63db6f86144879f7c1b80ee9bf5b92d948e3
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Oct 26 17:44:43 2011 -0400

    searchbar: animate move in and move out of the searchbar
    
    To achieve this, we have to change the application layout (again).
    Now the GtkWindow only has one child, a GtkClutterEmbed, which holds
    the stage.
    Both the top searchbar and the grid content are GtkClutterActors,
    arranged inside the space allocated by the ClutterBox.

 src/application.js |    2 ++
 src/embed.js       |   23 +++--------------------
 src/global.js      |    1 +
 src/mainWindow.js  |   33 ++++++++++++++++++++++++++++-----
 src/searchbar.js   |   49 ++++++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 78 insertions(+), 30 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index 216fdfe..e42b53d 100644
--- a/src/application.js
+++ b/src/application.js
@@ -23,6 +23,7 @@ const DBus = imports.dbus;
 const Lang = imports.lang;
 const Gettext = imports.gettext;
 
+const ClutterX11 = imports.gi.ClutterX11;
 const GtkClutter = imports.gi.GtkClutter;
 const EvDoc = imports.gi.EvinceDocument;
 const Gdk = imports.gi.Gdk;
@@ -105,6 +106,7 @@ Application.prototype = {
         String.prototype.format = Format.format;
 
         GLib.set_prgname('gnome-documents');
+        ClutterX11.disable_event_retrieval();
         GtkClutter.init(null, null);
         EvDoc.init();
         Tweener.init();
diff --git a/src/embed.js b/src/embed.js
index cc295f6..975d18d 100644
--- a/src/embed.js
+++ b/src/embed.js
@@ -85,13 +85,13 @@ ViewEmbed.prototype  = {
         this._fsToolbar = new MainToolbar.FullscreenToolbar();
         this._fsToolbar.setModel(this._docModel);
 
-        this._stage.add_actor(this._fsToolbar.actor);
+        Global.stage.add_actor(this._fsToolbar.actor);
 
         let vScrollbar = this._scrolledWin.get_vscrollbar();
 
         let sizeConstraint = new Clutter.BindConstraint
             ({ coordinate: Clutter.BindCoordinate.WIDTH,
-               source: this._stage,
+               source: Global.stage,
                offset: (vScrollbar.get_visible() ?
                         (- (vScrollbar.get_preferred_width()[1])) : 0 ) });
 
@@ -239,10 +239,7 @@ ViewEmbed.prototype  = {
             this._preview = null;
         }
 
-        this._actor = null;
-        this._clutterEmbed = null;
         this._docModel = null;
-        this._stage = null;
 
         Global.documentManager.setActiveItem(null);
 
@@ -318,24 +315,10 @@ ViewEmbed.prototype  = {
             this._queryErrorId = 0;
         }
 
-        this._clutterEmbed = new GtkClutter.Embed();
-        this.widget.add(this._clutterEmbed);
-
         this._scrolledWin = new Gtk.ScrolledWindow({ hexpand: true,
                                                      vexpand: true,
                                                      shadow_type: Gtk.ShadowType.IN });
-        this._actor = new GtkClutter.Actor({ contents: this._scrolledWin });
-
-        this._stage = this._clutterEmbed.get_stage();
-        this._actor.add_constraint(
-            new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.WIDTH,
-                                         source: this._stage }));
-        this._actor.add_constraint(
-            new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.HEIGHT,
-                                         source: this._stage }));
-
-        this._stage.add_actor(this._actor);
-
+        this.widget.add(this._scrolledWin);
         this.widget.show_all();
     },
 
diff --git a/src/global.js b/src/global.js
index 5e6a2cf..aedfa89 100644
--- a/src/global.js
+++ b/src/global.js
@@ -33,5 +33,6 @@ let searchFilterController = null;
 let sideFilterController = null;
 let selectionController = null;
 let settings = null;
+let stage = null;
 let sourceManager = null;
 let trackerController = null;
diff --git a/src/mainWindow.js b/src/mainWindow.js
index c629d2f..85a7047 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -19,9 +19,11 @@
  *
  */
 
+const Clutter = imports.gi.Clutter;
 const Gdk = imports.gi.Gdk;
 const GLib = imports.gi.GLib;
 const Gtk = imports.gi.Gtk;
+const GtkClutter = imports.gi.GtkClutter;
 
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
@@ -47,6 +49,11 @@ MainWindow.prototype = {
         this.window = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL,
                                        window_position: Gtk.WindowPosition.CENTER,
                                        title: _("Documents") });
+        this._clutterEmbed = new GtkClutter.Embed();
+        this.window.add(this._clutterEmbed);
+        this._clutterEmbed.show();
+
+        Global.stage = this._clutterEmbed.get_stage();
 
         Global.modeController.setWindowMode(WindowMode.WindowMode.OVERVIEW);
 
@@ -84,17 +91,33 @@ MainWindow.prototype = {
         Global.modeController.connect('fullscreen-changed',
                                       Lang.bind(this, this._onFullscreenChanged));
 
-        this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
-        this.window.add(this._grid);
+        // the base layout is a vertical ClutterBox
+        this._clutterBoxLayout = new Clutter.BoxLayout({ vertical: true });
+        this._clutterBox = new Clutter.Box({ layout_manager: this._clutterBoxLayout });
+        this._clutterBox.add_constraint(
+            new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE,
+                                         source: Global.stage }));
+
+        Global.stage.add_actor(this._clutterBox);
 
+        // first child: searchbar filling the X axis
         this._searchbar = new Searchbar.Searchbar();
-        this._grid.attach(this._searchbar.widget, 0, 0, 2, 1);
+        this._clutterBox.add_actor(this._searchbar.actor);
+        this._clutterBoxLayout.set_fill(this._searchbar.actor, true, false);
+
+        // second child: the actual sidebar + embed, filling both axis
+        // and expanding
+        this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL });
+        this._gridActor = new GtkClutter.Actor({ contents: this._grid });
+        this._clutterBox.add_actor(this._gridActor);
+        this._clutterBoxLayout.set_expand(this._gridActor, true);
+        this._clutterBoxLayout.set_fill(this._gridActor, true, true);
 
         this._sidebar = new Sidebar.Sidebar();
-        this._grid.attach(this._sidebar.widget, 0, 1, 1, 1);
+        this._grid.add(this._sidebar.widget);
 
         this._embed = new Embed.ViewEmbed();
-        this._grid.attach(this._embed.widget, 1, 1, 1, 1);
+        this._grid.add(this._embed.widget);
 
         this._grid.show_all();
     },
diff --git a/src/searchbar.js b/src/searchbar.js
index e59e4c0..2c69b2d 100644
--- a/src/searchbar.js
+++ b/src/searchbar.js
@@ -20,12 +20,15 @@
  */
 
 const Gd = imports.gi.Gd;
+const Gdk = imports.gi.Gdk;
 const Gtk = imports.gi.Gtk;
+const GtkClutter = imports.gi.GtkClutter;
 
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Global = imports.global;
+const Tweener = imports.util.tweener;
 
 const _SEARCH_ENTRY_TIMEOUT = 200;
 
@@ -41,10 +44,14 @@ Searchbar.prototype = {
         this.widget = new Gtk.Toolbar();
         this.widget.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR);
 
+        this.actor = new GtkClutter.Actor({ contents: this.widget,
+                                            height: 0 });
+
         this._searchEntry = new Gtk.Entry({ width_request: 260,
                                             secondary_icon_name: 'edit-find-symbolic',
                                             secondary_icon_sensitive: false,
-                                            secondary_icon_activatable: false });
+                                            secondary_icon_activatable: false,
+                                            no_show_all: true });
         let item = new Gtk.ToolItem();
         item.set_expand(true);
 
@@ -54,6 +61,18 @@ Searchbar.prototype = {
 
         item.add(container);
 
+        this._searchEntry.connect('key-press-event', Lang.bind(this,
+            function(widget, event) {
+                let keyval = event.get_keyval()[1];
+
+                if (keyval == Gdk.KEY_Escape) {
+                    this._moveOut();
+                    return true;
+                }
+
+                return false;
+            }));
+
         this._searchEntry.connect('changed', Lang.bind(this, function() {
             let text = this._searchEntry.get_text();
             if (text && text != '') {
@@ -85,13 +104,12 @@ Searchbar.prototype = {
         }));
 
         this._searchFocusId =
-            Global.focusController.connect('focus-search', Lang.bind(this,
-                function() {
-                    this._searchEntry.grab_focus();
-                }));
+            Global.focusController.connect('focus-search', Lang.bind(this, this._moveIn));
 
         this.widget.insert(item, 0);
         this._searchEntry.set_text(Global.searchFilterController.getFilter());
+
+        this.widget.show_all();
     },
 
     destroy: function() {
@@ -99,5 +117,26 @@ Searchbar.prototype = {
             Global.focusController.disconnect(this._searchFocusId);
             this._searchFocusId = 0;
         }
+    },
+
+    _moveIn: function() {
+        this._searchEntry.show();
+        Tweener.addTween(this.actor, { height: this.widget.get_preferred_height()[1],
+                                       time: 0.20,
+                                       transition: 'easeOutQuad',
+                                       onComplete: function() {
+                                           this._searchEntry.grab_focus();
+                                       },
+                                       onCompleteScope: this });
+    },
+
+    _moveOut: function() {
+        Tweener.addTween(this.actor, { height: 0,
+                                       time: 0.20,
+                                       transition: 'easeOutQuad',
+                                       onComplete: function() {
+                                           this._searchEntry.hide();
+                                       },
+                                       onCompleteScope: this });
     }
 };



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