[gtk+/wip/csoriano/pathbar-bin-view-window] f



commit 913d91423da97ed8614d27d1e14e0cf82487a791
Author: Carlos Soriano <csoriano gnome org>
Date:   Thu Jun 9 17:17:10 2016 +0200

    f

 gtk/Makefile.am                                   |    4 +-
 gtk/gtk.h                                         |    2 +-
 gtk/gtkhidingbox.c                                |  978 --------------------
 gtk/gtkhidingbox.h                                |   84 --
 gtk/gtkpathbar.c                                  |    9 +-
 gtk/gtkpathbarcontainer.c                         | 1010 ++++++++++++++++++---
 gtk/gtkpathbarcontainer.h                         |   84 ++
 gtk/gtkpathbarcontainerprivate.h                  |   66 --
 tests/Makefile.am                                 |    8 +-
 tests/{testhidingbox.c => testpathbarcontainer.c} |   32 +-
 10 files changed, 974 insertions(+), 1303 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index e230d1c..ed18068 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -489,7 +489,6 @@ gtk_private_h_sources =             \
        gtkgestureswipeprivate.h        \
        gtkgesturezoomprivate.h \
        gtkheaderbarprivate.h   \
-       gtkhidingbox.h  \
        gtkhslaprivate.h        \
        gtkiconcache.h          \
        gtkiconhelperprivate.h  \
@@ -521,6 +520,7 @@ gtk_private_h_sources =             \
        gtkmountoperationprivate.h \
        gtknativedialogprivate.h \
        gtkorientableprivate.h  \
+       gtkpathbarcontainer.h   \
        gtkpathbarcontainerprivate.h \
        gtkpango.h              \
        gtkplacessidebarprivate.h       \
@@ -783,7 +783,6 @@ gtk_base_c_sources =                \
        gtkglarea.c             \
        gtkgrid.c               \
        gtkheaderbar.c          \
-       gtkhidingbox.c          \
        gtkhsla.c               \
        gtkicon.c               \
        gtkiconcache.c          \
@@ -838,6 +837,7 @@ gtk_base_c_sources =                \
        gtkpango.c              \
        gtkpapersize.c          \
        gtkpathbar.c            \
+       gtkpathbarcontainer.c   \
        gtkplacessidebar.c      \
        gtkplacesview.c         \
        gtkplacesviewrow.c      \
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 3fb9c67..915b12a 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -121,7 +121,7 @@
 #include <gtk/gtkglarea.h>
 #include <gtk/gtkgrid.h>
 #include <gtk/gtkheaderbar.h>
-#include <gtk/gtkhidingbox.h>
+#include <gtk/gtkpathbarcontainer.h>
 #include <gtk/gtkicontheme.h>
 #include <gtk/gtkiconview.h>
 #include <gtk/gtkimage.h>
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index a983f10..d7f785e 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -32,12 +32,11 @@
 #include "gtkpopover.h"
 #include "gtkbuilder.h"
 #include "gtkstylecontext.h"
-#include "gtkpathbarcontainerprivate.h"
 
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
 #include "gtktypebuiltins.h"
-#include "gtkhidingbox.h"
+#include "gtkpathbarcontainer.h"
 
 /**
  * SECTION:gtkpathbar
@@ -542,7 +541,7 @@ populate_overflow_popover (GtkPathBar *self)
   gtk_container_foreach (GTK_CONTAINER (overflow_container),
                          (GtkCallback) gtk_widget_destroy, NULL);
 
-  overflow_children = gtk_hiding_box_get_overflow_children (GTK_HIDING_BOX (path_box));
+  overflow_children = gtk_pathbar_container_get_overflow_children (GTK_PATHBAR_CONTAINER (path_box));
   for (l = overflow_children; l != NULL; l = l->next)
     {
       data = g_object_get_data (l->data, "data");
@@ -915,8 +914,8 @@ gtk_path_bar_set_inverted (GtkPathBar *self,
   if (priv->inverted != inverted)
     {
       priv->inverted = inverted != FALSE;
-      gtk_hiding_box_set_inverted (GTK_HIDING_BOX (priv->path_box_1), inverted);
-      gtk_hiding_box_set_inverted (GTK_HIDING_BOX (priv->path_box_2), inverted);
+      gtk_pathbar_container_set_inverted (GTK_PATHBAR_CONTAINER (priv->path_box_1), inverted);
+      gtk_pathbar_container_set_inverted (GTK_PATHBAR_CONTAINER (priv->path_box_2), inverted);
 
       g_object_notify (G_OBJECT (self), "inverted");
     }
diff --git a/gtk/gtkpathbarcontainer.c b/gtk/gtkpathbarcontainer.c
index f68d9dc..076f3c8 100644
--- a/gtk/gtkpathbarcontainer.c
+++ b/gtk/gtkpathbarcontainer.c
@@ -1,10 +1,11 @@
-/* gtkpathbarcontainer.c
+/*
+ * Copyright (C) 2016 Carlos Soriano <csoriano gnome org>
  *
- * Copyright (C) 2015 Red Hat
+ * Licensed under the GNU General Public License Version 2
  *
- * This program is free software: you can redistribute it and/or modify
+ * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -13,206 +14,844 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Carlos Soriano <csoriano gnome org>
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include "config.h"
 
-#include "gtkpathbarcontainerprivate.h"
-#include "gtkbuildable.h"
-#include "gtkwidget.h"
-#include "gtkmenubutton.h"
-#include "gtksizerequest.h"
-#include "gtkhidingbox.h"
+#include "gtkpathbarcontainer.h"
 #include "gtkwidgetprivate.h"
-#include "glib-object.h"
+#include "gtkintl.h"
+#include "gtksizerequest.h"
+#include "gtkbuildable.h"
+#include "gtkrevealer.h"
+#include "gtkscrolledwindow.h"
+#include "gtkbox.h"
+
+//TODO remove
+#include "gtkbutton.h"
+
+#include "glib.h"
+
+#define REVEALER_ANIMATION_TIME 250 //ms
+#define INVERT_ANIMATION_SPEED 1.2 //px/ms
+#define INVERT_ANIMATION_MAX_TIME 750 //px/ms
 
 struct _GtkPathBarContainerPrivate
 {
-  GtkWidget *overflow_button;
-  GtkWidget *path_box;
+  GList *children;
+  gint inverted :1;
+  GList *widgets_to_hide;
+  GList *widgets_to_show;
+  GList *widgets_to_remove;
+  gint current_width;
+  gint current_height;
+  guint needs_update :1;
+
+  gboolean invert_animation;
+
+  GdkWindow *bin_window;
+  GdkWindow *view_window;
+
+  GtkWidget *box;
+
+  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;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkPathBarContainer, gtk_path_bar_container, GTK_TYPE_BIN)
+
+enum {
+  PROP_0,
+  PROP_INVERTED,
+  LAST_PROP
 };
 
-static GtkBuildableIface *parent_buildable_iface;
+static GParamSpec *path_bar_container_properties[LAST_PROP] = { NULL, };
 
-static GObject *
-buildable_get_internal_child (GtkBuildable *buildable,
-                              GtkBuilder   *builder,
-                              const gchar  *childname)
+static void
+gtk_path_bar_container_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
 {
-  if (g_strcmp0 (childname, "overflow_button") == 0)
-    return G_OBJECT (gtk_path_bar_container_get_overflow_button (GTK_PATH_BAR_CONTAINER (buildable)));
-  if (g_strcmp0 (childname, "path_box") == 0)
-    return G_OBJECT (gtk_path_bar_container_get_path_box (GTK_PATH_BAR_CONTAINER (buildable)));
+  GtkPathBarContainer *box = GTK_PATH_BAR_CONTAINER (object);
 
-  return parent_buildable_iface->get_internal_child (buildable, builder, childname);
+  switch (prop_id)
+    {
+    case PROP_INVERTED:
+      gtk_path_bar_container_set_inverted (box, g_value_get_boolean (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 static void
-buildable_init (GtkBuildableIface *iface)
+gtk_path_bar_container_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
 {
-  parent_buildable_iface = g_type_interface_peek_parent (iface);
-  iface->get_internal_child = buildable_get_internal_child;
+  GtkPathBarContainer *box = GTK_PATH_BAR_CONTAINER (object);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (box);
+
+  switch (prop_id)
+    {
+    case PROP_INVERTED:
+      g_value_set_boolean (value, priv->inverted);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+void
+gtk_path_bar_container_add (GtkPathBarContainer *self,
+                           GtkWidget           *widget)
+{
+  GtkPathBarContainer *box = GTK_PATH_BAR_CONTAINER (self);
+  GtkWidget *revealer;
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_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_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_all (revealer);
+
+  g_print ("add\n");
 }
 
-G_DEFINE_TYPE_WITH_CODE (GtkPathBarContainer, gtk_path_bar_container, GTK_TYPE_CONTAINER,
-                         G_ADD_PRIVATE (GtkPathBarContainer)
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_init))
 static void
-container_forall (GtkContainer *container,
-                  gboolean      include_internals,
-                  GtkCallback   callback,
-                  gpointer      callback_data)
+really_remove_child (GtkPathBarContainer *self,
+                     GtkWidget           *widget)
 {
-  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (GTK_PATH_BAR_CONTAINER 
(container));
+  GList *child;
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
 
-  if (include_internals)
+  g_print ("really remove child %p %s\n", widget, gtk_button_get_label (GTK_BUTTON (widget)));
+  for (child = priv->widgets_to_remove; child != NULL; child = child->next)
     {
-      (* callback) (priv->overflow_button, callback_data);
-      (* callback) (priv->path_box, callback_data);
+      GtkWidget *revealer;
+
+      revealer = gtk_widget_get_parent (child->data);
+      g_print ("aver %p\n", child->data);
+      if (child->data == widget && !gtk_revealer_get_child_revealed (GTK_REVEALER (revealer)))
+        {
+          g_print ("############################## INSIDE\n");
+          gboolean was_visible = gtk_widget_get_visible (widget);
+
+          priv->widgets_to_remove = g_list_remove (priv->widgets_to_remove,
+                                                   child->data);
+          gtk_container_remove (GTK_CONTAINER (priv->box), revealer);
+
+          if (was_visible)
+            gtk_widget_queue_resize (GTK_WIDGET (self));
+
+          break;
+        }
     }
 }
 
-static GtkSizeRequestMode
-get_request_mode (GtkWidget *self)
+static void
+unrevealed_really_remove_child (GObject    *widget,
+                                GParamSpec *pspec,
+                                gpointer    user_data)
 {
-  return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+  GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (user_data);
+
+  g_print ("unrevelaed really remove child %p %s\n", widget, G_OBJECT_TYPE_NAME (widget));
+  g_signal_handlers_disconnect_by_func (widget, unrevealed_really_remove_child, self);
+  really_remove_child (self, gtk_bin_get_child (GTK_BIN (widget)));
+}
+
+void
+gtk_path_bar_container_remove (GtkPathBarContainer *self,
+                       GtkWidget    *widget)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
+  GtkWidget *to_remove;
+
+  g_print ("remove %p %s\n", widget, G_OBJECT_TYPE_NAME (widget));
+  if (GTK_IS_REVEALER (widget) && gtk_widget_get_parent (widget) == priv->box)
+    to_remove = gtk_bin_get_child (GTK_BIN (widget));
+  else
+    to_remove = widget;
+
+  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 (self));
+}
+
+static GtkAllocation*
+get_children_allocation (GtkPathBarContainer *self,
+                         gboolean             inverted)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_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;
+
+  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);
+
+  /* Retrieve desired size for visible children. */
+  for (i = 0, child = children; child != NULL; i++, child = child->next)
+    {
+      child_widget = GTK_WIDGET (child->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
-size_allocate (GtkWidget     *self,
-               GtkAllocation *allocation)
-{
-  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (GTK_PATH_BAR_CONTAINER 
(self));
-  gint path_min_width;
-  gint path_nat_width;
-  gint overflow_button_min_width;
-  GtkAllocation path_container_allocation;
-  GtkAllocation overflow_button_allocation;
-  GtkTextDirection direction;
-  gboolean overflow;
-  GList *overflow_children;
+update_children_visibility (GtkPathBarContainer *box,
+                            GtkAllocation       *allocation)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (box);
+  GtkWidget *child_widget;
+  GList *child;
+  GtkRequestedSize *sizes_temp;
+  gint i;
   GList *children;
+  gboolean allocate_more_children = TRUE;
+  gint current_children_width = 0;
+
+  g_list_free (priv->widgets_to_show);
+  priv->widgets_to_show = NULL;
+  g_list_free (priv->widgets_to_hide);
+  priv->widgets_to_hide = NULL;
+  children = g_list_copy (priv->children);
+  sizes_temp = g_newa (GtkRequestedSize, g_list_length (priv->children));
+  if (priv->inverted)
+    children = g_list_reverse (children);
+
+  /* Retrieve desired size for visible children. */
+  for (i = 0, child = children; child != NULL; i++, child = child->next)
+    {
+      child_widget = GTK_WIDGET (child->data);
+
+      gtk_widget_get_preferred_width_for_height (child_widget,
+                                                 allocation->height,
+                                                 &sizes_temp[i].minimum_size,
+                                                 &sizes_temp[i].natural_size);
+
+      current_children_width += sizes_temp[i].minimum_size;
+
+      if (!allocate_more_children || current_children_width > allocation->width)
+        {
+          if (allocate_more_children)
+            priv->allocated_children_width = current_children_width - sizes_temp[i].minimum_size;
+          allocate_more_children = FALSE;
+          priv->previous_child_width = sizes_temp[i].minimum_size;
+          if (gtk_revealer_get_child_revealed (GTK_REVEALER (gtk_widget_get_parent (child_widget))))
+            priv->widgets_to_hide = g_list_append (priv->widgets_to_hide, child_widget);
+
+          continue;
+        }
+
+      if (!g_list_find (priv->widgets_to_remove, child_widget))
+        priv->widgets_to_show = g_list_append (priv->widgets_to_show, child_widget);
+    }
+
+  priv->total_children_width = current_children_width;
+  g_list_free (children);
+}
+
+static void
+add_opacity_class (GtkWidget   *widget,
+                   const gchar *class_name)
+{
+  GtkStyleContext *style_context;
+
+  style_context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_add_class (style_context, class_name);
+}
+
+static void
+remove_opacity_classes (GtkWidget *widget)
+{
+  GtkStyleContext *style_context;
+
+  style_context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_remove_class (style_context, "pathbar-initial-opacity");
+  gtk_style_context_remove_class (style_context, "pathbar-opacity-on");
+  gtk_style_context_remove_class (style_context, "pathbar-opacity-off");
+  gtk_style_context_remove_class (style_context, "pathbar-invert-animation-opacity-off");
+  gtk_style_context_remove_class (style_context, "pathbar-invert-animation-opacity-on");
+}
+
+static void
+revealer_on_show_completed (GObject    *widget,
+                            GParamSpec *pspec,
+                            gpointer    user_data)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (GTK_PATH_BAR_CONTAINER 
(user_data));
 
-  gtk_widget_set_allocation (self, allocation);
+  g_print ("opacity on!!!!!\n");
+  remove_opacity_classes (GTK_WIDGET (widget));
+  g_signal_handlers_disconnect_by_func (widget, revealer_on_show_completed, user_data);
+  priv->widgets_to_show = g_list_remove (priv->widgets_to_show,
+                                         gtk_bin_get_child (GTK_BIN (widget)));
+}
 
-  children = gtk_container_get_children (GTK_CONTAINER (priv->path_box));
-  gtk_widget_set_child_visible (priv->overflow_button, FALSE);
+static void
+revealer_on_hide_completed (GObject    *widget,
+                            GParamSpec *pspec,
+                            gpointer    user_data)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (GTK_PATH_BAR_CONTAINER 
(user_data));
+
+  g_print ("opacity off!!!!!\n");
+  remove_opacity_classes (GTK_WIDGET (widget));
+  g_signal_handlers_disconnect_by_func (widget, revealer_on_hide_completed,
+                                        user_data);
+  priv->widgets_to_hide = g_list_remove (priv->widgets_to_hide,
+                                         gtk_bin_get_child (GTK_BIN (widget)));
+}
 
-  if (g_list_length (children) == 0)
+static void
+idle_update_revealers (GtkPathBarContainer *self)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
+  GList *l;
+
+  /* The invert animation is handled in a tick callback, do nothing here */
+  if (priv->invert_animation)
     return;
 
-  gtk_widget_get_preferred_width (priv->path_box, &path_min_width, &path_nat_width);
-
-  /* Try to allocate all children with our allocation so we can request if there
-   * is some overflow children */
-  path_container_allocation.x = allocation->x;
-  path_container_allocation.width = allocation->width;
-  path_container_allocation.y = allocation->y;
-  path_container_allocation.height = allocation->height;
-  gtk_widget_size_allocate (priv->path_box, &path_container_allocation);
-  gtk_widget_get_preferred_width (priv->overflow_button, &overflow_button_min_width, NULL);
-  overflow_children = gtk_hiding_box_get_overflow_children (GTK_HIDING_BOX (priv->path_box));
-  overflow = overflow_children != NULL;
-  g_list_free (overflow_children);
-
-  direction = gtk_widget_get_direction (self);
-
-  path_container_allocation.x = allocation->x;
-  path_container_allocation.width = allocation->width;
-  if (overflow)
+  for (l = priv->widgets_to_hide; l != NULL; l = l->next)
+    {
+      GtkWidget *revealer;
+
+      revealer = gtk_widget_get_parent (l->data);
+      if (gtk_revealer_get_child_revealed (GTK_REVEALER (revealer)) &&
+          gtk_revealer_get_reveal_child (GTK_REVEALER (revealer)))
+        {
+          g_signal_handlers_disconnect_by_func (revealer, revealer_on_hide_completed, self);
+          g_signal_connect (revealer, "notify::child-revealed", (GCallback) revealer_on_hide_completed, 
self);
+
+          remove_opacity_classes (revealer);
+          add_opacity_class (revealer, "pathbar-opacity-off");
+
+          gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE);
+        }
+    }
+
+  for (l = priv->widgets_to_remove; l != NULL; l = l->next)
     {
-      if (direction == GTK_TEXT_DIR_LTR)
+      GtkWidget *revealer;
+
+      revealer = gtk_widget_get_parent (l->data);
+      if (gtk_revealer_get_child_revealed (GTK_REVEALER (revealer)))
         {
-          path_container_allocation.x = allocation->x + overflow_button_min_width;
-          path_container_allocation.width = allocation->width - overflow_button_min_width;
-
-          overflow_button_allocation.y = allocation->y;
-          overflow_button_allocation.height = allocation->height;
-          overflow_button_allocation.width = overflow_button_min_width;
-          overflow_button_allocation.x = allocation->x;
-          gtk_widget_set_child_visible (priv->overflow_button, TRUE);
-          gtk_widget_size_allocate (priv->overflow_button, &overflow_button_allocation);
+          g_signal_handlers_disconnect_by_func (revealer, revealer_on_hide_completed, self);
+          g_signal_connect (revealer, "notify::child-revealed",
+                            (GCallback) unrevealed_really_remove_child, self);
+
+          remove_opacity_classes (revealer);
+          add_opacity_class (revealer, "pathbar-opacity-off");
+
+          gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE);
         }
       else
         {
-          path_container_allocation.width = allocation->width - overflow_button_min_width;
+          really_remove_child (self, l->data);
         }
     }
 
-  path_container_allocation.y = allocation->y;
-  path_container_allocation.height = allocation->height;
-  gtk_widget_size_allocate (priv->path_box, &path_container_allocation);
+  /* We want to defer to show revealers until the animation of those that needs
+   * to be hidden or removed are done
+   */
+  if (priv->widgets_to_remove || priv->widgets_to_hide)
+    return;
 
-  if (overflow && direction == GTK_TEXT_DIR_RTL)
+  for (l = priv->widgets_to_show; l != NULL; l = l->next)
     {
-      overflow_button_allocation.y = allocation->y;
-      overflow_button_allocation.height = allocation->height;
-      overflow_button_allocation.width = overflow_button_min_width;
-      overflow_button_allocation.x = path_container_allocation.x +
-                                     path_container_allocation.width;
-      gtk_widget_set_child_visible (priv->overflow_button, TRUE);
-      gtk_widget_size_allocate (priv->overflow_button, &overflow_button_allocation);
+      GtkWidget *revealer;
+
+      revealer = gtk_widget_get_parent (l->data);
+      if (!gtk_revealer_get_reveal_child (GTK_REVEALER (revealer)))
+        {
+          g_signal_handlers_disconnect_by_func (revealer, revealer_on_show_completed, self);
+          g_signal_connect (revealer, "notify::child-revealed", (GCallback) revealer_on_show_completed, 
self);
+
+          remove_opacity_classes (revealer);
+          add_opacity_class (revealer, "pathbar-opacity-on");
+
+          gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE);
+        }
     }
 
-  _gtk_widget_set_simple_clip (self, NULL);
+}
+
+static gint
+get_max_scroll (GtkPathBarContainer *self)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
+  GtkAllocation *used_children_allocation;
+  gint children_width;
+  gdouble max_scroll;
 
-  g_list_free (children);
+  used_children_allocation = get_children_allocation (self, TRUE);
+  children_width = gtk_widget_get_allocated_width (priv->box);
+
+  if (priv->invert_animation)
+    {
+      if (priv->inverted)
+        {
+          max_scroll = MAX (0, children_width - used_children_allocation->width);
+        }
+      else
+        {
+          max_scroll = children_width - used_children_allocation->width;
+        }
+    }
+  else
+    {
+      max_scroll = MAX (0, children_width - used_children_allocation->width);
+    }
+
+  return max_scroll;
 }
 
 static void
-get_preferred_width (GtkWidget *self,
-                     gint      *minimum_width,
-                     gint      *natural_width)
+update_scrolling (GtkPathBarContainer *self)
 {
-  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (GTK_PATH_BAR_CONTAINER 
(self));
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
+  GtkAllocation allocation;
+  GtkAllocation child_allocation;
+  gint scroll_value;
+  gint max_scroll;
+
+  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->invert_animation)
+        {
+          /* We only move the window to the left of the allocation, so negative values */
+          if (priv->inverted)
+            scroll_value = - priv->invert_animation_progress * max_scroll;
+          else
+            scroll_value = - (1 - priv->invert_animation_progress) * max_scroll;
+        }
+      else
+        {
+          scroll_value = 0;
+        }
+
+      gdk_window_move_resize (priv->bin_window,
+                              scroll_value, 0,
+                              child_allocation.width, child_allocation.height);
+    }
+}
+
+static void
+gtk_path_bar_container_size_allocate (GtkWidget     *widget,
+                                     GtkAllocation *allocation)
+{
+  GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (widget);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_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))
+    {
+      gdk_window_move_resize (priv->view_window,
+                              allocation->x, allocation->y,
+                              allocation->width, allocation->height);
+      gdk_window_show (priv->view_window);
+    }
+}
+
+static void
+finish_invert_animation (GtkPathBarContainer *self)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
+  GtkAllocation allocation;
+  GList *widgets_to_hide_copy;
+  GList *l;
+
+  /* Hide the revealers that need to be hidden now. */
+  update_children_visibility (self, &allocation);
+  widgets_to_hide_copy = g_list_copy (priv->widgets_to_hide);
+  for (l = widgets_to_hide_copy; l != NULL; l = l->next)
+    {
+      GtkWidget *revealer;
+      double animation_time;
+
+      revealer = gtk_widget_get_parent (l->data);
+      remove_opacity_classes (revealer);
+
+      add_opacity_class (revealer, "pathbar-invert-animation-opacity-off");
+      g_signal_handlers_disconnect_by_func (revealer, revealer_on_hide_completed, self);
+      g_signal_connect (revealer, "notify::child-revealed", (GCallback) revealer_on_hide_completed, self);
+
+      /* If the animation we just did was to the inverted state, we
+       * have the revealers that need to be hidden out of the view, so
+       * there's no point on animating them.
+       * Not only that, we want to update the scroll in a way that takes
+       * into account the state when the animation is finished, if not
+       * we are going to show the animation of the revealers next time
+       * the scroll is updated
+       */
+      animation_time =  priv->inverted ? 0 : REVEALER_ANIMATION_TIME;
+      gtk_revealer_set_transition_duration (GTK_REVEALER (revealer),
+                                            animation_time);
+      gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE);
+      gtk_revealer_set_transition_duration (GTK_REVEALER (revealer),
+                                            REVEALER_ANIMATION_TIME);
+    }
+
+  priv->invert_animation = FALSE;
+  priv->invert_animation_progress = 0;
+  priv->invert_animation_initial_time = 0;
+  gtk_widget_remove_tick_callback (priv->box,
+                                   priv->invert_animation_tick_id);
+  priv->invert_animation_tick_id = 0;
+}
+
+
+static gboolean
+invert_animation_on_tick (GtkWidget     *widget,
+                          GdkFrameClock *frame_clock,
+                          gpointer       user_data)
+{
+  GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (user_data);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
+  guint64 elapsed;
+  gint max_scroll;
+  double animation_speed;
+  GtkAllocation *used_children_allocation;
+  GtkAllocation child_allocation;
+  GtkAllocation allocation;
+
+  /* Initialize the frame clock the first time this is called */
+  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;
+
+  /* If there are several items the animation can take some time, so let's limit
+   * it to some extend
+   */
+  if (max_scroll / INVERT_ANIMATION_SPEED > INVERT_ANIMATION_MAX_TIME)
+    animation_speed = max_scroll / INVERT_ANIMATION_MAX_TIME;
+  else
+    animation_speed = INVERT_ANIMATION_SPEED;
+
+  elapsed = gdk_frame_clock_get_frame_time (frame_clock) - priv->invert_animation_initial_time;
+  priv->invert_animation_progress = MIN (1, elapsed * 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);
+
+  if (priv->invert_animation_progress >= 1)
+    {
+      finish_invert_animation (self);
+
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+start_invert_animation (GtkPathBarContainer *self)
+{
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
+  GList *child;
+
+  if (priv->invert_animation)
+    finish_invert_animation (self);
+
+  priv->invert_animation = TRUE;
+  priv->invert_animation_progress = 0;
+  priv->invert_animation_initial_children_width = gtk_widget_get_allocated_width (GTK_WIDGET (self));
+
+  for (child = priv->children; child != NULL; child = child->next)
+    {
+      GtkWidget *revealer;
+
+      revealer = gtk_widget_get_parent (GTK_WIDGET (child->data));
 
-  gtk_widget_get_preferred_width (priv->path_box, minimum_width, natural_width);
+      remove_opacity_classes (revealer);
+      if (gtk_revealer_get_child_revealed (GTK_REVEALER (gtk_widget_get_parent (child->data))))
+        {
+          add_opacity_class (revealer, "pathbar-initial-opacity");
+          add_opacity_class (revealer, "pathbar-invert-animation-opacity-on");
+        }
+
+      gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), 0);
+      gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE);
+      gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), REVEALER_ANIMATION_TIME);
+    }
+
+  priv->invert_animation_tick_id = gtk_widget_add_tick_callback (priv->box,
+                                                                 (GtkTickCallback) invert_animation_on_tick,
+                                                                 self, NULL);
 }
 
 static void
-get_preferred_height (GtkWidget *self,
-                      gint      *minimum_height,
-                      gint      *natural_height)
+gtk_path_bar_container_get_preferred_width (GtkWidget *widget,
+                                           gint      *minimum_width,
+                                           gint      *natural_width)
 {
-  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (GTK_PATH_BAR_CONTAINER 
(self));
+  GtkPathBarContainer *box = GTK_PATH_BAR_CONTAINER (widget);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (box);
+  gint child_minimum_width;
+  gint child_natural_width;
+  GList *child;
+  gint n_visible_children;
+  gboolean have_min = FALSE;
+  GList *children;
+
+  *minimum_width = 0;
+  *natural_width = 0;
+
+  children = g_list_copy (priv->children);
+  if (priv->inverted)
+    children = g_list_reverse (children);
+
+  n_visible_children = 0;
+  for (child = children; child != NULL; child = child->next)
+    {
+      if (!gtk_widget_is_visible (child->data))
+        continue;
+
+      ++n_visible_children;
+      gtk_widget_get_preferred_width (child->data, &child_minimum_width, &child_natural_width);
+      /* Minimum is a minimum of the first visible child */
+      if (!have_min)
+        {
+          *minimum_width = child_minimum_width;
+          have_min = TRUE;
+        }
+      /* Natural is a sum of all visible children */
+      *natural_width += child_natural_width;
+    }
 
-  gtk_widget_get_preferred_height (priv->path_box, minimum_height, natural_height);
+  g_list_free (children);
 }
 
 static void
-widget_destroy (GtkWidget *object)
+gtk_path_bar_container_get_preferred_width_for_height (GtkWidget *widget,
+                                                      gint       height,
+                                                      gint      *minimum_width_out,
+                                                      gint      *natural_width_out)
 {
-  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (GTK_PATH_BAR_CONTAINER 
(object));
+  gtk_path_bar_container_get_preferred_width (widget, minimum_width_out, natural_width_out);
+}
 
-  if (priv->overflow_button && priv->path_box)
+static void
+gtk_path_bar_container_get_preferred_height (GtkWidget *widget,
+                                            gint      *minimum_height,
+                                            gint      *natural_height)
+{
+  GtkPathBarContainer *box = GTK_PATH_BAR_CONTAINER (widget);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (box);
+  gint child_minimum_height;
+  gint child_natural_height;
+  GList *child;
+
+  *minimum_height = 0;
+  *natural_height = 0;
+  for (child = priv->children; child != NULL; child = child->next)
     {
-      gtk_widget_unparent (priv->overflow_button);
-      gtk_widget_unparent (priv->path_box);
+      if (!gtk_widget_is_visible (child->data))
+        continue;
 
-      priv->overflow_button = NULL;
-      priv->path_box = NULL;
+      gtk_widget_get_preferred_height (child->data, &child_minimum_height, &child_natural_height);
+      *minimum_height = MAX (*minimum_height, child_minimum_height);
+      *natural_height = MAX (*natural_height, child_natural_height);
     }
+}
+
+static GtkSizeRequestMode
+gtk_path_bar_container_get_request_mode (GtkWidget *self)
+{
+  return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
+static void
+gtk_path_bar_container_container_add (GtkContainer *container,
+                              GtkWidget    *child)
+{
+  g_return_if_fail (child != NULL);
+
+  g_error ("Path bar cannot add children. Use the path bar API instead");
+
+  return;
+}
+
+static void
+gtk_path_bar_container_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_path_bar_container_unrealize (GtkWidget *widget)
+{
+  GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (widget);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_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_path_bar_container_parent_class)->destroy (object);
+  GTK_WIDGET_CLASS (gtk_path_bar_container_parent_class)->unrealize (widget);
 }
 
 static void
-gtk_path_bar_container_class_init (GtkPathBarContainerClass *klass)
+gtk_path_bar_container_realize (GtkWidget *widget)
 {
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+  GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (widget);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_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);
+}
 
-  widget_class->get_request_mode = get_request_mode;
-  widget_class->get_preferred_width = get_preferred_width;
-  widget_class->get_preferred_height = get_preferred_height;
-  widget_class->size_allocate = size_allocate;
-  widget_class->destroy = widget_destroy;
+static gboolean
+gtk_path_bar_container_draw (GtkWidget *widget,
+                     cairo_t   *cr)
+{
+  GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (widget);
+  GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
 
-  // Neccesary to draw and realize children
-  container_class->forall = container_forall;
+  if (gtk_cairo_should_draw_window (cr, priv->bin_window))
+    {
+      GTK_WIDGET_CLASS (gtk_path_bar_container_parent_class)->draw (widget, cr);
+    }
+
+  return GDK_EVENT_PROPAGATE;
 }
 
 static void
@@ -220,41 +859,118 @@ gtk_path_bar_container_init (GtkPathBarContainer *self)
 {
   GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self);
 
-  gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
+  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_path_bar_container_parent_class)->add (GTK_CONTAINER (self), priv->box);
 
-  priv->overflow_button = gtk_menu_button_new ();
-  priv->path_box = gtk_hiding_box_new ();
+  gtk_widget_show (priv->box);
 
-  gtk_widget_set_parent (priv->overflow_button, GTK_WIDGET (self));
-  gtk_widget_set_parent (priv->path_box, GTK_WIDGET (self));
+  priv->invert_animation = FALSE;
+  priv->inverted = FALSE;
+  priv->invert_animation_tick_id = 0;
+  priv->widgets_to_hide = NULL;
+  priv->widgets_to_show = NULL;
+  priv->widgets_to_remove = NULL;
+
+  g_print ("init\n");
+}
+
+static void
+gtk_path_bar_container_class_init (GtkPathBarContainerClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
+
+  object_class->set_property = gtk_path_bar_container_set_property;
+  object_class->get_property = gtk_path_bar_container_get_property;
+
+  widget_class->size_allocate = gtk_path_bar_container_size_allocate;
+  widget_class->get_preferred_width = gtk_path_bar_container_get_preferred_width;
+  widget_class->get_preferred_height = gtk_path_bar_container_get_preferred_height;
+  widget_class->get_preferred_width_for_height = gtk_path_bar_container_get_preferred_width_for_height;
+  widget_class->get_request_mode = gtk_path_bar_container_get_request_mode;
+  widget_class->realize = gtk_path_bar_container_realize;
+  widget_class->unrealize = gtk_path_bar_container_unrealize;
+  widget_class->draw = gtk_path_bar_container_draw;
+
+  container_class->add = gtk_path_bar_container_container_add;
+  container_class->remove = gtk_path_bar_container_container_remove;
+
+  path_bar_container_properties[PROP_INVERTED] =
+           g_param_spec_int ("inverted",
+                             _("Direction of hiding children inverted"),
+                             P_("If false the container will start hiding widgets from the end when there is 
not enough space, and the oposite in case inverted is true."),
+                             0, G_MAXINT, 0,
+                             G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, LAST_PROP, path_bar_container_properties);
+  g_print ("class init\n");
 }
 
+/**
+ * gtk_path_bar_container_new:
+ *
+ * Creates a new #GtkPathBarContainer.
+ *
+ * Returns: a new #GtkPathBarContainer.
+ **/
 GtkWidget *
 gtk_path_bar_container_new (void)
 {
   return g_object_new (GTK_TYPE_PATH_BAR_CONTAINER, NULL);
 }
 
-GtkWidget *
-gtk_path_bar_container_get_overflow_button (GtkPathBarContainer *self)
+void
+gtk_path_bar_container_set_inverted (GtkPathBarContainer *box,
+                             gboolean      inverted)
 {
-  GtkPathBarContainerPrivate *priv;
+  GtkPathBarContainerPrivate *priv ;
+
+  g_return_if_fail (GTK_IS_PATH_BAR_CONTAINER (box));
 
-  g_return_val_if_fail (GTK_IS_PATH_BAR_CONTAINER (self), NULL);
+  priv = gtk_path_bar_container_get_instance_private (box);
 
-  priv = gtk_path_bar_container_get_instance_private (self);
+  if (priv->inverted != inverted)
+    {
+      priv->inverted = inverted != FALSE;
+
+      g_object_notify (G_OBJECT (box), "inverted");
 
-  return priv->overflow_button;
+      start_invert_animation (box);
+      gtk_widget_queue_resize (GTK_WIDGET (box));
+    }
 }
 
-GtkWidget *
-gtk_path_bar_container_get_path_box (GtkPathBarContainer *self)
+gboolean
+gtk_path_bar_container_get_inverted (GtkPathBarContainer *box)
 {
-  GtkPathBarContainerPrivate *priv;
+  GtkPathBarContainerPrivate *priv ;
+
+  g_return_val_if_fail (GTK_IS_PATH_BAR_CONTAINER (box), 0);
+
+  priv = gtk_path_bar_container_get_instance_private (box);
+
+  return priv->inverted;
+}
+
+GList *
+gtk_path_bar_container_get_overflow_children (GtkPathBarContainer *box)
+{
+  GtkPathBarContainerPrivate *priv ;
+  GList *result = NULL;
+  GList *l;
+
+  g_return_val_if_fail (GTK_IS_PATH_BAR_CONTAINER (box), 0);
 
-  g_return_val_if_fail (GTK_IS_PATH_BAR_CONTAINER (self), NULL);
+  priv = gtk_path_bar_container_get_instance_private (box);
 
-  priv = gtk_path_bar_container_get_instance_private (self);
+  for (l = priv->children; l != NULL; l = l->next)
+    if (gtk_widget_is_visible (l->data) && !gtk_widget_get_child_visible (l->data))
+      result = g_list_append (result, l->data);
 
-  return priv->path_box;
+  return result;
 }
diff --git a/gtk/gtkpathbarcontainer.h b/gtk/gtkpathbarcontainer.h
new file mode 100644
index 0000000..877d340
--- /dev/null
+++ b/gtk/gtkpathbarcontainer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 Carlos Soriano <csoriano gnome org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GTK_PATH_BAR_CONTAINER_H__
+#define __GTK_PATH_BAR_CONTAINER_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkbin.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_PATH_BAR_CONTAINER            (gtk_path_bar_container_get_type())
+#define GTK_PATH_BAR_CONTAINER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GTK_TYPE_PATH_BAR_CONTAINER, GtkPathBarContainer))
+#define GTK_PATH_BAR_CONTAINER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), 
GTK_TYPE_PATH_BAR_CONTAINER, GtkPathBarContainerClass))
+#define GTK_IS_PATH_BAR_CONTAINER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GTK_TYPE_PATH_BAR_CONTAINER))
+#define GTK_IS_PATH_BAR_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GTK_TYPE_PATH_BAR_CONTAINER)
+#define GTK_PATH_BAR_CONTAINER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GTK_TYPE_PATH_BAR_CONTAINER, GtkPathBarContainerClass))
+
+typedef struct _GtkPathBarContainer GtkPathBarContainer;
+typedef struct _GtkPathBarContainerClass GtkPathBarContainerClass;
+typedef struct _GtkPathBarContainerPrivate GtkPathBarContainerPrivate;
+
+struct _GtkPathBarContainerClass
+{
+  GtkBinClass parent;
+
+  /* Padding for future expansion */
+  gpointer reserved[10];
+};
+
+struct _GtkPathBarContainer
+{
+  GtkBin parent_instance;
+};
+
+GDK_AVAILABLE_IN_3_20
+GType             gtk_path_bar_container_get_type                (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_3_20
+GtkWidget        *gtk_path_bar_container_new                     (void);
+GDK_AVAILABLE_IN_3_20
+void              gtk_path_bar_container_set_spacing             (GtkPathBarContainer      *box,
+                                                                 gint                      spacing);
+GDK_AVAILABLE_IN_3_20
+gint              gtk_path_bar_container_get_spacing             (GtkPathBarContainer      *box);
+
+GDK_AVAILABLE_IN_3_20
+void              gtk_path_bar_container_set_inverted            (GtkPathBarContainer      *box,
+                                                                 gboolean                  inverted);
+GDK_AVAILABLE_IN_3_20
+gboolean          gtk_path_bar_container_get_inverted            (GtkPathBarContainer      *box);
+
+GDK_AVAILABLE_IN_3_20
+GList             *gtk_path_bar_container_get_overflow_children  (GtkPathBarContainer      *box);
+
+GDK_AVAILABLE_IN_3_20
+void              gtk_path_bar_container_add                     (GtkPathBarContainer      *self,
+                                                                 GtkWidget                *widget);
+GDK_AVAILABLE_IN_3_20
+void              gtk_path_bar_container_remove                  (GtkPathBarContainer      *self,
+                                                                 GtkWidget                *widget);
+G_END_DECLS
+
+#endif /* GTK_PATH_BAR_CONTAINER_H_ */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3352d9a..f892f2c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -86,7 +86,7 @@ noinst_PROGRAMS =  $(TEST_PROGS)      \
        testgtk                         \
        testheaderbar                   \
        testheightforwidth              \
-       testhidingbox                   \
+       testpathbarcontainer            \
        testiconview                    \
        testiconview-keynav             \
        testicontheme                   \
@@ -294,7 +294,7 @@ testpixbuf_save_DEPENDENCIES = $(TEST_DEPS)
 testpixbuf_color_DEPENDENCIES = $(TEST_DEPS)
 testpixbuf_scale_DEPENDENCIES = $(TEST_DEPS)
 testpathbar_DEPENDENCIES = $(TEST_DEPS)
-testhidingbox_DEPENDENCIES = $(TEST_DEPS)
+testpathbarcontainer_DEPENDENCIES = $(TEST_DEPS)
 testgmenu_DEPENDENCIES = $(TEST_DEPS)
 testlogout_DEPENDENCIES = $(TEST_DEPS)
 teststack_DEPENDENCIES = $(TEST_DEPS)
@@ -398,8 +398,8 @@ testmenubutton_SOURCES =    \
 testpathbar_SOURCES =          \
        testpathbar.c
 
-testhidingbox_SOURCES =        \
-       testhidingbox.c
+testpathbarcontainer_SOURCES =         \
+       testpathbarcontainer.c
 
 testprint_SOURCES =            \
        testprint.c             \
diff --git a/tests/testhidingbox.c b/tests/testpathbarcontainer.c
similarity index 79%
rename from tests/testhidingbox.c
rename to tests/testpathbarcontainer.c
index bc2446f..4dcf21a 100644
--- a/tests/testhidingbox.c
+++ b/tests/testpathbarcontainer.c
@@ -4,7 +4,7 @@
 
 #define N_BUTTONS 10
 
-static GtkWidget *hiding_box;
+static GtkWidget *path_bar_container;
 static char *lorem_ipsum = "Loremipsumdolorsitamet, consecteturadipisicingelit,";
 
 static char*
@@ -47,16 +47,16 @@ on_reset_button_clicked (GtkButton *reset_button)
   GtkWidget *button;
 
 #if 0
-  gtk_container_foreach (GTK_CONTAINER (hiding_box), (GtkCallback) gtk_widget_destroy, NULL);
+  gtk_container_foreach (GTK_CONTAINER (path_bar_container), (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_hiding_box_add (GTK_HIDING_BOX (hiding_box), button);
+      g_signal_connect (button, "clicked", (GCallback) on_button_clicked, path_bar_container);
+      gtk_path_bar_container_add (GTK_HIDING_BOX (path_bar_container), button);
     }
 
-  gtk_widget_show_all (hiding_box);
+  gtk_widget_show_all (path_bar_container);
 #endif
 }
 
@@ -67,8 +67,8 @@ 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_hiding_box_add (GTK_HIDING_BOX (hiding_box), button);
+  g_signal_connect (button, "clicked", (GCallback) on_button_clicked, patbar_container);
+  gtk_path_bar_container_add (GTK_HIDING_BOX (path_bar_container), button);
 }
 
 static void
@@ -78,18 +78,18 @@ on_remove_button (gint line)
   GList *last;
 
 #if 0
-  children = gtk_container_get_children (hiding_box);
+  children = gtk_container_get_children (path_bar_container);
   last = g_list_last (children);
   if (last)
-    gtk_container_remove (hiding_box, GTK_WIDGET (last->data));
+    gtk_container_remove (path_bar_container, GTK_WIDGET (last->data));
 #endif
 }
 
 static void
 on_invert_button (gint line)
 {
-  gtk_hiding_box_set_inverted (GTK_HIDING_BOX (hiding_box),
-                               !gtk_hiding_box_get_inverted (GTK_HIDING_BOX (hiding_box)));
+  gtk_path_bar_container_set_inverted (GTK_HIDING_BOX (path_bar_container),
+                               !gtk_path_bar_container_get_inverted (GTK_HIDING_BOX (path_bar_container)));
 }
 
 int
@@ -117,21 +117,21 @@ main (int argc, char *argv[])
                              NULL);
 
   grid = gtk_grid_new ();
-  g_type_ensure (GTK_TYPE_HIDING_BOX);
+  g_type_ensure (GTK_TYPE_PATH_BAR_CONTAINER);
 
   label = gtk_label_new ("Generic GtkPathBar tests");
   gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1);
 
   /* ----------------------------------------------------------------------- */
-  hiding_box = gtk_hiding_box_new ();
-  gtk_grid_attach (GTK_GRID (grid), hiding_box, 0, 1, 1, 1);
-  gtk_widget_show_all (hiding_box);
+  path_bar_container = gtk_path_bar_container_new ();
+  gtk_grid_attach (GTK_GRID (grid), path_bar_container, 0, 1, 1, 1);
+  gtk_widget_show_all (path_bar_container);
   /* Add/Remove buttons */
   add_button = gtk_button_new_with_label ("Add");
   gtk_widget_set_halign (add_button, GTK_ALIGN_END);
   remove_button = gtk_button_new_with_label ("Remove");
   gtk_widget_set_halign (remove_button, GTK_ALIGN_END);
-  gtk_grid_attach_next_to (GTK_GRID (grid), add_button, hiding_box, GTK_POS_RIGHT, 1, 1);
+  gtk_grid_attach_next_to (GTK_GRID (grid), add_button, path_bar_container, GTK_POS_RIGHT, 1, 1);
   g_signal_connect_swapped (add_button, "clicked", (GCallback) on_add_button, GINT_TO_POINTER (0));
   gtk_grid_attach_next_to (GTK_GRID (grid), remove_button, add_button, GTK_POS_RIGHT, 1, 1);
   g_signal_connect_swapped (remove_button, "clicked", (GCallback) on_remove_button, GINT_TO_POINTER (0));


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