[gtk+/wip/csoriano/pathbar-prototype] gtkpathbar: use gtkhidingbox completely



commit 4f6eb148c8cde4ca40f6820c3a49a0a852534155
Author: Carlos Soriano <csoriano gnome org>
Date:   Fri Nov 6 19:43:07 2015 +0100

    gtkpathbar: use gtkhidingbox completely

 gtk/gtkpathbar.c |  190 +++++++++++++++++-------------------------------------
 1 files changed, 59 insertions(+), 131 deletions(-)
---
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index 14d5979..ba8a789 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -184,6 +184,7 @@ create_path_chunk (GtkPathBar    *self,
   GtkWidget *button;
   GtkWidget *separator;
   GtkWidget *path_chunk;
+  GtkWidget *button_label;
   GtkStyleContext *style;
   PathChunkData *path_chunk_data;
   GtkTextDirection direction;
@@ -192,7 +193,12 @@ create_path_chunk (GtkPathBar    *self,
 
   path_chunk = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
-  button = gtk_toggle_button_new_with_label (label);
+  button = gtk_toggle_button_new ();
+  button_label = gtk_label_new (label);
+  gtk_label_set_ellipsize (GTK_LABEL (button_label), PANGO_ELLIPSIZE_MIDDLE);
+  gtk_label_set_width_chars (GTK_LABEL (button_label),
+                             MIN (g_utf8_strlen (label, -1), 6));
+  gtk_container_add (GTK_CONTAINER (button), button_label);
 
   g_signal_connect_swapped (button, "button-release-event",
                             G_CALLBACK (on_path_chunk_button_release_event), path_chunk);
@@ -233,7 +239,7 @@ static void
 popup_overflow_menu (GtkPathBar *self)
 {
   GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
-  GList *children;
+  GList *overflow_children;
   GList *l;
   PathChunkData *data;
   GtkWidget *path_chunk;
@@ -244,21 +250,18 @@ popup_overflow_menu (GtkPathBar *self)
   popover = gtk_popover_new (priv->overflow_button);
   gtk_container_add (GTK_CONTAINER (popover), overflow_box);
 
-  children = gtk_container_get_children (GTK_CONTAINER (priv->path_box));
-  for (l = children; l != NULL; l = l->next)
+  overflow_children = gtk_hiding_box_get_overflow_children (GTK_HIDING_BOX (priv->path_box));
+  for (l = overflow_children; l != NULL; l = l->next)
     {
-      if (!gtk_widget_get_child_visible (l->data))
-        {
-          data = g_object_get_data (l->data, "data");
-          path_chunk = create_path_chunk (self, (const GString*) data->path,
-                                          (const gchar*) data->label, FALSE);
-          gtk_container_add (GTK_CONTAINER (overflow_box), path_chunk);
-        }
+      data = g_object_get_data (l->data, "data");
+      path_chunk = create_path_chunk (self, (const GString*) data->path,
+                                      (const gchar*) data->label, FALSE);
+      gtk_container_add (GTK_CONTAINER (overflow_box), path_chunk);
     }
 
   gtk_widget_show_all (popover);
 
-  g_list_free (children);
+  g_list_free (overflow_children);
 }
 
 void
@@ -552,101 +555,20 @@ get_request_mode (GtkWidget *self)
 }
 
 static void
-allocate_overflow_button (GtkWidget     *self,
-                          GtkAllocation *container_allocation,
-                          gint          *current_x_pos)
-{
-  GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
-  gint overflow_button_min_width;
-  GtkAllocation child_allocation;
-  GtkTextDirection direction;
-
-  direction = gtk_widget_get_direction (self);
-  gtk_widget_get_preferred_width (priv->overflow_button, &overflow_button_min_width, NULL);
-  child_allocation.y = container_allocation->y;
-  child_allocation.height = container_allocation->height;
-  child_allocation.width = overflow_button_min_width;
-  child_allocation.x = *current_x_pos;
-  gtk_widget_size_allocate (priv->overflow_button, &child_allocation);
-
-  if (direction == GTK_TEXT_DIR_LTR)
-    *current_x_pos += overflow_button_min_width;
-  else
-    *current_x_pos -= overflow_button_min_width;
-}
-
-static void
-update_visible_children (GtkWidget     *self,
-                         GtkAllocation *container_allocation)
-{
-  GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
-  GList *children;
-  GList *l;
-  gint child_nat_width;
-  gint child_min_width;
-  gboolean overflow;
-  gint path_min_width;
-  gint path_nat_width;
-  gint min_width;
-  gint nat_width;
-  gboolean allocate_more_children = TRUE;
-
-  children = gtk_container_get_children (GTK_CONTAINER (priv->path_box));
-  children = g_list_reverse (children);
-  min_width = 0;
-  nat_width = 0;
-
-  get_path_preferred_width (self, &path_min_width, &path_nat_width);
-  overflow = container_allocation->width < path_min_width;
-
-  gtk_widget_set_child_visible (priv->overflow_button, overflow);
-
-  if (overflow)
-    {
-      gint overflow_button_min_width;
-
-      gtk_widget_get_preferred_width (priv->overflow_button, &overflow_button_min_width, NULL);
-      min_width += overflow_button_min_width;
-      nat_width += overflow_button_min_width;
-    }
-
-  for (l = children; l != NULL; l = l->next)
-    {
-      gtk_widget_get_preferred_width (l->data, &child_min_width, &child_nat_width);
-      if (min_width + child_min_width <= container_allocation->width && allocate_more_children)
-        {
-          gtk_widget_set_child_visible (l->data, TRUE);
-          min_width += child_min_width;
-          nat_width += child_nat_width;
-        }
-      else
-        {
-          gtk_widget_set_child_visible (l->data, FALSE);
-          allocate_more_children = FALSE;
-        }
-    }
-
-  g_list_free (children);
-}
-
-
-static void
 size_allocate (GtkWidget     *self,
                GtkAllocation *allocation)
 {
   GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
-  gint child_min_width;
-  gint child_nat_width;
   gint path_min_width;
   gint path_nat_width;
   gint current_x_pos;
-  gint box_start_x;
-  gint box_width;
-  GtkAllocation child_allocation;
+  gint overflow_button_min_width;
+  GtkAllocation path_container_allocation;
+  GtkAllocation overflow_button_allocation;
   GtkTextDirection direction;
   gboolean overflow;
+  GList *overflow_children;
   GList *children;
-  GList *l;
 
   gtk_widget_set_allocation (self, allocation);
 
@@ -655,47 +577,53 @@ size_allocate (GtkWidget     *self,
   if (g_list_length (children) == 0)
     return;
 
-  get_path_preferred_width (self, &path_min_width, &path_nat_width);
-  overflow = allocation->width < path_min_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);
+  overflow_children = gtk_hiding_box_get_overflow_children (GTK_HIDING_BOX (priv->path_box));
+  overflow = overflow_children != NULL;
+  g_list_free (overflow_children);
+
+  gtk_widget_set_child_visible (priv->overflow_button, FALSE);
+  gtk_widget_get_preferred_width (priv->path_box, &path_min_width, &path_nat_width);
+  gtk_widget_get_preferred_width (priv->overflow_button, &overflow_button_min_width, NULL);
   direction = gtk_widget_get_direction (self);
-  box_start_x = current_x_pos = direction == GTK_TEXT_DIR_LTR ? allocation->x : allocation->width;
-
-  update_visible_children (self, allocation);
+  current_x_pos = allocation->x;
 
+  g_print ("overflow %d %d\n", overflow, overflow_button_min_width);
   if (overflow && direction == GTK_TEXT_DIR_LTR)
     {
-      allocate_overflow_button (self, allocation, &current_x_pos);
-      box_start_x = current_x_pos;
-    }
-
-  for (l = children; l != NULL; l = l->next)
-    {
-      gtk_widget_get_preferred_width (l->data, &child_min_width, &child_nat_width);
-      child_allocation.width = overflow ? child_min_width : child_nat_width;
-      child_allocation.y = allocation->y;
-      child_allocation.height = allocation->height;
-      if (gtk_widget_get_child_visible (l->data))
-        {
-          child_allocation.x = current_x_pos;
-          gtk_widget_size_allocate (l->data, &child_allocation);
-
-          if (direction == GTK_TEXT_DIR_LTR)
-            current_x_pos += child_allocation.width;
-          else
-            current_x_pos -= child_allocation.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 = current_x_pos;
+      gtk_widget_set_child_visible (priv->overflow_button, TRUE);
+      gtk_widget_size_allocate (priv->overflow_button, &overflow_button_allocation);
+      current_x_pos += overflow_button_allocation.width;
     }
 
-  box_width = current_x_pos;
+  path_container_allocation.x = current_x_pos;
+  path_container_allocation.width = overflow ? allocation->width - overflow_button_min_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);
 
   if (overflow && direction == GTK_TEXT_DIR_RTL)
-    allocate_overflow_button (self, allocation, &current_x_pos);
-
-  child_allocation.x = box_start_x;
-  child_allocation.width = box_width;
-  child_allocation.y = allocation->y;
-  child_allocation.height = allocation->height;
-  gtk_widget_size_allocate (priv->path_box, &child_allocation);
+    {
+      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 -
+                                     overflow_button_min_width;
+      gtk_widget_set_child_visible (priv->overflow_button, TRUE);
+      gtk_widget_size_allocate (priv->overflow_button, &overflow_button_allocation);
+    }
 
   g_list_free (children);
 }
@@ -715,7 +643,7 @@ gtk_path_bar_class_init (GtkPathBarClass *klass)
   //widget_class->get_preferred_height = get_preferred_height;
   //widget_class->get_preferred_width_for_height = get_preferred_width_for_height;
   //widget_class->get_preferred_height_for_width = get_preferred_height_for_width;
-  //widget_class->size_allocate = size_allocate;
+  widget_class->size_allocate = size_allocate;
 
   /**
    * GtkPlacesSidebar::populate-popup:


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