[gtk+/wip/csoriano/pathbar-prototype: 46/46] gtkpathbar: root management done



commit 7f75672b96641ee08e9546814151826323414d92
Author: Carlos Soriano <csoriano gnome org>
Date:   Fri Nov 20 02:52:10 2015 +0100

    gtkpathbar: root management done

 gtk/gtkpathbar.c    |  303 +++++++++++++++++++++++++++------------------------
 gtk/gtkpathbar.h    |    5 +
 tests/testpathbar.c |   99 ++++++++++++++---
 3 files changed, 253 insertions(+), 154 deletions(-)
---
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index 0d3ae8f..5d2e77c 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -80,6 +80,7 @@ struct _GtkPathBarPrivate
   gboolean edit_mode_enabled;
 
   gboolean selecting_path;
+  gboolean setting_path;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkPathBar, gtk_path_bar, GTK_TYPE_BIN)
@@ -103,8 +104,9 @@ static guint path_bar_signals[LAST_SIGNAL] = { 0 };
 
 typedef struct {
   GtkWidget *button;
+  GIcon *icon;
   gchar *label;
-  GString *path;
+  gchar *path;
   GtkPathBar *path_bar;
 } PathChunkData;
 
@@ -208,13 +210,13 @@ on_path_chunk_button_release_event (GtkWidget      *path_chunk,
           if (priv->selecting_path)
             return TRUE;
 
-          gtk_path_bar_set_selected_path (data->path_bar, (const gchar*) data->path->str);
+          gtk_path_bar_set_selected_path (data->path_bar, data->path);
 
           return TRUE;
 
         case GDK_BUTTON_SECONDARY:
           show_path_chunk_popover (data->path_bar, path_chunk);
-          emit_populate_popup (data->path_bar, data->path->str);
+          emit_populate_popup (data->path_bar, data->path);
 
           return TRUE;
 
@@ -229,21 +231,25 @@ on_path_chunk_button_release_event (GtkWidget      *path_chunk,
 static void
 free_path_chunk_data (PathChunkData *data)
 {
-  g_free (data->label);
-  g_string_free (data->path, TRUE);
+  if (data->label)
+    g_free (data->label);
+  g_free (data->path);
+  g_clear_object (&data->icon);
   g_slice_free (PathChunkData, data);
 }
 
 static GtkWidget *
-create_path_chunk (GtkPathBar    *self,
-                   const GString *path,
-                   const gchar   *label,
-                   gboolean       add_separator)
+create_path_chunk (GtkPathBar  *self,
+                   const gchar *path,
+                   const gchar *label,
+                   GIcon       *icon,
+                   gboolean     add_separator)
 {
   GtkWidget *button;
   GtkWidget *separator;
   GtkWidget *path_chunk;
   GtkWidget *button_label;
+  GtkWidget *image;
   GtkStyleContext *style;
   PathChunkData *path_chunk_data;
   GtkTextDirection direction;
@@ -252,13 +258,22 @@ create_path_chunk (GtkPathBar    *self,
 
   path_chunk = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
   button = gtk_toggle_button_new ();
-  button_label = gtk_label_new (label);
-  gtk_label_set_ellipsize (GTK_LABEL (button_label), PANGO_ELLIPSIZE_MIDDLE);
-  // FIXME: the GtkLabel requests more than the number of chars set here.
-  // For visual testing for now substract 2 chars.
-  gtk_label_set_width_chars (GTK_LABEL (button_label),
-                             MIN (g_utf8_strlen (label, -1), 10));
-  gtk_container_add (GTK_CONTAINER (button), button_label);
+  if (label)
+    {
+      button_label = gtk_label_new (label);
+      gtk_label_set_ellipsize (GTK_LABEL (button_label), PANGO_ELLIPSIZE_MIDDLE);
+      // FIXME: the GtkLabel requests more than the number of chars set here.
+      // For visual testing for now substract 2 chars.
+      gtk_label_set_width_chars (GTK_LABEL (button_label),
+                                 MIN (strlen (label), 10));
+      gtk_container_add (GTK_CONTAINER (button), button_label);
+    }
+
+  if (icon)
+    {
+      image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
+      gtk_button_set_image (GTK_BUTTON (button), image);
+    }
 
   style = gtk_widget_get_style_context (button);
   gtk_style_context_add_class (style, "flat");
@@ -283,8 +298,17 @@ create_path_chunk (GtkPathBar    *self,
     }
 
   path_chunk_data = g_slice_new (PathChunkData);
-  path_chunk_data->label = g_strdup (label);
-  path_chunk_data->path = g_string_new (path->str);
+  if (label)
+    path_chunk_data->label = g_strdup (label);
+  else
+    path_chunk_data->label = NULL;
+
+  if (icon)
+    path_chunk_data->icon = g_object_ref (icon);
+  else
+    path_chunk_data->icon = NULL;
+
+  path_chunk_data->path = g_strdup (path);
   path_chunk_data->path_bar = self;
   path_chunk_data->button = button;
   g_object_set_data_full (G_OBJECT (path_chunk), "data",
@@ -295,129 +319,86 @@ create_path_chunk (GtkPathBar    *self,
   return path_chunk;
 }
 
-static GtkWidget*
-create_root_chunk (GtkPathBar *self)
+static gboolean
+check_path_format (const gchar *path)
 {
-  GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self);
-  GtkWidget *button;
-  GtkWidget *separator;
-  GtkWidget *path_chunk = NULL;
-  GtkWidget *button_label;
-  GtkWidget *image;
-  GtkStyleContext *style;
-  PathChunkData *path_chunk_data;
-  GtkTextDirection direction;
-
-  if (priv->root_label || priv->root_icon)
-    {
-      direction = gtk_widget_get_direction (GTK_WIDGET (self));
+  gchar ** splitted_path = NULL;
+  gboolean valid = FALSE;
 
-      path_chunk = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-      button = gtk_toggle_button_new ();
-      if (priv->root_label)
-        {
-          button_label = gtk_label_new (priv->root_label);
-          gtk_label_set_ellipsize (GTK_LABEL (button_label), PANGO_ELLIPSIZE_MIDDLE);
-          gtk_button_set_label (GTK_BUTTON (path_chunk), priv->root_label);
-          // FIXME: the GtkLabel requests more than the number of chars set here.
-          // For visual testing for now substract 2 chars.
-          gtk_label_set_width_chars (GTK_LABEL (button_label),
-                                     MIN (g_utf8_strlen (priv->root_label, -1), 10));
-          gtk_container_add (GTK_CONTAINER (button), button_label);
-        }
+  if (!path || strlen (path) == 0)
+    goto out;
 
-      if (priv->root_icon)
-        {
-          image = gtk_image_new_from_gicon (priv->root_icon, GTK_ICON_SIZE_MENU);
-          gtk_button_set_image (GTK_BUTTON (path_chunk), image);
-        }
+  if (!g_utf8_validate (path, -1, NULL))
+    goto out;
 
-      style = gtk_widget_get_style_context (button);
-      gtk_style_context_add_class (style, "flat");
+  /* Special case "/", which is always valid */
+  if (g_strcmp0 (path, "/") == 0)
+    {
+      valid = TRUE;
+      goto out;
+    }
 
-      g_signal_connect_swapped (button, "button-release-event",
-                                G_CALLBACK (on_path_chunk_button_release_event), path_chunk);
+  splitted_path = g_strsplit (path, "/", -1);
 
-      separator = gtk_label_new ("/");
-      gtk_widget_set_sensitive (separator, FALSE);
-      gtk_container_add (GTK_CONTAINER (path_chunk), separator);
+  /* Path must start with "/" */
+  if (g_strcmp0 (splitted_path[0], "") != 0)
+    goto out;
 
-      if (direction == GTK_TEXT_DIR_LTR)
-        {
-          gtk_container_add (GTK_CONTAINER (path_chunk), button);
-          gtk_container_add (GTK_CONTAINER (path_chunk), separator);
-        } else {
-          gtk_container_add (GTK_CONTAINER (path_chunk), separator);
-          gtk_container_add (GTK_CONTAINER (path_chunk), button);
-        }
+  for (guint i = 0; i < g_strv_length (splitted_path); i++)
+    {
+      /* First part of the path is always empty when splitted */
+      if (g_strcmp0 (splitted_path[i], "") == 0 && i != 0)
+        goto out;
+    }
 
-      path_chunk_data = g_slice_new (PathChunkData);
-      path_chunk_data->label = g_strdup (priv->root_label);
-      path_chunk_data->path = g_string_new (priv->root_path);
-      path_chunk_data->path_bar = self;
-      path_chunk_data->button = path_chunk;
-      g_object_set_data_full (G_OBJECT (path_chunk), "data",
-                              path_chunk_data, (GDestroyNotify) free_path_chunk_data);
+  valid = TRUE;
 
-      gtk_widget_show_all (path_chunk);
-    }
+out:
+  if (splitted_path)
+    g_strfreev (splitted_path);
 
-  return path_chunk;
+  return valid;
 }
 
 static void
 on_entry_activate (GtkPathBar *self)
 {
   GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self);
+  const gchar *text;
 
   gtk_path_bar_set_edit_mode_enabled (self, FALSE);
-  gtk_path_bar_set_path (self, gtk_entry_get_text (GTK_ENTRY (priv->edit_entry)));
+  text = gtk_entry_get_text (GTK_ENTRY (priv->edit_entry));
+  if (check_path_format (text))
+    gtk_path_bar_set_path (self, text);
+  else
+    gtk_entry_set_text (GTK_ENTRY (priv->edit_entry), priv->path);
+
 }
 
-static gboolean
-check_path_format (const gchar *path)
+static gchar**
+get_splitted_path (const gchar* path)
 {
-  gchar ** splitted_path;
-  gboolean valid = FALSE;
-
-  splitted_path = g_strsplit (path, "/", -1);
+  gchar *path_no_first_slash;
+  gchar **splitted_path;
 
-  if (g_strv_length (splitted_path) == 0)
-    goto out;
+  path_no_first_slash = g_utf8_substring (path, 1, strlen (path));
+  splitted_path = g_strsplit (path_no_first_slash, "/", -1);
 
-  if (!g_utf8_validate (path, -1, NULL))
-    goto out;
+  g_free (path_no_first_slash);
 
-  for (guint i = 0; i < g_strv_length (splitted_path); i++)
-    {
-      /* First and last part of the path is always empty when splitted */
-      if (g_strcmp0 (splitted_path[i], "") == 0 && i != 0)
-        goto out;
-    }
-  /* Path must start with "/" */
-  if (g_strcmp0 (splitted_path[0], "") != 0)
-    goto out;
-
-  valid = TRUE;
-
-out:
-  g_strfreev (splitted_path);
-
-  return valid;
+  return splitted_path;
 }
 
 static void
 update_path_bar (GtkPathBar  *self)
 {
   GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self);
-  gchar ** splitted_path;
-  GString *current_path = NULL;
   GtkWidget *path_chunk;
   GtkWidget *path_box;
   GtkWidget *overflow_button;
   GtkWidget *path_bar;
   GtkWidget *root_chunk;
-  gchar *unprefixed_path = NULL;
+  gchar *unprefixed_path;
 
   get_path_bar_widgets (GTK_PATH_BAR (self), &path_bar, &overflow_button, &path_box, FALSE);
 
@@ -427,30 +408,60 @@ update_path_bar (GtkPathBar  *self)
 
   gtk_container_foreach (GTK_CONTAINER (path_box), (GtkCallback) gtk_widget_destroy, NULL);
 
-  root_chunk = create_root_chunk (self);
-  if (root_chunk)
-    gtk_container_add (GTK_CONTAINER (path_box), root_chunk);
-
-  /* Remove root path */
   if (priv->root_path)
-    unprefixed_path = g_utf8_substring (priv->path, strlen (priv->root_path) - 1,
-                                        strlen (priv->path) -1);
+    {
+      root_chunk = create_path_chunk (self, priv->root_path, priv->root_label,
+                                      priv->root_icon, TRUE);
+      gtk_container_add (GTK_CONTAINER (path_box), root_chunk);
+      /* Remove root path */
+      unprefixed_path = g_utf8_substring (priv->path, strlen (priv->root_path),
+                                          strlen (priv->path));
+    }
   else
-    unprefixed_path = g_strdup (priv->path);
-
-  splitted_path = g_strsplit (unprefixed_path, "/", -1);
-  current_path = g_string_new ("");
-
-  for (guint i = 0; i < g_strv_length (splitted_path); i++)
     {
-      if (g_strcmp0 (splitted_path[0], "") == 0 && i == 0)
-        continue;
-
-      g_string_append (current_path, "/");
-      g_string_append (current_path, splitted_path[i]);
+      unprefixed_path = g_strdup (priv->path);
+    }
 
-      path_chunk = create_path_chunk (self, current_path, splitted_path[i],
-                                      i != g_strv_length (splitted_path) - 1);
+  /* We always expect a label and we use "/" as a separator.
+   * However, "/" is a valid path, so we need to handle it ourselves
+   * if the client didn't set a root label or icon for it.
+   */
+  if (g_strcmp0 (priv->path, "/") != 0 || priv->root_path)
+    {
+      /* Do nothing if the path and the path reprensented by the root are equal */
+      if (g_strcmp0 (priv->path, priv->root_path) != 0)
+        {
+          GString *current_path = NULL;
+          gchar **splitted_path;
+          gboolean add_separator;
+          gint length;
+          gint i;
+
+          splitted_path = get_splitted_path (unprefixed_path);
+          current_path = g_string_new (priv->root_path);
+          length = g_strv_length (splitted_path);
+          for (i = 0; i < length; i++)
+            {
+              g_string_append (current_path, "/");
+              g_string_append (current_path, splitted_path[i]);
+
+              /* We add a separator for all items except the last one, which will result
+               * in a pathbar in the form of "Home/Documents/Example".
+               * However,if only one item is present, add a separator at the end since
+               * is visually more pleasant. The result will be in the form of "Home/" */
+              add_separator = length == 1 || i != length - 1;
+              path_chunk = create_path_chunk (self, current_path->str, splitted_path[i],
+                                              NULL, add_separator);
+              gtk_container_add (GTK_CONTAINER (path_box), path_chunk);
+            }
+
+          g_strfreev (splitted_path);
+          g_string_free (current_path, TRUE);
+        }
+    }
+  else
+    {
+      path_chunk = create_path_chunk (self, "/", "/", NULL, FALSE);
       gtk_container_add (GTK_CONTAINER (path_box), path_chunk);
     }
 
@@ -458,9 +469,7 @@ update_path_bar (GtkPathBar  *self)
 
   gtk_stack_set_visible_child (GTK_STACK (priv->path_bar_containers_stack), path_bar);
 
-  g_strfreev (splitted_path);
   g_free (unprefixed_path);
-  g_string_free (current_path, TRUE);
 }
 
 static void
@@ -487,14 +496,14 @@ update_selected_path (GtkPathBar  *self)
     {
       data = g_object_get_data (G_OBJECT (l->data), "data");
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->button),
-                                    g_strcmp0 (data->path->str, priv->selected_path) == 0);
+                                    g_strcmp0 (data->path, priv->selected_path) == 0);
     }
 
   for (l = overflow_children; l != NULL; l = l->next)
     {
       data = g_object_get_data (G_OBJECT (l->data), "data");
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->button),
-                                    g_strcmp0 (data->path->str, priv->selected_path) == 0);
+                                    g_strcmp0 (data->path, priv->selected_path) == 0);
     }
 
   g_list_free (children);
@@ -526,8 +535,7 @@ populate_overflow_popover (GtkPathBar *self)
   for (l = overflow_children; l != NULL; l = l->next)
     {
       data = g_object_get_data (l->data, "data");
-      path_chunk = create_path_chunk (self, (const GString*) data->path,
-                                      (const gchar*) data->label, FALSE);
+      path_chunk = create_path_chunk (self, data->path, data->label, data->icon, FALSE);
       gtk_container_add (GTK_CONTAINER (overflow_container), path_chunk);
     }
 
@@ -708,6 +716,7 @@ gtk_path_bar_init (GtkPathBar *self)
   gtk_widget_init_template (GTK_WIDGET (self));
 
   priv->selecting_path = FALSE;
+  priv->setting_path = FALSE;
   priv->hide_direction = GTK_DIR_RIGHT;
 }
 
@@ -764,9 +773,18 @@ gtk_path_bar_set_path (GtkPathBar  *self,
     g_free (priv->path);
   priv->path = g_strdup (path);
 
-  update_path_bar (self);
+  priv->setting_path = TRUE;
+
+  /* Remove root */
+  gtk_path_bar_set_root (self, NULL, NULL, NULL);
+
+  /* Notify before updating visually the path, in this way we allow clients to
+   * set a root withouth flashing the path bar */
   g_object_notify_by_pspec (G_OBJECT (self), path_bar_properties[PROP_PATH]);
+  update_path_bar (self);
   gtk_path_bar_set_selected_path (self, priv->path);
+
+  priv->setting_path = FALSE;
 }
 
 /**
@@ -812,7 +830,6 @@ gtk_path_bar_set_selected_path (GtkPathBar  *self,
 
   priv = gtk_path_bar_get_instance_private (GTK_PATH_BAR (self));
 
-  g_print ("set selected %s %s\n", priv->path, path);
   g_return_if_fail (g_str_has_prefix (priv->path, path) ||
                     g_strcmp0 (priv->path, path) == 0);
 
@@ -957,27 +974,33 @@ gtk_path_bar_set_root (GtkPathBar  *self,
       g_object_unref (priv->root_icon);
       priv->root_icon = NULL;
     }
-  if (icon)
-    priv->root_icon = g_object_ref (icon);
 
   if (priv->root_label)
     {
       g_free (priv->root_label);
       priv->root_label = NULL;
     }
-  if (label)
-    priv->root_label = g_strdup (label);
 
   if (priv->root_path)
     {
       g_free (priv->root_path);
       priv->root_path = NULL;
     }
+
+  if (icon)
+    priv->root_icon = g_object_ref (icon);
+
+  if (label)
+    priv->root_label = g_strdup (label);
+
   if (path)
     priv->root_path = g_strdup (path);
 
-  update_path_bar (self);
-  update_selected_path (self);
+  if (!priv->setting_path)
+    {
+      update_path_bar (self);
+      update_selected_path (self);
+    }
 }
 
 GtkWidget *
diff --git a/gtk/gtkpathbar.h b/gtk/gtkpathbar.h
index 4095a0a..4ecd293 100644
--- a/gtk/gtkpathbar.h
+++ b/gtk/gtkpathbar.h
@@ -88,6 +88,11 @@ GDK_AVAILABLE_IN_3_20
 void                  gtk_path_bar_set_edit_mode_enabled (GtkPathBar       *path_bar,
                                                           gboolean          enable);
 
+GDK_AVAILABLE_IN_3_20
+void                  gtk_path_bar_set_root              (GtkPathBar       *self,
+                                                          GIcon            *icon,
+                                                          const gchar      *label,
+                                                          const gchar      *path);
 
 G_END_DECLS
 
diff --git a/tests/testpathbar.c b/tests/testpathbar.c
index 0cbaaa7..761f725 100644
--- a/tests/testpathbar.c
+++ b/tests/testpathbar.c
@@ -5,8 +5,8 @@
 static GActionGroup *action_group;
 static GList *path_bars = NULL;
 static GList *files_path_bars = NULL;
-static const gchar* original_path = "/test/test 2/test 3/asda lkasdl/pppppppppppppppp/ alskd";
-static const gchar* file_original_path = "/test/test 2/test 3/asda lkasdl/pppppppppppppppp/alskd";
+static const gchar* ORIGINAL_PATH = "/test/test 2/test 3/asda lkasdl/pppppppppppppppp/ alskd";
+static const gchar* ROOT_PATH = "/test/test 2/test 3";
 
 static void
 action_menu_1 (GSimpleAction *action,
@@ -93,18 +93,38 @@ on_path_selected_set_path (GtkPathBar *path_bar,
 }
 
 static void
+on_path_changed_set_root (GtkPathBar *path_bar,
+                          GParamSpec *pspec,
+                          gpointer   *user_data)
+{
+  gchar *new_path;
+
+  new_path = g_strdup (gtk_path_bar_get_path (path_bar));
+  if (g_str_has_prefix (new_path, ROOT_PATH))
+    {
+      g_print ("Path changed: %s, setting root\n", new_path);
+      gtk_path_bar_set_root (path_bar, NULL, "NewRoot", ROOT_PATH);
+    }
+  else if (g_strcmp0 (new_path, "/") == 0)
+    {
+      g_print ("Path changed: %s, setting root to “/” \n", new_path);
+      gtk_path_bar_set_root (path_bar, NULL, "TopRoot", "/");
+    }
+}
+
+static void
 on_reset_button_clicked (GtkButton *reset_button)
 {
   GList *l;
   GFile *file;
 
-  file = g_file_new_for_path (file_original_path);
+  file = g_file_new_for_path (ORIGINAL_PATH);
 
   for (l = files_path_bars; l != NULL; l = l->next)
     gtk_files_path_bar_set_file (l->data, file);
 
   for (l = path_bars; l != NULL; l = l->next)
-    gtk_path_bar_set_path (l->data, original_path);
+    gtk_path_bar_set_path (l->data, ORIGINAL_PATH);
 
   g_object_unref (file);
 }
@@ -149,6 +169,7 @@ main (int argc, char *argv[])
   GtkWidget *edit_mode_button;
   GtkWidget *label;
   GFile *file;
+  GIcon *icon;
 
   gtk_init (&argc, &argv);
 
@@ -170,12 +191,13 @@ main (int argc, char *argv[])
   grid = gtk_grid_new ();
   g_type_ensure (GTK_TYPE_PATH_BAR);
 
-  label = gtk_label_new ("Generic path bar tests");
+  label = gtk_label_new ("Generic GtkPathBar tests");
   gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1);
 
+  /* ----------------------------------------------------------------------- */
   path_bar = gtk_path_bar_new ();
   gtk_grid_attach (GTK_GRID (grid), path_bar, 0, 1, 1, 1);
-  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), original_path);
+  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), ORIGINAL_PATH);
   g_signal_connect (GTK_PATH_BAR (path_bar), "populate-popup",
                     G_CALLBACK (on_populate_popup), window);
   g_signal_connect (GTK_PATH_BAR (path_bar), "notify::selected-path",
@@ -188,9 +210,10 @@ main (int argc, char *argv[])
                     G_CALLBACK (on_path_bar_edit_mode_button_clicked), path_bar);
   gtk_grid_attach (GTK_GRID (grid), edit_mode_button, 1, 1, 1, 1);
 
+  /* ----------------------------------------------------------------------- */
   path_bar = gtk_path_bar_new ();
   gtk_path_bar_set_hide_direction (GTK_PATH_BAR (path_bar), GTK_DIR_LEFT);
-  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), original_path);
+  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), ORIGINAL_PATH);
   g_signal_connect (GTK_PATH_BAR (path_bar), "populate-popup",
                     G_CALLBACK (on_populate_popup), window);
   g_signal_connect (GTK_PATH_BAR (path_bar), "notify::selected-path",
@@ -204,12 +227,13 @@ main (int argc, char *argv[])
                     G_CALLBACK (on_path_bar_edit_mode_button_clicked), path_bar);
   gtk_grid_attach (GTK_GRID (grid), edit_mode_button, 1, 2, 1, 1);
 
-  label = gtk_label_new ("File chooser use case test");
+  label = gtk_label_new ("“/” a.k.a root, special case");
   gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 2, 1);
 
+  /* ----------------------------------------------------------------------- */
   path_bar = gtk_path_bar_new ();
   gtk_path_bar_set_hide_direction (GTK_PATH_BAR (path_bar), GTK_DIR_LEFT);
-  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), original_path);
+  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), "/");
   g_signal_connect (GTK_PATH_BAR (path_bar), "populate-popup",
                     G_CALLBACK (on_populate_popup), window);
   g_signal_connect (GTK_PATH_BAR (path_bar), "notify::selected-path",
@@ -223,24 +247,71 @@ main (int argc, char *argv[])
                     G_CALLBACK (on_path_bar_edit_mode_button_clicked), path_bar);
   gtk_grid_attach (GTK_GRID (grid), edit_mode_button, 1, 4, 1, 1);
 
+  label = gtk_label_new ("GtkPathBar with special roots");
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 5, 2, 1);
+
+  /* ----------------------------------------------------------------------- */
+  path_bar = gtk_path_bar_new ();
+  gtk_path_bar_set_hide_direction (GTK_PATH_BAR (path_bar), GTK_DIR_LEFT);
+  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), ORIGINAL_PATH);
+  gtk_path_bar_set_root (GTK_PATH_BAR (path_bar), NULL, "ThisIsARoot", "/test/test 2/test 3");
+  g_signal_connect (GTK_PATH_BAR (path_bar), "populate-popup",
+                    G_CALLBACK (on_populate_popup), window);
+  g_signal_connect (GTK_PATH_BAR (path_bar), "notify::selected-path",
+                    G_CALLBACK (on_path_selected_set_path), window);
+  g_signal_connect (GTK_PATH_BAR (path_bar), "notify::path",
+                    G_CALLBACK (on_path_changed_set_root), window);
+  path_bars = g_list_append (path_bars, path_bar);
+  gtk_grid_attach (GTK_GRID (grid), path_bar, 0, 6, 1, 1);
+
+  edit_mode_button = gtk_button_new_from_icon_name ("edit-symbolic", GTK_ICON_SIZE_MENU);
+  gtk_widget_set_hexpand (edit_mode_button, FALSE);
+  g_signal_connect (GTK_BUTTON (edit_mode_button), "clicked",
+                    G_CALLBACK (on_path_bar_edit_mode_button_clicked), path_bar);
+  gtk_grid_attach (GTK_GRID (grid), edit_mode_button, 1, 6, 1, 1);
+
+  /* ----------------------------------------------------------------------- */
+  path_bar = gtk_path_bar_new ();
+  gtk_path_bar_set_hide_direction (GTK_PATH_BAR (path_bar), GTK_DIR_LEFT);
+  gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), ORIGINAL_PATH);
+  icon = g_themed_icon_new ("drives-harddisk-symbolic");
+  gtk_path_bar_set_root (GTK_PATH_BAR (path_bar), icon, NULL, "/test/test 2/test 3");
+  g_object_unref (icon);
+  g_signal_connect (GTK_PATH_BAR (path_bar), "populate-popup",
+                    G_CALLBACK (on_populate_popup), window);
+  g_signal_connect (GTK_PATH_BAR (path_bar), "notify::selected-path",
+                    G_CALLBACK (on_path_selected_set_path), window);
+  g_signal_connect (GTK_PATH_BAR (path_bar), "notify::path",
+                    G_CALLBACK (on_path_changed_set_root), window);
+  path_bars = g_list_append (path_bars, path_bar);
+  gtk_grid_attach (GTK_GRID (grid), path_bar, 0, 7, 1, 1);
+
+  edit_mode_button = gtk_button_new_from_icon_name ("edit-symbolic", GTK_ICON_SIZE_MENU);
+  gtk_widget_set_hexpand (edit_mode_button, FALSE);
+  g_signal_connect (GTK_BUTTON (edit_mode_button), "clicked",
+                    G_CALLBACK (on_path_bar_edit_mode_button_clicked), path_bar);
+  gtk_grid_attach (GTK_GRID (grid), edit_mode_button, 1, 7, 1, 1);
+
   /* GtkFilesPathBar tests */
   label = gtk_label_new ("GtkFilesPathBar tests");
-  gtk_grid_attach (GTK_GRID (grid), label, 0, 5, 2, 1);
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 8, 2, 1);
+
+  /* ----------------------------------------------------------------------- */
   path_bar = gtk_files_path_bar_new ();
-  file = g_file_new_for_path (file_original_path);
+  file = g_file_new_for_path (ORIGINAL_PATH);
   gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (path_bar), file);
   g_signal_connect (GTK_FILES_PATH_BAR (path_bar), "populate-popup",
                     G_CALLBACK (on_populate_popup), window);
   g_signal_connect (GTK_FILES_PATH_BAR (path_bar), "notify::file",
                     G_CALLBACK (on_file_changed), window);
   files_path_bars = g_list_append (files_path_bars, path_bar);
-  gtk_grid_attach (GTK_GRID (grid), path_bar, 0, 6, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), path_bar, 0, 9, 1, 1);
 
   edit_mode_button = gtk_button_new_from_icon_name ("edit-symbolic", GTK_ICON_SIZE_MENU);
   gtk_widget_set_hexpand (edit_mode_button, FALSE);
   g_signal_connect (GTK_BUTTON (edit_mode_button), "clicked",
                     G_CALLBACK (on_files_path_bar_edit_mode_button_clicked), path_bar);
-  gtk_grid_attach (GTK_GRID (grid), edit_mode_button, 1, 6, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), edit_mode_button, 1, 9, 1, 1);
 
   g_clear_object (&file);
 
@@ -249,7 +320,7 @@ main (int argc, char *argv[])
   gtk_widget_set_hexpand (reset_button, TRUE);
   g_signal_connect (GTK_BUTTON (reset_button), "clicked",
                     G_CALLBACK (on_reset_button_clicked), window);
-  gtk_grid_attach (GTK_GRID (grid), reset_button, 0, 7, 2, 1);
+  gtk_grid_attach (GTK_GRID (grid), reset_button, 0, 10, 2, 1);
 
   gtk_container_add (GTK_CONTAINER (window), grid);
   gtk_widget_show_all (window);


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