[gnome-boxes] Use LayoutManagers and implicit animations



commit c38d002b1ae95f4c386198988e1f46576a20d565
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Jun 1 15:35:17 2012 +0200

    Use LayoutManagers and implicit animations
    
    This rewrites the whole layout and animation setup to use Clutter 1.10 style
    LayoutManager APIs and implicit animations. It also removes the use of deprecated
    APIs like ClutterState, etc.
    
    This leads to less magic numbers and a more robust layout, as well as niceties like
    being able to automatically set a minimum size for the window (although this needs
    more work).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=677274

 src/app.vala             |  141 ++++++++++++++++++++++++++-------------------
 src/collection-view.vala |   76 ++++++-------------------
 src/display-page.vala    |    5 ++
 src/machine.vala         |  126 ++++++++++++++++++++--------------------
 src/notificationbar.vala |   22 +++----
 src/properties.vala      |   25 ++++++---
 src/selectionbar.vala    |    3 -
 src/sidebar.vala         |   11 ++--
 src/topbar.vala          |    5 --
 src/wizard-source.vala   |    3 +
 src/wizard.vala          |   13 ++++
 11 files changed, 215 insertions(+), 215 deletions(-)
---
diff --git a/src/app.vala b/src/app.vala
index 7900cbb..bbfec3b 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -25,11 +25,14 @@ private class Boxes.App: Boxes.UI {
     public Gtk.Notebook notebook;
     public GtkClutter.Embed embed;
     public Clutter.Stage stage;
-    public Clutter.State state;
-    public Clutter.Box box; // the whole app box
+    public Clutter.BinLayout stage_bin;
+    public Clutter.Actor overlay_bin_actor;
+    public Clutter.BinLayout overlay_bin;
     public CollectionItem current_item; // current object/vm manipulated
     public Topbar topbar;
     public Notificationbar notificationbar;
+    public Boxes.Revealer sidebar_revealer;
+    public Boxes.Revealer topbar_revealer;
     public Sidebar sidebar;
     public Selectionbar selectionbar;
     public uint duration;
@@ -45,7 +48,6 @@ private class Boxes.App: Boxes.UI {
     public signal void ready (bool first_time);
     public signal void item_selected (CollectionItem item);
     private Gtk.Application application;
-    private Clutter.TableLayout box_table;
     private CollectionView view;
 
     private HashTable<string,GVir.Connection> connections;
@@ -364,55 +366,97 @@ private class Boxes.App: Boxes.UI {
         notebook.append_page (display_page.widget, null);
 
         stage = embed.get_stage () as Clutter.Stage;
-        stage.set_color (gdk_rgba_to_clutter_color (get_boxes_bg_color ()));
-
-        state = new Clutter.State ();
-        state.set_duration (null, null, duration);
+        stage.set_background_color (gdk_rgba_to_clutter_color (get_boxes_bg_color ()));
 
         window.delete_event.connect (() => { return quit (); });
 
         window.key_press_event.connect (on_key_pressed);
 
-        box_table = new Clutter.TableLayout ();
-        box = new Clutter.Box (box_table);
-        box.add_constraint (new Clutter.BindConstraint (stage, BindCoordinate.SIZE, 0));
-        stage.add_actor (box);
+        stage_bin = new Clutter.BinLayout (Clutter.BinAlignment.FIXED,
+                                           Clutter.BinAlignment.FIXED);
+        stage.set_layout_manager (stage_bin);
 
         sidebar = new Sidebar (this);
         view = new CollectionView (this, sidebar.category);
         topbar = new Topbar (this);
         notificationbar = new Notificationbar (this);
-        notificationbar.actor.add_constraint (new Clutter.AlignConstraint (view.actor, AlignAxis.X_AXIS, 0.5f));
-        var yconstraint = new Clutter.BindConstraint (topbar.actor, BindCoordinate.Y, topbar.height);
-        notificationbar.actor.add_constraint (yconstraint);
-        topbar.actor.notify["height"].connect (() => {
-            yconstraint.set_offset (topbar.height);
-        });
-
         selectionbar = new Selectionbar (this);
-        selectionbar.actor.add_constraint (new Clutter.AlignConstraint (view.actor, AlignAxis.X_AXIS, 0.5f));
-        yconstraint = new Clutter.BindConstraint (view.actor, BindCoordinate.Y,
-                                                  view.actor.height - selectionbar.spacing);
-        selectionbar.actor.add_constraint (yconstraint);
-        view.actor.notify["height"].connect (() => {
-            yconstraint.set_offset (view.actor.height - selectionbar.spacing);
-        });
-        notebook.show_all ();
-
         wizard = new Wizard (this);
         properties = new Properties (this);
 
+        var vbox_actor = new Clutter.Actor ();
+        var vbox = new Clutter.BoxLayout ();
+        vbox_actor.set_layout_manager (vbox);
+        vbox.set_vertical (true);
+
+        stage_bin.add (vbox_actor,
+                       Clutter.BinAlignment.FILL,
+                       Clutter.BinAlignment.FILL);
+
+        topbar_revealer = new Boxes.Revealer (true);
+        vbox.pack (topbar_revealer, false, true, true, Clutter.BoxAlignment.START, Clutter.BoxAlignment.START);
+        topbar_revealer.add (topbar.actor);
+
+        var below_bin_actor = new Clutter.Actor ();
+        var below_bin = new Clutter.BinLayout (Clutter.BinAlignment.FIXED,
+                                               Clutter.BinAlignment.FIXED);
+        below_bin_actor.set_layout_manager (below_bin);
+
+        vbox.pack (below_bin_actor, true, true, true, Clutter.BoxAlignment.START, Clutter.BoxAlignment.START);
+
+        below_bin.add (view.actor,
+                       Clutter.BinAlignment.FILL,
+                       Clutter.BinAlignment.FILL);
+
+        var hbox_actor = new Clutter.Actor ();
+        var hbox = new Clutter.BoxLayout ();
+        hbox_actor.set_layout_manager (hbox);
+
+        below_bin.add (hbox_actor,
+                       Clutter.BinAlignment.FILL,
+                       Clutter.BinAlignment.FILL);
+
+        overlay_bin_actor = new Clutter.Actor ();
+        overlay_bin = new Clutter.BinLayout (Clutter.BinAlignment.FIXED,
+                                             Clutter.BinAlignment.FIXED);
+        overlay_bin_actor.set_layout_manager (overlay_bin);
+        overlay_bin.set ("use-animations", true,
+                         "easing-mode", Clutter.AnimationMode.LINEAR,
+                         "easing-duration", duration);
+        below_bin.add (overlay_bin_actor,
+                       Clutter.BinAlignment.FILL,
+                       Clutter.BinAlignment.FILL);
+
+        sidebar_revealer = new Boxes.Revealer (false);
+        hbox.pack (sidebar_revealer, false, true, true, Clutter.BoxAlignment.START, Clutter.BoxAlignment.START);
+        sidebar_revealer.unreveal ();
+        sidebar_revealer.add (sidebar.actor);
+
+        var content_bin_actor = new Clutter.Actor ();
+        var content_bin = new Clutter.BinLayout (Clutter.BinAlignment.FILL,
+                                                 Clutter.BinAlignment.FILL);
+        content_bin_actor.set_layout_manager (content_bin);
+        hbox.pack (content_bin_actor, true, true, true, Clutter.BoxAlignment.START, Clutter.BoxAlignment.START);
+
+        below_bin.add (notificationbar.actor, Clutter.BinAlignment.CENTER, Clutter.BinAlignment.START);
+
+        content_bin.add (selectionbar.actor, Clutter.BinAlignment.CENTER, Clutter.BinAlignment.END);
+        content_bin_actor.add (wizard.actor);
+        content_bin_actor.add (properties.actor);
+
+        properties.actor.hide ();
+        selectionbar.actor.hide ();
+
+        notebook.show_all ();
+
         ui_state = UIState.COLLECTION;
     }
 
-    private void set_main_ui_state (string clutter_state) {
+    private void set_main_ui_state () {
         notebook.page = Boxes.AppPage.MAIN;
-        box.set_layout_manager (box_table);
-        state.set_state (clutter_state);
     }
 
     public override void ui_state_changed () {
-        box.set_layout_manager (box_table);
         action_fullscreen.set_enabled (ui_state == UIState.DISPLAY);
         action_properties.set_enabled (ui_state == UIState.DISPLAY);
 
@@ -421,26 +465,8 @@ private class Boxes.App: Boxes.UI {
         }
 
         switch (ui_state) {
-        case UIState.DISPLAY:
-            box.set_layout_manager (new Clutter.FixedLayout ());
-            state.set_state (fullscreen ? "display-fullscreen" : "display");
-            break;
-
-        case UIState.CREDS:
-            set_main_ui_state ("creds");
-            break;
-
         case UIState.COLLECTION:
-            set_main_ui_state ("collection");
-            actor_unpin (topbar.actor);
-            actor_unpin (view.actor);
-            actor_remove (topbar.actor);
-            actor_remove (sidebar.actor);
-            actor_remove (view.actor);
-            box.pack (topbar.actor, "column", 0, "row", 0,
-                      "x-expand", false, "y-expand", false);
-            box.pack (view.actor, "column", 0, "row", 1,
-                      "x-expand", true, "y-expand", true);
+            set_main_ui_state ();
             if (current_item is Machine) {
                 var machine = current_item as Machine;
 
@@ -451,18 +477,13 @@ private class Boxes.App: Boxes.UI {
             view.visible = true;
             break;
 
+        case UIState.CREDS:
         case UIState.PROPERTIES:
         case UIState.WIZARD:
-            actor_remove (topbar.actor);
-            actor_remove (sidebar.actor);
-            actor_remove (view.actor);
-            box.pack (topbar.actor, "column", 0, "row", 0, "column-span", 2,
-                      "x-expand", false, "y-expand", false);
-            box.pack (sidebar.actor, "column", 0, "row", 1,
-                      "x-expand", false, "y-expand", true);
-            box.pack (view.actor, "column", 1, "row", 1,
-                      "x-expand", true, "y-expand", true);
-            set_main_ui_state ("collection");
+            set_main_ui_state ();
+            break;
+
+        case UIState.DISPLAY:
             break;
 
         default:
diff --git a/src/collection-view.vala b/src/collection-view.vala
index 2c5c6dd..7a7ddbd 100644
--- a/src/collection-view.vala
+++ b/src/collection-view.vala
@@ -6,7 +6,6 @@ private class Boxes.CollectionView: Boxes.UI {
 
     private App app;
     private GtkClutter.Actor gtkactor;
-    private Clutter.Box over_boxes; // a box on top of boxes list
 
     private Category _category;
     public Category category {
@@ -40,66 +39,39 @@ private class Boxes.CollectionView: Boxes.UI {
         });
     }
 
-    public void set_over_boxes (Clutter.Actor actor, bool center = false) {
-        if (center)
-            over_boxes.pack (actor,
-                             "x-align", Clutter.BinAlignment.CENTER,
-                             "y-align", Clutter.BinAlignment.CENTER);
-        else
-            over_boxes.pack (actor);
-
-        actor_add (over_boxes, app.stage);
-    }
-
     public override void ui_state_changed () {
+        uint opacity = 0;
         switch (ui_state) {
         case UIState.COLLECTION:
-            actor.show ();
+            opacity = 255;
             icon_view.unselect_all ();
-            actor_remove (app.wizard.actor);
-            actor_remove (over_boxes);
             if (app.current_item != null)
                 actor_remove (app.current_item.actor);
             break;
 
         case UIState.CREDS:
-            set_over_boxes (app.current_item.actor, true);
-            break;
-
-        case UIState.DISPLAY: {
-            float x, y;
-            var display = app.current_item.actor;
-
-            actor.hide ();
-            actor_remove (app.properties.actor);
-
-            if (previous_ui_state == UIState.CREDS) {
-                /* move display/machine actor to stage, keep same position */
-                display.get_transformed_position (out x, out y);
-                actor_remove (display);
-                actor_add (display, app.stage);
-                display.set_position (x, y);
-            }
-            break;
-        }
-
-        case UIState.WIZARD:
-            if (app.current_item != null)
-                actor_remove (app.current_item.actor);
-            app.wizard.actor.add_constraint (new Clutter.BindConstraint (over_boxes, BindCoordinate.SIZE, 0));
-            set_over_boxes (app.wizard.actor);
+            var actor = app.current_item.actor;
+            app.overlay_bin.add (actor,
+                                 Clutter.BinAlignment.FIXED,
+                                 Clutter.BinAlignment.FIXED);
+
+            // TODO: How do I get the icon coords from the iconview?
+            Clutter.ActorBox box = { 20, 20, 20 + Machine.SCREENSHOT_WIDTH, 20 + Machine.SCREENSHOT_HEIGHT};
+            actor.allocate (box, 0);
+            actor.min_width = actor.natural_width = Machine.SCREENSHOT_WIDTH * 2;
+            app.overlay_bin.set_alignment (actor,
+                                           Clutter.BinAlignment.CENTER,
+                                           Clutter.BinAlignment.CENTER);
             break;
 
         case UIState.PROPERTIES:
-            actor_remove (app.current_item.actor);
-            app.properties.actor.add_constraint (new Clutter.BindConstraint (over_boxes, BindCoordinate.SIZE, 0));
-            set_over_boxes (app.properties.actor);
-            break;
-
-        default:
+            var item_actor = app.current_item.actor;
+            item_actor.hide ();
             break;
         }
 
+        fade_actor (actor, opacity);
+
         if (app.current_item != null)
             app.current_item.ui_state = ui_state;
     }
@@ -245,17 +217,5 @@ private class Boxes.CollectionView: Boxes.UI {
         scrolled_window.show_all ();
 
         gtkactor = new GtkClutter.Actor.with_contents (scrolled_window);
-
-        over_boxes = new Clutter.Box (new Clutter.BinLayout (Clutter.BinAlignment.FILL, Clutter.BinAlignment.FILL));
-        over_boxes.add_constraint_with_name ("top-box-size",
-                                             new Clutter.BindConstraint (gtkactor, BindCoordinate.SIZE, 0));
-        over_boxes.add_constraint_with_name ("top-box-position",
-                                             new Clutter.BindConstraint (gtkactor, BindCoordinate.POSITION, 0));
-
-        app.state.set_key (null, "creds", actor, "opacity", AnimationMode.EASE_OUT_QUAD, (uint) 0, 0, 0);
-        app.state.set_key (null, "display", actor, "opacity", AnimationMode.EASE_OUT_QUAD, (uint) 0, 0, 0);
-        app.state.set_key (null, "collection", actor, "opacity", AnimationMode.EASE_OUT_QUAD, (uint) 255, 0, 0);
-        app.state.set_key (null, "display", over_boxes, "x", AnimationMode.EASE_OUT_QUAD, (float) 0, 0, 0);
-        app.state.set_key (null, "display", over_boxes, "y", AnimationMode.EASE_OUT_QUAD, (float) 0, 0, 0);
     }
 }
diff --git a/src/display-page.vala b/src/display-page.vala
index 4592a61..67c32da 100644
--- a/src/display-page.vala
+++ b/src/display-page.vala
@@ -13,6 +13,9 @@ private class Boxes.DisplayToolbar: Gtk.Toolbar {
         get_style_context ().add_class (STYLE_CLASS_MENUBAR);
         set_show_arrow (false);
 
+        // Make sure we're the same size as the normal toolbar
+        this.set_size_request (-1, (int) Topbar.height);
+
         var left_group = new ToolItem ();
         insert (left_group, 0);
 
@@ -28,6 +31,7 @@ private class Boxes.DisplayToolbar: Gtk.Toolbar {
         size_group.add_widget (right_group);
 
         var left_box = new Box (Orientation.HORIZONTAL, 0);
+        left_box.valign = Gtk.Align.CENTER;
         left_group.add (left_box);
 
         var back = new Button ();
@@ -44,6 +48,7 @@ private class Boxes.DisplayToolbar: Gtk.Toolbar {
         center_group.add (label);
 
         var right_box = new Box (Orientation.HORIZONTAL, 12);
+        right_box.valign = Gtk.Align.CENTER;
         right_group.add(right_box);
 
         var btn = new Button ();
diff --git a/src/machine.vala b/src/machine.vala
index 80e2cbe..058c71f 100644
--- a/src/machine.vala
+++ b/src/machine.vala
@@ -255,10 +255,9 @@ private abstract class Boxes.Machine: Boxes.CollectionItem, Boxes.IPropertiesPro
 }
 
 private class Boxes.MachineActor: Boxes.UI {
-    public override Clutter.Actor actor { get { return box; } }
-    public Clutter.Box box;
+    public override Clutter.Actor actor { get { return _actor; } }
+    public Clutter.Actor _actor;
 
-    private Clutter.BindConstraint yconstraint;
     private GtkClutter.Texture screenshot;
     private GtkClutter.Actor gtk_vbox;
     private GtkClutter.Actor? display;
@@ -268,8 +267,6 @@ private class Boxes.MachineActor: Boxes.UI {
     private Machine machine;
     private ulong height_id;
 
-    static const int properties_y = 200;
-
     ~MachineActor() {
         machine.app.actor.disconnect (height_id);
         height_id = 0;
@@ -281,17 +278,22 @@ private class Boxes.MachineActor: Boxes.UI {
         var layout = new Clutter.BoxLayout ();
         layout.vertical = true;
         layout.spacing = 10;
-        box = new Clutter.Box (layout);
+        _actor = new Clutter.Actor ();
+        _actor.set_layout_manager (layout);
 
         screenshot = new GtkClutter.Texture ();
         screenshot.name = "screenshot";
         set_screenshot (machine.pixbuf);
-        scale_screenshot ();
-        actor_add (screenshot, box);
+        _actor.min_width = _actor.natural_width = Machine.SCREENSHOT_WIDTH;
+
         screenshot.keep_aspect_ratio = true;
+        _actor.add (screenshot);
 
         vbox = new Gtk.VBox (false, 0);
         gtk_vbox = new GtkClutter.Actor.with_contents (vbox);
+        // Ensure we have enough space to fit everything without changing
+        // size, as that causes weird re-animations
+        gtk_vbox.height = 80;
 
         gtk_vbox.get_widget ().get_style_context ().add_class ("boxes-bg");
 
@@ -299,6 +301,7 @@ private class Boxes.MachineActor: Boxes.UI {
         label.modify_fg (Gtk.StateType.NORMAL, get_color ("white"));
         machine.bind_property ("name", label, "label", BindingFlags.DEFAULT);
         vbox.add (label);
+        vbox.set_valign (Gtk.Align.START);
         password_entry = new Gtk.Entry ();
         password_entry.set_visibility (false);
         password_entry.set_placeholder_text (_("Password"));
@@ -319,21 +322,8 @@ private class Boxes.MachineActor: Boxes.UI {
         vbox.show_all ();
         password_entry.hide ();
 
-        actor_add (gtk_vbox, box);
-        actor.set_reactive (true);
-
-        yconstraint = new Clutter.BindConstraint (machine.app.actor, BindCoordinate.Y,
-                                                  machine.app.actor.height - properties_y);
-        height_id = machine.app.actor.notify["height"].connect (() => {
-            yconstraint.set_offset (machine.app.actor.height - properties_y);
-        });
-
-        yconstraint.enabled = false;
-    }
-
-    public void scale_screenshot (float scale = 1.5f) {
-        screenshot.set_size (Machine.SCREENSHOT_WIDTH * scale,
-                             Machine.SCREENSHOT_HEIGHT * scale);
+        _actor.add (gtk_vbox);
+        _actor.set_reactive (true);
     }
 
     public void set_screenshot (Gdk.Pixbuf pixbuf) {
@@ -345,6 +335,7 @@ private class Boxes.MachineActor: Boxes.UI {
     }
 
     public void set_password_needed (bool needed) {
+        _actor.queue_relayout ();
         password_entry.visible = needed;
         password_entry.set_can_focus (needed);
         if (needed) {
@@ -368,7 +359,6 @@ private class Boxes.MachineActor: Boxes.UI {
         int width, height;
         int x, y;
 
-        yconstraint.enabled = false;
         machine.app.display_page.get_size (out width, out height);
         machine.app.window.get_size (out window_width, out window_height);
         x = window_width - width;
@@ -376,44 +366,40 @@ private class Boxes.MachineActor: Boxes.UI {
 
         switch (ui_state) {
         case UIState.CREDS:
-            scale_screenshot (2.0f);
+            gtk_vbox.show ();
             break;
 
         case UIState.DISPLAY:
+            gtk_vbox.hide ();
             if (previous_ui_state == UIState.CREDS) {
-                password_entry.hide ();
-                label.hide ();
-                screenshot.animate (Clutter.AnimationMode.LINEAR, machine.app.duration,
-                                    "width", (float) width,
-                                    "height", (float) height);
-                actor.animate (Clutter.AnimationMode.LINEAR, machine.app.duration,
-                               "x", (float) x,
-                               "y", (float) y);
+                machine.app.overlay_bin.set_alignment (actor,
+                                                       Clutter.BinAlignment.FILL,
+                                                       Clutter.BinAlignment.FILL);
             } else {
                 if (display != null) {
                     // zoom in, back from properties
-                    var anim = display.animate (Clutter.AnimationMode.LINEAR, machine.app.duration,
-                                                "x", (float) x,
-                                                "y", (float) y,
-                                                "width", (float) width,
-                                                "height", (float) height);
-                    anim.completed.connect (() => {
-                        actor_remove (display);
-                        var widget = display.contents;
-                        display.contents = null;
-                        display = null;
-                        // FIXME: enable grabs
-                        machine.display.set_enable_inputs (widget, true);
-                        machine.app.display_page.show_display (machine.display, widget);
-                    });
+
+                    machine.app.overlay_bin.set_alignment (display,
+                                                           Clutter.BinAlignment.FILL,
+                                                           Clutter.BinAlignment.FILL);
+
+                    /* Todo: No good way to get the end of the transision yet? */
+                    Timeout.add (machine.app.duration, () => {
+                            var widget = display.contents;
+                            display.contents = null;
+                            display.destroy ();
+                            display = null;
+                            // FIXME: enable grabs
+                            machine.display.set_enable_inputs (widget, true);
+                            machine.app.display_page.show_display (machine.display, widget);
+                            return false;
+                        });
                 } else
                     machine.app.display_page.show ();
             }
-
             break;
 
         case UIState.COLLECTION:
-            scale_screenshot ();
             password_entry.set_can_focus (false);
             password_entry.hide ();
             label.show ();
@@ -423,20 +409,34 @@ private class Boxes.MachineActor: Boxes.UI {
             var widget = machine.app.display_page.remove_display ();
             machine.display.set_enable_inputs (widget, false);
             display = new GtkClutter.Actor.with_contents (widget);
-            display.x = 0.0f;
-            display.y = 0.0f;
-            display.width = (float) width;
-            display.height = (float) height;
-            actor_add (display, machine.app.stage);
-            display.add_constraint (yconstraint);
-
-            display.animate (Clutter.AnimationMode.LINEAR, machine.app.duration,
-                             "x", 10.0f,
-                             "y", height - 200.0f,
-                             "width", 180.0f,
-                             "height", 130.0f).completed.connect (() => {
-                                 yconstraint.enabled = true;
-                             });
+            machine.app.overlay_bin.add (display,
+                                         Clutter.BinAlignment.FILL,
+                                         Clutter.BinAlignment.FILL);
+
+            Clutter.ActorBox box = { 0, 0,  width, height};
+            display.allocate (box, 0);
+            display.show ();
+
+            // Temporarily hide toolbar in fullscreen so that the the animation
+            // actor doesn't get pushed down before zooming to the sidebar
+            if (machine.app.fullscreen)
+                machine.app.topbar.actor.hide ();
+
+            ulong id = 0;
+            id = machine.app.properties.screenshot_placeholder.size_allocate.connect ( (alloc) => {
+                machine.app.properties.screenshot_placeholder.disconnect (id);
+                Idle.add_full (Priority.HIGH, () => {
+                    machine.app.topbar.actor.show ();
+                    machine.app.overlay_bin.set_alignment (display,
+                                                           Clutter.BinAlignment.FIXED,
+                                                           Clutter.BinAlignment.FIXED);
+                    display.x = alloc.x;
+                    display.y = alloc.y;
+                    display.width = alloc.width;
+                    display.height = alloc.height;
+                    return false;
+                });
+            });
 
             break;
 
diff --git a/src/notificationbar.vala b/src/notificationbar.vala
index a20cb9d..531ed18 100644
--- a/src/notificationbar.vala
+++ b/src/notificationbar.vala
@@ -2,12 +2,14 @@
 using Gtk;
 
 private class Boxes.Notificationbar: GLib.Object {
-    public Clutter.Actor actor { get; private set; }
+    public Clutter.Actor actor { get { return revealer; } }
     public static const float spacing = 60.0f;
 
     public delegate void OKFunc ();
     public delegate void CancelFunc ();
 
+    public GtkClutter.Actor gtk_actor;
+    public Revealer revealer;
     private App app;
     private InfoBar info_bar;
     private Label message_label;
@@ -101,6 +103,9 @@ private class Boxes.Notificationbar: GLib.Object {
     }
 
     private void setup_action_notify () {
+        revealer = new Revealer (true);
+        revealer.unreveal ();
+
         info_bar = new InfoBar ();
         info_bar.get_style_context ().add_class ("osd");
         info_bar.margin = 5;
@@ -126,22 +131,15 @@ private class Boxes.Notificationbar: GLib.Object {
 
         info_bar.show_all ();
 
-        actor = new GtkClutter.Actor.with_contents (info_bar);
-        app.stage.add (actor);
-        actor.hide ();
-        actor.scale_y = 0f;
+        gtk_actor = new GtkClutter.Actor.with_contents (info_bar);
+        revealer.add (gtk_actor);
     }
 
     private void show () {
-        app.stage.set_child_above_sibling (actor, null);
-        actor.show ();
-        actor.queue_redraw ();
-        actor.animate (Clutter.AnimationMode.LINEAR, app.duration, "scale-y", 1f);
+        revealer.reveal ();
     }
 
     private void hide () {
-        var animation = actor.animate (Clutter.AnimationMode.LINEAR, app.duration, "scale-y", 0f);
-        animation.completed.connect (() => { actor.hide (); });
+        revealer.unreveal ();
     }
 }
-
diff --git a/src/properties.vala b/src/properties.vala
index cc4a23a..630a0be 100644
--- a/src/properties.vala
+++ b/src/properties.vala
@@ -13,6 +13,7 @@ private enum Boxes.PropertiesPage {
 private class Boxes.Properties: Boxes.UI {
     public override Clutter.Actor actor { get { return gtk_actor; } }
 
+    public Gtk.Widget screenshot_placeholder;
     private GtkClutter.Actor gtk_actor;
     private Boxes.App app;
     private Gtk.Notebook notebook;
@@ -135,6 +136,7 @@ private class Boxes.Properties: Boxes.UI {
         notebook.show_tabs = false;
         notebook.get_style_context ().add_class ("boxes-bg");
         gtk_actor = new GtkClutter.Actor.with_contents (notebook);
+        gtk_actor.opacity = 0;
 
         /* topbar */
         var hbox = app.topbar.notebook.get_nth_page (Boxes.TopbarPage.PROPERTIES) as Gtk.HBox;
@@ -184,38 +186,43 @@ private class Boxes.Properties: Boxes.UI {
         vbox.pack_start (grid, false, false, 0);
         grid.column_homogeneous = true;
         grid.column_spacing = 2;
+        grid.row_spacing = 10;
         grid.margin_left = 10;
         grid.margin_right = 10;
-        /* this will need to be FIXME */
         grid.margin_bottom = 30;
-        grid.margin_top = 200;
+        grid.margin_top = 10;
+
+        screenshot_placeholder = new Gtk.Alignment (0.0f, 0.0f, 0.0f, 0.0f);
+        screenshot_placeholder.set_size_request (180, 130);
+        grid.attach (screenshot_placeholder, 0, 0, 6, 1);
 
         var label = new Gtk.Label (_("CPU:"));
         label.get_style_context ().add_class ("boxes-graph-label");
-        grid.attach (label, 0, 0, 1, 1);
+        grid.attach (label, 0, 1, 1, 1);
         cpu = new MiniGraph.with_ymax ({}, 100.0, 20);
         cpu.hexpand = true;
-        grid.attach (cpu, 1, 0, 1, 1);
+        grid.attach (cpu, 1, 1, 1, 1);
 
         label = new Gtk.Label (_("I/O:"));
         label.get_style_context ().add_class ("boxes-graph-label");
-        grid.attach (label, 2, 0, 1, 1);
+        grid.attach (label, 2, 1, 1, 1);
         io = new MiniGraph ({}, 20);
         io.hexpand = true;
-        grid.attach (io, 3, 0, 1, 1);
+        grid.attach (io, 3, 1, 1, 1);
 
         label = new Gtk.Label (_("Net:"));
         label.get_style_context ().add_class ("boxes-graph-label");
-        grid.attach (label, 4, 0, 1, 1);
+        grid.attach (label, 4, 1, 1, 1);
         net = new MiniGraph ({}, 20);
         net.hexpand = true;
-        grid.attach (net, 5, 0, 1, 1);
+        grid.attach (net, 5, 1, 1, 1);
 
         vbox.show_all ();
         notebook.show_all ();
     }
 
     public override void ui_state_changed () {
+        uint opacity = 0;
         if (stats_id != 0) {
             app.current_item.disconnect (stats_id);
             stats_id = 0;
@@ -225,7 +232,9 @@ private class Boxes.Properties: Boxes.UI {
         case UIState.PROPERTIES:
             toolbar_label_bind = app.current_item.bind_property ("name", toolbar_label, "label", BindingFlags.SYNC_CREATE);
             populate ();
+            opacity = 255;
             break;
         }
+        fade_actor (actor, opacity);
     }
 }
diff --git a/src/selectionbar.vala b/src/selectionbar.vala
index 524f4e6..7f87c4b 100644
--- a/src/selectionbar.vala
+++ b/src/selectionbar.vala
@@ -46,7 +46,6 @@ private class Boxes.Selectionbar: GLib.Object {
         toolbar.show_all ();
 
         actor.reactive = true;
-        actor.hide ();
 
         app.notify["selection-mode"].connect (() => {
             update_visible ();
@@ -55,8 +54,6 @@ private class Boxes.Selectionbar: GLib.Object {
         app.notify["selected-items"].connect (() => {
             update_visible ();
         });
-
-        app.stage.add (actor);
     }
 
     private void update_visible () {
diff --git a/src/sidebar.vala b/src/sidebar.vala
index e09fb21..60f4f7f 100644
--- a/src/sidebar.vala
+++ b/src/sidebar.vala
@@ -44,15 +44,17 @@ private class Boxes.Sidebar: Boxes.UI {
     public override void ui_state_changed () {
         switch (ui_state) {
         case UIState.COLLECTION:
+            app.sidebar_revealer.unreveal ();
             notebook.page = SidebarPage.COLLECTION;
             break;
 
-        case UIState.DISPLAY:
-            actor_pin (actor);
-            break;
+		default:
+            app.sidebar_revealer.unreveal ();
+			break;
 
         case UIState.WIZARD:
         case UIState.PROPERTIES:
+            app.sidebar_revealer.reveal ();
             notebook.page = ui_state == UIState.WIZARD ? SidebarPage.WIZARD : SidebarPage.PROPERTIES;
             break;
         }
@@ -177,8 +179,5 @@ private class Boxes.Sidebar: Boxes.UI {
         notebook.append_page (vbox, null);
 
         notebook.show_all ();
-
-        // FIXME: make it dynamic depending on sidebar size..:
-        app.state.set_key (null, "display", gtk_actor, "x", AnimationMode.EASE_OUT_QUAD, -(float) width, 0, 0);
     }
 }
diff --git a/src/topbar.vala b/src/topbar.vala
index c0163cc..47ec350 100644
--- a/src/topbar.vala
+++ b/src/topbar.vala
@@ -147,9 +147,6 @@ private class Boxes.Topbar: Boxes.UI {
 
         notebook.show_tabs = false;
         notebook.show_all ();
-
-        // FIXME: make it dynamic depending on topbar size..:
-        app.state.set_key (null, "display-fullscreen", gtk_actor, "y", AnimationMode.EASE_OUT_QUAD, -(float) height, 0, 0);
     }
 
     private void update_select_btn_sensitivity () {
@@ -182,7 +179,6 @@ private class Boxes.Topbar: Boxes.UI {
             break;
 
         case UIState.DISPLAY:
-            actor_pin (gtk_actor);
             break;
 
         case UIState.PROPERTIES:
@@ -198,4 +194,3 @@ private class Boxes.Topbar: Boxes.UI {
         }
     }
 }
-
diff --git a/src/wizard-source.vala b/src/wizard-source.vala
index c146316..d680bb9 100644
--- a/src/wizard-source.vala
+++ b/src/wizard-source.vala
@@ -153,6 +153,9 @@ private class Boxes.WizardSource: GLib.Object {
         url_label.set_markup (_("<b>Desktop Access</b>\n\nWill add boxes for all systems available from this account."));
         url_label.set_use_markup (true);
         url_label.wrap = true;
+        // Work around clutter size allocation issue (bz#677260)
+        url_label.width_chars = 30;
+
         hbox.pack_start (url_label, true, true);
         vbox.add (hbox);
 
diff --git a/src/wizard.vala b/src/wizard.vala
index dc8c282..1955b57 100644
--- a/src/wizard.vala
+++ b/src/wizard.vala
@@ -387,6 +387,7 @@ private class Boxes.Wizard: Boxes.UI {
         notebook.show_tabs = false;
         notebook.get_style_context ().add_class ("boxes-bg");
         gtk_actor = new GtkClutter.Actor.with_contents (notebook);
+        gtk_actor.opacity = 0;
 
         /* Introduction */
         var hbox = new Gtk.HBox (false, 10);
@@ -397,6 +398,8 @@ private class Boxes.Wizard: Boxes.UI {
         label.set_markup (_("Creating a Box will allow you to use another operating system directly from your existing login.\n\nYou may connect to an existing machine <b><i>over the network</i></b> or create a <b><i>virtual machine</i></b> that runs locally on your own."));
         label.set_use_markup (true);
         label.wrap = true;
+        // Work around clutter size allocation issue (bz#677260)
+        label.width_chars = 30;
         label.halign = Gtk.Align.START;
         hbox.add (label);
         hbox.show_all ();
@@ -410,6 +413,8 @@ private class Boxes.Wizard: Boxes.UI {
         label = new Gtk.Label (_("Insert operating system installation media or select a source below"));
         label.get_style_context ().add_class ("boxes-wizard-label");
         label.wrap = true;
+        // Work around clutter size allocation issue (bz#677260)
+        label.width_chars = 30;
         label.xalign = 0.0f;
         vbox.pack_start (label, false, false);
         vbox.pack_start (wizard_source.widget, false, false);
@@ -418,6 +423,8 @@ private class Boxes.Wizard: Boxes.UI {
         label = new Gtk.Label (_("Any trademarks shown above are used merely for identification of software products you have already obtained and are the property of their respective owners."));
         label.get_style_context ().add_class ("boxes-logo-notice-label");
         label.wrap = true;
+        // Work around clutter size allocation issue (bz#677260)
+        label.width_chars = 30;
         label.max_width_chars = 50;
         vbox.pack_start (label, false, false);
         vbox.show_all ();
@@ -431,6 +438,8 @@ private class Boxes.Wizard: Boxes.UI {
         label = new Gtk.Label (_("Preparing to create new box"));
         label.get_style_context ().add_class ("boxes-wizard-label");
         label.wrap = true;
+        // Work around clutter size allocation issue (bz#677260)
+        label.width_chars = 30;
         label.xalign = 0.0f;
         vbox.pack_start (label, false, false);
 
@@ -535,11 +544,15 @@ private class Boxes.Wizard: Boxes.UI {
     }
 
     public override void ui_state_changed () {
+        uint opacity = 0;
         switch (ui_state) {
         case UIState.WIZARD:
             page = WizardPage.INTRODUCTION;
+            opacity = 255;
             break;
         }
+
+        fade_actor (actor, opacity);
     }
 
     private class WizardSummary: GLib.Object {



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