[gtk+/wip/csoriano/pathbar-bin-view-window: 65/65] Experiment with a view and bin window



commit ded3d2738a186b8d8234dccbfb21b491a76d0511
Author: Carlos Soriano <csoriano gnome org>
Date:   Thu Jun 2 17:01:49 2016 +0200

    Experiment with a view and bin window

 gtk/gtkhidingbox.c                       |  584 ++++++++++++++++++------------
 gtk/gtkhidingbox.h                       |   13 +-
 gtk/gtkwindow.c                          |    3 +-
 gtk/theme/Adwaita/_common.scss           |    8 +-
 gtk/theme/Adwaita/gtk-contained-dark.css |   12 +-
 gtk/theme/Adwaita/gtk-contained.css      |   12 +-
 tests/testhidingbox.c                    |   11 +-
 7 files changed, 393 insertions(+), 250 deletions(-)
---
diff --git a/gtk/gtkhidingbox.c b/gtk/gtkhidingbox.c
index 2417741..1be948d 100644
--- a/gtk/gtkhidingbox.c
+++ b/gtk/gtkhidingbox.c
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2015 Rafał Lużyński <digitalfreak lingonborough com>
- * Copyright (C) 2015 Red Hat
+ * Copyright (C) 2016 Red Hat
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -18,8 +17,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Authors: Rafał Lużyński <digitalfreak lingonborough com>
- *          Carlos Soriano <csoriano gnome org>
+ * Authors: Carlos Soriano <csoriano gnome org>
  */
 
 #include "config.h"
@@ -30,7 +28,6 @@
 #include "gtksizerequest.h"
 #include "gtkbuildable.h"
 #include "gtkrevealer.h"
-#include "gtkadjustment.h"
 #include "gtkscrolledwindow.h"
 #include "gtkbox.h"
 
@@ -40,12 +37,11 @@
 #include "glib.h"
 
 #define REVEALER_ANIMATION_TIME 250 //ms
-#define INVERT_ANIMATION_SPEED 0.1 //px/ms
+#define INVERT_ANIMATION_SPEED 1.5 //px/ms
 
 struct _GtkHidingBoxPrivate
 {
   GList *children;
-  gint16 spacing;
   gint inverted :1;
   GList *widgets_to_hide;
   GList *widgets_to_show;
@@ -56,54 +52,24 @@ struct _GtkHidingBoxPrivate
 
   gboolean invert_animation;
 
-  GtkWidget *scrolled_window;
+  GdkWindow *bin_window;
+  GdkWindow *view_window;
+
   GtkWidget *box;
-  GtkAdjustment *hadjustment;
 
   guint invert_animation_tick_id;
   double invert_animation_progress;
+  gint invert_animation_initial_children_width;
   guint64 invert_animation_initial_time;
   gint allocated_children_width;
   gint total_children_width;
   gint previous_child_width;
 };
 
-static void
-gtk_hiding_box_buildable_init (GtkBuildableIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GtkHidingBox, gtk_hiding_box, GTK_TYPE_CONTAINER,
-                         G_ADD_PRIVATE (GtkHidingBox)
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gtk_hiding_box_buildable_init))
-
-
-static void
-gtk_hiding_box_buildable_add_child (GtkBuildable *buildable,
-                                    GtkBuilder   *builder,
-                                    GObject      *child,
-                                    const gchar  *type)
-{
-  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (GTK_HIDING_BOX (buildable));
-
-  if (!type)
-    {
-      gtk_container_add (GTK_CONTAINER (buildable), GTK_WIDGET (child));
-      priv->needs_update = TRUE;
-    }
-  else
-    {
-      GTK_BUILDER_WARN_INVALID_CHILD_TYPE (GTK_HIDING_BOX (buildable), type);
-    }
-}
-
-static void
-gtk_hiding_box_buildable_init (GtkBuildableIface *iface)
-{
-  iface->add_child = gtk_hiding_box_buildable_add_child;
-}
+G_DEFINE_TYPE_WITH_PRIVATE (GtkHidingBox, gtk_hiding_box, GTK_TYPE_BIN)
 
 enum {
   PROP_0,
-  PROP_SPACING,
   PROP_INVERTED,
   LAST_PROP
 };
@@ -120,9 +86,6 @@ gtk_hiding_box_set_property (GObject      *object,
 
   switch (prop_id)
     {
-    case PROP_SPACING:
-      gtk_hiding_box_set_spacing (box, g_value_get_int (value));
-      break;
     case PROP_INVERTED:
       gtk_hiding_box_set_inverted (box, g_value_get_boolean (value));
       break;
@@ -143,9 +106,6 @@ gtk_hiding_box_get_property (GObject    *object,
 
   switch (prop_id)
     {
-    case PROP_SPACING:
-      g_value_set_int (value, priv->spacing);
-      break;
     case PROP_INVERTED:
       g_value_set_boolean (value, priv->inverted);
       break;
@@ -155,25 +115,25 @@ gtk_hiding_box_get_property (GObject    *object,
     }
 }
 
-static void
-gtk_hiding_box_add (GtkContainer *container,
+void
+gtk_hiding_box_add (GtkHidingBox *self,
                     GtkWidget    *widget)
 {
-  GtkHidingBox *box = GTK_HIDING_BOX (container);
+  GtkHidingBox *box = GTK_HIDING_BOX (self);
   GtkWidget *revealer;
   GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box);
   GtkStyleContext *style_context;
 
   revealer = gtk_revealer_new ();
   style_context = gtk_widget_get_style_context (revealer);
-  gtk_style_context_add_class (style_context, "pathbar-initial-opacity");
+  //gtk_style_context_add_class (style_context, "pathbar-initial-opacity");
   gtk_revealer_set_transition_type (GTK_REVEALER (revealer),
                                     GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT);
   gtk_container_add (GTK_CONTAINER (revealer), widget);
   g_print ("box fine? %s \n", G_OBJECT_TYPE_NAME (priv->box));
   gtk_container_add (GTK_CONTAINER (priv->box), revealer);
   priv->children = g_list_append (priv->children, widget);
-  gtk_widget_show (revealer);
+  gtk_widget_show_all (revealer);
 
   g_print ("add\n");
 }
@@ -220,12 +180,11 @@ unrevealed_really_remove_child (GObject    *widget,
   really_remove_child (self, gtk_bin_get_child (GTK_BIN (widget)));
 }
 
-static void
-gtk_hiding_box_remove (GtkContainer *container,
+void
+gtk_hiding_box_remove (GtkHidingBox *self,
                        GtkWidget    *widget)
 {
-  GtkHidingBox *box = GTK_HIDING_BOX (container);
-  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
   GtkWidget *to_remove;
 
   g_print ("remove %p %s\n", widget, G_OBJECT_TYPE_NAME (widget));
@@ -237,29 +196,68 @@ gtk_hiding_box_remove (GtkContainer *container,
   priv->widgets_to_remove = g_list_append (priv->widgets_to_remove, to_remove);
   priv->children = g_list_remove (priv->children, to_remove);
   priv->needs_update = TRUE;
-  gtk_widget_queue_resize (GTK_WIDGET (container));
+
+  gtk_widget_queue_resize (GTK_WIDGET (self));
 }
 
-static void
-gtk_hiding_box_forall (GtkContainer *container,
-                       gboolean      include_internals,
-                       GtkCallback   callback,
-                       gpointer      callback_data)
+static GtkAllocation*
+get_children_allocation (GtkHidingBox *self,
+                         gboolean      inverted)
 {
-  GtkHidingBox *box = GTK_HIDING_BOX (container);
-  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+  GtkAllocation *children_allocation;
+  GtkAllocation *allocation;
+  GtkWidget *child_widget;
   GList *child;
+  GtkRequestedSize *sizes_temp;
+  gint i;
+  GList *children;
+  gint current_children_min_width = 0;
+  gint current_children_nat_width = 0;
 
-  for (child = priv->children; child != NULL; child = child->next)
-    (* callback) (child->data, callback_data);
+  children = g_list_copy (priv->children);
+  sizes_temp = g_newa (GtkRequestedSize, g_list_length (priv->children));
+  allocation = g_new (GtkAllocation, 1);
+  gtk_widget_get_allocation (GTK_WIDGET (self), allocation);
+  children_allocation = g_new (GtkAllocation, 1);
+  children_allocation->x = 0;
+  children_allocation->y = 0;
+  children_allocation->height = allocation->height;
+
+  if (inverted)
+    children = g_list_reverse (children);
 
-  if (include_internals)
-  {
-    (* callback) (priv->scrolled_window, callback_data);
+  /* Retrieve desired size for visible children. */
+  for (i = 0, child = children; child != NULL; i++, child = child->next)
+    {
+      child_widget = GTK_WIDGET (child->data);
 
-    for (child = priv->widgets_to_remove; child != NULL; child = child->next)
-      (* callback) (child->data, callback_data);
-  }
+      /* If we are in the middle of a revealer animation, get the revealer
+       * allocation */
+      gtk_widget_get_preferred_width_for_height (gtk_widget_get_parent (child_widget),
+                                                 allocation->height,
+                                                 &sizes_temp[i].minimum_size,
+                                                 &sizes_temp[i].natural_size);
+
+      current_children_min_width += sizes_temp[i].minimum_size;
+      current_children_nat_width += sizes_temp[i].natural_size;
+      if (current_children_min_width > allocation->width)
+        {
+          current_children_min_width -= sizes_temp[i].minimum_size;
+          current_children_nat_width -= sizes_temp[i].natural_size;
+          break;
+        }
+    }
+
+  if (current_children_nat_width > allocation->width)
+    children_allocation->width = current_children_min_width;
+  else
+    children_allocation->width = current_children_nat_width;
+
+  g_list_free (children);
+  g_free (allocation);
+
+  return children_allocation;
 }
 
 static void
@@ -364,52 +362,51 @@ opacity_off (GObject    *widget,
 
   g_print ("opacity off!!!!!\n");
   g_signal_handlers_disconnect_by_func (widget, opacity_off, user_data);
-  priv->widgets_to_hide = g_list_remove (priv->widgets_to_hide,
-                                         gtk_bin_get_child (GTK_BIN (widget)));
+  priv->widgets_to_hide = g_list_remove (priv->widgets_to_hide, gtk_bin_get_child (GTK_BIN (widget)));
   remove_all_opacity_classes (GTK_WIDGET (widget));
 }
 
 static void
-idle_update_revealers (GtkHidingBox *box)
+idle_update_revealers (GtkHidingBox *self)
 {
-  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
   GList *l;
+  GList *widgets_to_hide_copy;
 
-  for (l = priv->widgets_to_hide; l != NULL; l = l->next)
+  g_print ("UPDATE REVEALERS\n");
+  widgets_to_hide_copy = g_list_copy (priv->widgets_to_hide);
+  for (l = widgets_to_hide_copy; l != NULL; l = l->next)
     {
       GtkWidget *revealer;
 
-      g_print ("update revealer hide %s\n", gtk_button_get_label (GTK_BUTTON (l->data)));
       revealer = gtk_widget_get_parent (l->data);
-      if (gtk_revealer_get_reveal_child (GTK_REVEALER (revealer)))
+      g_print ("widget to hide %s\n", gtk_button_get_label (GTK_BUTTON (l->data)));
+      if (gtk_revealer_get_child_revealed (GTK_REVEALER (revealer)) &&
+          gtk_revealer_get_reveal_child (GTK_REVEALER (revealer)))
         {
           remove_all_opacity_classes (revealer);
           if (priv->invert_animation && priv->invert_animation_progress >= 1)
             {
               gdouble velocity = INVERT_ANIMATION_SPEED; // px / ms
               gint revealer_animation_time;
-              gdouble max_real_adjustment;
-
-              max_real_adjustment = gtk_adjustment_get_upper (priv->hadjustment) -
-                                    gtk_widget_get_allocated_width (priv->scrolled_window);
 
-              g_print ("animation velocity %f %f\n", max_real_adjustment, velocity);
-              revealer_animation_time = (gtk_widget_get_allocated_width (priv->scrolled_window) -
-                                         priv->allocated_children_width) /
-                                         velocity;
-              g_print ("animation time %d %d %d\n", priv->allocated_children_width, 
gtk_widget_get_allocated_width (priv->scrolled_window), revealer_animation_time);
               add_opacity_class (revealer, "pathbar-invert-animation-opacity-off");
-              g_signal_connect (revealer, "notify::child-revealed", (GCallback) opacity_off, box);
-              gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), revealer_animation_time);
+  g_signal_handlers_disconnect_by_func (revealer, opacity_off, self);
+              g_signal_connect (revealer, "notify::child-revealed", (GCallback) opacity_off, self);
+              gtk_revealer_set_transition_duration (GTK_REVEALER (revealer),
+                                                    priv->inverted ? 0 :
+                                                                     REVEALER_ANIMATION_TIME);
 
               gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE);
+              g_print ("~~~~~~~~ finishing\n");
             }
           else if (!priv->invert_animation)
             {
               add_opacity_class (revealer, "pathbar-opacity-off");
-              g_signal_connect (revealer, "notify::child-revealed", (GCallback) opacity_off, box);
-              gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), REVEALER_ANIMATION_TIME);
+  g_signal_handlers_disconnect_by_func (revealer, opacity_off, self);
+              g_signal_connect (revealer, "notify::child-revealed", (GCallback) opacity_off, self);
               gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE);
+              g_print ("~~~~~~~~ NOT finishing\n");
             }
 #if 0
           if (!priv->invert_animation)
@@ -422,26 +419,26 @@ idle_update_revealers (GtkHidingBox *box)
 #endif
         }
     }
+  g_list_free (widgets_to_hide_copy);
 
   for (l = priv->widgets_to_remove; l != NULL; l = l->next)
     {
       GtkWidget *revealer;
 
-      g_print ("update revealer remove %s\n", gtk_button_get_label (GTK_BUTTON (l->data)));
       revealer = gtk_widget_get_parent (l->data);
       if (gtk_revealer_get_child_revealed (GTK_REVEALER (revealer)))
         {
           remove_all_opacity_classes (revealer);
           add_opacity_class (revealer, "pathbar-opacity-off");
           g_signal_connect (revealer, "notify::child-revealed",
-                            (GCallback) unrevealed_really_remove_child, box);
+                            (GCallback) unrevealed_really_remove_child, self);
           gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), REVEALER_ANIMATION_TIME);
           gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE);
         }
       else
         {
           g_print ("widget to remove NOT revealed %p\n", l->data);
-          really_remove_child (box, l->data);
+          really_remove_child (self, l->data);
         }
     }
 
@@ -462,89 +459,155 @@ idle_update_revealers (GtkHidingBox *box)
           else
             gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), REVEALER_ANIMATION_TIME);
           gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE);
-          g_signal_connect (revealer, "notify::child-revealed", (GCallback) opacity_on, box);
+          g_signal_connect (revealer, "notify::child-revealed", (GCallback) opacity_on, self);
         }
     }
 
 }
 
-static void
-gtk_hiding_box_size_allocate (GtkWidget     *widget,
-                              GtkAllocation *allocation)
+static gint
+get_max_scroll (GtkHidingBox *self)
 {
-  GtkHidingBox *box = GTK_HIDING_BOX (widget);
-  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box);
-  GtkAllocation child_allocation;
-  GtkRequestedSize *sizes;
-
-  gtk_widget_set_allocation (widget, allocation);
-
-  sizes = g_newa (GtkRequestedSize, g_list_length (priv->children));
-  update_children_visibility (box, allocation);
-
-  idle_update_revealers (box);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+  GtkAllocation *used_children_allocation;
+  gint child_width;
+  gdouble max_scroll;
 
-  child_allocation.x = allocation->x;
-  child_allocation.y = allocation->y;
-  child_allocation.width = allocation->width;
-  child_allocation.height = allocation->height;
-  gtk_widget_size_allocate (priv->scrolled_window, &child_allocation);
+  used_children_allocation = get_children_allocation (self, TRUE);
+  child_width = gtk_widget_get_allocated_width (priv->box);
+  g_print ("get max scroll %d %d\n", used_children_allocation->width, child_width);
+  if (priv->invert_animation)
+    {
+      if (priv->inverted)
+        {
+          max_scroll = MAX (0, child_width - used_children_allocation->width);
+        }
+      else
+        {
+          max_scroll = child_width - used_children_allocation->width;
+        }
+    }
+  else
+    {
+      max_scroll = MAX (0, child_width - used_children_allocation->width);
+    }
 
-  _gtk_widget_set_simple_clip (widget, NULL);
+  return max_scroll;
 }
 
 static void
-update_hadjustment (GtkHidingBox  *self)
+update_scrolling (GtkHidingBox *self)
 {
   GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
-  gdouble adjustment_value;
-  gdouble max_real_adjustment;
-
-  max_real_adjustment = gtk_adjustment_get_upper (priv->hadjustment) -
-                        gtk_widget_get_allocated_width (priv->scrolled_window);
+  GtkAllocation allocation;
+  GtkAllocation child_allocation;
+  gint scroll_value;
+  gint max_scroll;
 
-  g_print ("aligment changed %f %f %d %f\n", max_real_adjustment, gtk_adjustment_get_upper 
(priv->hadjustment), gtk_widget_get_allocated_width (priv->scrolled_window), gtk_adjustment_get_lower 
(priv->hadjustment));
-  if (priv->invert_animation)
+  gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
+  gtk_widget_get_allocation (priv->box, &child_allocation);
+  max_scroll = get_max_scroll (self);
+  if (gtk_widget_get_realized (GTK_WIDGET (self)))
     {
-      if (priv->inverted)
+      if (priv->invert_animation)
         {
-          adjustment_value = (priv->invert_animation_progress) *
-                             (max_real_adjustment -
-                              gtk_adjustment_get_lower (priv->hadjustment));
+          if (priv->inverted)
+            {
+              scroll_value = priv->invert_animation_progress * max_scroll;
+            }
+          else
+            {
+              scroll_value = (1 - priv->invert_animation_progress) * max_scroll;
+            }
         }
       else
         {
-          adjustment_value = ABS (1 - priv->invert_animation_progress) *
-                              (max_real_adjustment -
-                               gtk_adjustment_get_lower (priv->hadjustment));
+          if (priv->inverted)
+            {
+              scroll_value = 0;
+            }
+          else
+            {
+              scroll_value = 0;
+            }
         }
 
-      g_print ("adjustment value %f %f %f\n", adjustment_value, gtk_adjustment_get_upper 
(priv->hadjustment), priv->invert_animation_progress);
-      gtk_adjustment_set_value (priv->hadjustment, adjustment_value);
+      gdk_window_move_resize (priv->bin_window,
+                              -scroll_value, 0,
+                              child_allocation.width, child_allocation.height);
+
+        g_print ("update scrolling %d %d\n", max_scroll, scroll_value);
     }
-  else
+
+  gtk_widget_queue_resize (self);
+}
+
+static void
+gtk_hiding_box_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+  GtkHidingBox *self = GTK_HIDING_BOX (widget);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+  GtkAllocation child_allocation;
+  GtkRequestedSize *sizes;
+  GtkRequisition minimum_size;
+  GtkRequisition natural_size;
+
+  gtk_widget_set_allocation (widget, allocation);
+
+  sizes = g_newa (GtkRequestedSize, g_list_length (priv->children));
+
+  update_children_visibility (self, allocation);
+  idle_update_revealers (self);
+
+  gtk_widget_get_preferred_size (priv->box, &minimum_size, &natural_size);
+  child_allocation.x = 0;
+  child_allocation.y = 0;
+  child_allocation.width = natural_size.width;
+  child_allocation.height = natural_size.height;
+  gtk_widget_size_allocate (priv->box, &child_allocation);
+
+  update_scrolling (self);
+
+  if (gtk_widget_get_realized (widget))
     {
-      if (priv->inverted)
-        gtk_adjustment_set_value (priv->hadjustment, max_real_adjustment);
-      else
-        gtk_adjustment_set_value (priv->hadjustment, gtk_adjustment_get_lower (priv->hadjustment));
-    }
+      gdk_window_move_resize (priv->view_window,
+                              allocation->x, allocation->y,
+                              allocation->width, allocation->height);
+        g_print ("view window %d %d", allocation->width, allocation->height);
+      gdk_window_show (priv->view_window);
 
-  gtk_widget_queue_resize (GTK_WIDGET (self));
+      g_print ("visibles? %d %d\n", gdk_window_is_visible (priv->bin_window), gdk_window_is_visible 
(priv->view_window));
+    }
 }
 
 static void
 finish_invert_animation (GtkHidingBox *self)
 {
   GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+  GtkAllocation allocation;
+  GList *child;
 
   g_print ("\n\n\n\n\n\n\n\n##################ss#######finish invert animation\n\n\n\n\n\n\n");
+  gtk_widget_get_allocation (self, &allocation);
+  update_children_visibility (self, &allocation);
   idle_update_revealers (self);
   priv->invert_animation = FALSE;
+  priv->invert_animation_progress = 0;
   priv->invert_animation_initial_time = 0;
-  gtk_widget_remove_tick_callback (priv->scrolled_window,
+  gtk_widget_remove_tick_callback (priv->box,
                                    priv->invert_animation_tick_id);
   priv->invert_animation_tick_id = 0;
+
+  gtk_widget_queue_resize (self);
+  for (child = priv->children; child != NULL; child = child->next)
+    {
+      GtkWidget *revealer;
+
+      revealer = gtk_widget_get_parent (GTK_WIDGET (child->data));
+      gtk_widget_queue_resize (revealer);
+    }
+  gtk_widget_queue_resize (priv->box);
 }
 
 
@@ -556,18 +619,26 @@ invert_animation_on_tick (GtkWidget     *widget,
   GtkHidingBox *self = GTK_HIDING_BOX (user_data);
   GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
   guint64 elapsed;
-  gdouble max_real_adjustment;
-
-  max_real_adjustment = gtk_adjustment_get_upper (priv->hadjustment) -
-                        (gdouble) gtk_widget_get_allocated_width (priv->scrolled_window);
+  gint max_scroll;
+  GtkAllocation *used_children_allocation;
+  GtkAllocation child_allocation;
+  GtkAllocation allocation;
 
   if (priv->invert_animation_initial_time == 0)
     priv->invert_animation_initial_time = gdk_frame_clock_get_frame_time (frame_clock);
 
+  gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
+  gtk_widget_get_allocation (priv->box, &child_allocation);
+  used_children_allocation = get_children_allocation (self, TRUE);
+  max_scroll = get_max_scroll (self);
+  if (!max_scroll)
+    return TRUE;
+
   elapsed = gdk_frame_clock_get_frame_time (frame_clock) - priv->invert_animation_initial_time;
-  priv->invert_animation_progress = elapsed * INVERT_ANIMATION_SPEED / (1000. * max_real_adjustment);
-  g_print ("################animation progres %d %f %f %f\n", gtk_widget_get_allocated_width 
(priv->scrolled_window), max_real_adjustment, elapsed / 1000., priv->invert_animation_progress);
-  update_hadjustment (self);
+  priv->invert_animation_progress = MIN (1, elapsed * INVERT_ANIMATION_SPEED / (1000. * max_scroll));
+  g_print ("################animation progres %d %d %d %f %f\n", gtk_widget_get_allocated_width (GTK_WIDGET 
(self)), used_children_allocation->width, max_scroll, elapsed / 1000., priv->invert_animation_progress);
+  update_scrolling (self);
+  gtk_widget_queue_draw (GTK_WIDGET (self));
 
   if (priv->invert_animation_progress >= 1)
     {
@@ -587,7 +658,9 @@ start_invert_animation (GtkHidingBox *self)
 
   priv->invert_animation = TRUE;
   priv->invert_animation_progress = 0;
+  priv->invert_animation_initial_children_width = gtk_widget_get_allocated_width (GTK_WIDGET (self));
 
+  g_print ("start animation!!!\n");
   for (child = priv->children; child != NULL; child = child->next)
     {
       GtkWidget *revealer;
@@ -597,24 +670,16 @@ start_invert_animation (GtkHidingBox *self)
       remove_all_opacity_classes (revealer);
       add_opacity_class (revealer, "pathbar-invert-animation-opacity-on");
 
-      gtk_revealer_set_transition_duration (GTK_REVEALER (revealer),
-                                            0);
+      gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), 0);
       gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE);
     }
 
-  priv->invert_animation_tick_id = gtk_widget_add_tick_callback (priv->scrolled_window,
+  priv->invert_animation_tick_id = gtk_widget_add_tick_callback (priv->box,
                                                                  (GtkTickCallback) invert_animation_on_tick,
                                                                  self, NULL);
 }
 
 static void
-hadjustment_on_changed (GtkAdjustment *hadjustment,
-                        gpointer       user_data)
-{
-  update_hadjustment (GTK_HIDING_BOX (user_data));
-}
-
-static void
 gtk_hiding_box_get_preferred_width (GtkWidget *widget,
                                     gint      *minimum_width,
                                     gint      *natural_width)
@@ -653,14 +718,19 @@ gtk_hiding_box_get_preferred_width (GtkWidget *widget,
       *natural_width += child_natural_width;
     }
 
-  /* Natural must also include the spacing */
-  if (priv->spacing && n_visible_children > 1)
-    *natural_width += priv->spacing * (n_visible_children - 1);
-
   g_list_free (children);
 }
 
 static void
+gtk_hiding_box_get_preferred_width_for_height (GtkWidget *widget,
+                                                  gint       height,
+                                                  gint      *minimum_width_out,
+                                                  gint      *natural_width_out)
+{
+  gtk_hiding_box_get_preferred_width (widget, minimum_width_out, natural_width_out);
+}
+
+static void
 gtk_hiding_box_get_preferred_height (GtkWidget *widget,
                                      gint      *minimum_height,
                                      gint      *natural_height)
@@ -698,31 +768,125 @@ on_what (gpointer  data,
 }
 
 static void
-gtk_hiding_box_init (GtkHidingBox *box)
+gtk_hiding_box_container_add (GtkContainer *container,
+                              GtkWidget    *child)
 {
-  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box);
-  GtkWidget *hscrollbar;
-
-  gtk_widget_set_has_window (GTK_WIDGET (box), FALSE);
-  priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-  priv->hadjustment = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->scrolled_window));
-  g_signal_connect (priv->hadjustment, "changed", (GCallback) hadjustment_on_changed, box);
-  hscrollbar = gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW (priv->scrolled_window));
-  gtk_widget_hide (hscrollbar);
+  g_return_if_fail (child != NULL);
+
+  g_error ("Path bar cannot add children. Use the path bar API instead");
+
+  return;
+}
+
+static void
+gtk_hiding_box_container_remove (GtkContainer *container,
+                                 GtkWidget    *child)
+{
+  g_return_if_fail (child != NULL);
+
+  g_error ("Path bar cannot remove children. Use the path bar API instead");
+
+  return;
+}
+
+static void
+gtk_hiding_box_unrealize (GtkWidget *widget)
+{
+  GtkHidingBox *self = GTK_HIDING_BOX (widget);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+
+  gtk_widget_unregister_window (widget, priv->bin_window);
+  gdk_window_destroy (priv->bin_window);
+  priv->view_window = NULL;
+
+  GTK_WIDGET_CLASS (gtk_hiding_box_parent_class)->unrealize (widget);
+}
+
+static void
+gtk_hiding_box_realize (GtkWidget *widget)
+{
+  GtkHidingBox *self = GTK_HIDING_BOX (widget);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+  GtkAllocation allocation;
+  GtkAllocation *children_allocation;
+  GdkWindowAttr attributes = { 0 };
+  GdkWindowAttributesType attributes_mask;
+
+  g_print ("realize\n");
+  gtk_widget_set_realized (widget, TRUE);
+
+  gtk_widget_get_allocation (widget, &allocation);
+
+  attributes.x = allocation.x;
+  attributes.y = allocation.y;
+  attributes.width = allocation.width;
+  attributes.height = allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes_mask = (GDK_WA_X | GDK_WA_Y) | GDK_WA_VISUAL;
+
+  priv->view_window = gdk_window_new (gtk_widget_get_parent_window (GTK_WIDGET (self)),
+                                      &attributes, attributes_mask);
+  gtk_widget_set_window (widget, priv->view_window);
+  gtk_widget_register_window (widget, priv->view_window);
+
+  children_allocation = get_children_allocation (self, priv->inverted);
+  attributes.x = 0;
+  attributes.y = 0;
+  attributes.width = children_allocation->width;
+  attributes.height = children_allocation->height;
+
+  priv->bin_window = gdk_window_new (priv->view_window, &attributes,
+                                     attributes_mask);
+  gtk_widget_register_window (widget, priv->bin_window);
+
+  gtk_widget_set_parent_window (priv->box, priv->bin_window);
+
+  gdk_window_show (priv->bin_window);
+  gdk_window_show (priv->view_window);
+  gtk_widget_show_all (priv->box);
+}
+
+static gboolean
+gtk_hiding_box_draw (GtkWidget *widget,
+                     cairo_t   *cr)
+{
+  GtkHidingBox *self = GTK_HIDING_BOX (widget);
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+
+  if (gtk_cairo_should_draw_window (cr, priv->bin_window))
+    {
+      GTK_WIDGET_CLASS (gtk_hiding_box_parent_class)->draw (widget, cr);
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static void
+gtk_hiding_box_init (GtkHidingBox *self)
+{
+  GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (self);
+
+  gtk_widget_set_has_window (GTK_WIDGET (self), TRUE);
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (self), TRUE);
+
   priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_widget_set_parent_window (priv->box, priv->bin_window);
+  GTK_CONTAINER_CLASS (gtk_hiding_box_parent_class)->add (GTK_CONTAINER (self), priv->box);
+
+  gtk_widget_show (priv->box);
   g_object_weak_ref (G_OBJECT (priv->box), on_what, NULL);
-  gtk_container_add (GTK_CONTAINER (priv->scrolled_window), priv->box);
-  gtk_widget_set_parent (priv->scrolled_window, GTK_WIDGET (box));
 
   priv->invert_animation = FALSE;
-  priv->spacing = 0;
   priv->inverted = FALSE;
   priv->invert_animation_tick_id = 0;
   priv->widgets_to_hide = NULL;
   priv->widgets_to_show = NULL;
   priv->widgets_to_remove = NULL;
 
-  gtk_widget_show_all (priv->scrolled_window);
+  g_print ("init\n");
 }
 
 static void
@@ -738,18 +902,14 @@ gtk_hiding_box_class_init (GtkHidingBoxClass *class)
   widget_class->size_allocate = gtk_hiding_box_size_allocate;
   widget_class->get_preferred_width = gtk_hiding_box_get_preferred_width;
   widget_class->get_preferred_height = gtk_hiding_box_get_preferred_height;
+  widget_class->get_preferred_width_for_height = gtk_hiding_box_get_preferred_width_for_height;
   widget_class->get_request_mode = gtk_hiding_box_get_request_mode;
+  widget_class->realize = gtk_hiding_box_realize;
+  widget_class->unrealize = gtk_hiding_box_unrealize;
+  widget_class->draw = gtk_hiding_box_draw;
 
-  container_class->add = gtk_hiding_box_add;
-  container_class->remove = gtk_hiding_box_remove;
-  container_class->forall = gtk_hiding_box_forall;
-
-  hiding_box_properties[PROP_SPACING] =
-           g_param_spec_int ("spacing",
-                             _("Spacing"),
-                             _("The amount of space between children"),
-                             0, G_MAXINT, 0,
-                             G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+  container_class->add = gtk_hiding_box_container_add;
+  container_class->remove = gtk_hiding_box_container_remove;
 
   hiding_box_properties[PROP_INVERTED] =
            g_param_spec_int ("inverted",
@@ -759,6 +919,7 @@ gtk_hiding_box_class_init (GtkHidingBoxClass *class)
                              G_PARAM_READWRITE);
 
   g_object_class_install_properties (object_class, LAST_PROP, hiding_box_properties);
+  g_print ("class init\n");
 }
 
 /**
@@ -774,55 +935,6 @@ gtk_hiding_box_new (void)
   return g_object_new (GTK_TYPE_HIDING_BOX, NULL);
 }
 
-/**
- * gtk_hiding_box_set_spacing:
- * @box: a #GtkHidingBox
- * @spacing: the number of pixels to put between children
- *
- * Sets the #GtkHidingBox:spacing property of @box, which is the
- * number of pixels to place between children of @box.
- */
-void
-gtk_hiding_box_set_spacing (GtkHidingBox *box,
-                            gint          spacing)
-{
-  GtkHidingBoxPrivate *priv ;
-
-  g_return_if_fail (GTK_IS_HIDING_BOX (box));
-
-  priv = gtk_hiding_box_get_instance_private (box);
-
-  if (priv->spacing != spacing)
-    {
-      priv->spacing = spacing;
-
-      g_object_notify (G_OBJECT (box), "spacing");
-
-      gtk_widget_queue_resize (GTK_WIDGET (box));
-    }
-}
-
-/**
- * gtk_hiding_box_get_spacing:
- * @box: a #GtkHidingBox
- *
- * Gets the value set by gtk_hiding_box_set_spacing().
- *
- * Returns: spacing between children
- **/
-gint
-gtk_hiding_box_get_spacing (GtkHidingBox *box)
-{
-  GtkHidingBoxPrivate *priv ;
-
-  g_return_val_if_fail (GTK_IS_HIDING_BOX (box), 0);
-
-  priv = gtk_hiding_box_get_instance_private (box);
-
-  return priv->spacing;
-}
-
-
 void
 gtk_hiding_box_set_inverted (GtkHidingBox *box,
                              gboolean      inverted)
diff --git a/gtk/gtkhidingbox.h b/gtk/gtkhidingbox.h
index e125495..e7b0e6f 100644
--- a/gtk/gtkhidingbox.h
+++ b/gtk/gtkhidingbox.h
@@ -25,7 +25,7 @@
 #error "Only <gtk/gtk.h> can be included directly."
 #endif
 
-#include <gtk/gtkcontainer.h>
+#include <gtk/gtkbin.h>
 
 G_BEGIN_DECLS
 
@@ -42,7 +42,7 @@ typedef struct _GtkHidingBoxPrivate GtkHidingBoxPrivate;
 
 struct _GtkHidingBoxClass
 {
-  GtkContainerClass parent;
+  GtkBinClass parent;
 
   /* Padding for future expansion */
   gpointer reserved[10];
@@ -50,7 +50,7 @@ struct _GtkHidingBoxClass
 
 struct _GtkHidingBox
 {
-  GtkContainer parent_instance;
+  GtkBin parent_instance;
 };
 
 GDK_AVAILABLE_IN_3_20
@@ -72,6 +72,13 @@ gboolean          gtk_hiding_box_get_inverted            (GtkHidingBox      *box
 
 GDK_AVAILABLE_IN_3_20
 GList             *gtk_hiding_box_get_overflow_children  (GtkHidingBox      *box);
+
+GDK_AVAILABLE_IN_3_20
+void               gtk_hiding_box_add                    (GtkHidingBox      *self,
+                                                          GtkWidget         *widget);
+GDK_AVAILABLE_IN_3_20
+void               gtk_hiding_box_remove                 (GtkHidingBox      *self,
+                                                          GtkWidget         *widget);
 G_END_DECLS
 
 #endif /* GTK_HIDING_BOX_H_ */
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 95beb5d..3b55c63 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -6107,7 +6107,8 @@ gtk_window_show (GtkWidget *widget)
 
   _gtk_widget_set_visible_flag (widget, TRUE);
 
-  gtk_css_node_validate (gtk_widget_get_css_node (widget));
+  if (gtk_widget_get_css_node (widget))
+    gtk_css_node_validate (gtk_widget_get_css_node (widget));
 
   gtk_widget_realize (widget);
 
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 5c67929..f074a1b 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -1607,22 +1607,22 @@ path-bar button.flat, .path-bar-overflow-popover button.flat {
 
 .pathbar-opacity-on {
     opacity: 1;
-    transition-duration: 250ms;
+    transition-duration: 1000ms;
 }
 
 .pathbar-opacity-off {
     opacity: 0;
-    transition-duration: 250ms;
+    transition-duration: 1000ms;
 }
 
 .pathbar-invert-animation-opacity-on {
     opacity: 1;
-    transition-duration: 60ms;
+    transition-duration: 100ms;
 }
 
 .pathbar-invert-animation-opacity-off {
     opacity: 0;
-    transition-duration: 60ms;
+    transition-duration: 100ms;
 }
 
 /**************
diff --git a/gtk/theme/Adwaita/gtk-contained-dark.css b/gtk/theme/Adwaita/gtk-contained-dark.css
index 2abfac1..5aacc21 100644
--- a/gtk/theme/Adwaita/gtk-contained-dark.css
+++ b/gtk/theme/Adwaita/gtk-contained-dark.css
@@ -2105,11 +2105,19 @@ path-bar button.flat, .path-bar-overflow-popover button.flat {
 
 .pathbar-opacity-on {
   opacity: 1;
-  transition-duration: 250ms; }
+  transition-duration: 1000ms; }
 
 .pathbar-opacity-off {
   opacity: 0;
-  transition-duration: 250ms; }
+  transition-duration: 1000ms; }
+
+.pathbar-invert-animation-opacity-on {
+  opacity: 1;
+  transition-duration: 100ms; }
+
+.pathbar-invert-animation-opacity-off {
+  opacity: 0;
+  transition-duration: 100ms; }
 
 /**************
  * Tree Views *
diff --git a/gtk/theme/Adwaita/gtk-contained.css b/gtk/theme/Adwaita/gtk-contained.css
index 68ceff3..ba92932 100644
--- a/gtk/theme/Adwaita/gtk-contained.css
+++ b/gtk/theme/Adwaita/gtk-contained.css
@@ -2114,11 +2114,19 @@ path-bar button.flat, .path-bar-overflow-popover button.flat {
 
 .pathbar-opacity-on {
   opacity: 1;
-  transition-duration: 250ms; }
+  transition-duration: 1000ms; }
 
 .pathbar-opacity-off {
   opacity: 0;
-  transition-duration: 250ms; }
+  transition-duration: 1000ms; }
+
+.pathbar-invert-animation-opacity-on {
+  opacity: 1;
+  transition-duration: 100ms; }
+
+.pathbar-invert-animation-opacity-off {
+  opacity: 0;
+  transition-duration: 100ms; }
 
 /**************
  * Tree Views *
diff --git a/tests/testhidingbox.c b/tests/testhidingbox.c
index fda67ef..bc2446f 100644
--- a/tests/testhidingbox.c
+++ b/tests/testhidingbox.c
@@ -34,8 +34,11 @@ static void
 on_button_clicked (GtkWidget *button,
                    gpointer   user_data)
 {
+
+#if 0
   g_print ("button clicked\n");
   gtk_container_remove (GTK_CONTAINER (user_data), button);
+#endif
 }
 
 static void
@@ -43,16 +46,18 @@ on_reset_button_clicked (GtkButton *reset_button)
 {
   GtkWidget *button;
 
+#if 0
   gtk_container_foreach (GTK_CONTAINER (hiding_box), (GtkCallback) gtk_widget_destroy, NULL);
 
   for (int i = 0; i < N_BUTTONS; i++)
     {
       button = gtk_button_new_with_label (get_lorem_ipsum ());
       g_signal_connect (button, "clicked", (GCallback) on_button_clicked, hiding_box);
-      gtk_container_add (GTK_CONTAINER (hiding_box), button);
+      gtk_hiding_box_add (GTK_HIDING_BOX (hiding_box), button);
     }
 
   gtk_widget_show_all (hiding_box);
+#endif
 }
 
 static void
@@ -63,7 +68,7 @@ on_add_button (gint line)
   button = gtk_button_new_with_label (get_lorem_ipsum ());
   gtk_widget_show (button);
   g_signal_connect (button, "clicked", (GCallback) on_button_clicked, hiding_box);
-  gtk_container_add (GTK_CONTAINER (hiding_box), button);
+  gtk_hiding_box_add (GTK_HIDING_BOX (hiding_box), button);
 }
 
 static void
@@ -72,10 +77,12 @@ on_remove_button (gint line)
   GList *children;
   GList *last;
 
+#if 0
   children = gtk_container_get_children (hiding_box);
   last = g_list_last (children);
   if (last)
     gtk_container_remove (hiding_box, GTK_WIDGET (last->data));
+#endif
 }
 
 static void



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