[gtk+/wip/combo: 7/11] Make collapsing work in groups



commit 8c7ffdb03d1959ab54a5e6169ca17b52e7347a25
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Dec 25 22:24:16 2014 -0500

    Make collapsing work in groups

 gtk/gtkcombo.c |  128 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 96 insertions(+), 32 deletions(-)
---
diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c
index f5773fe..06d7821 100644
--- a/gtk/gtkcombo.c
+++ b/gtk/gtkcombo.c
@@ -298,8 +298,11 @@ static gboolean button_key_press     (GtkWidget      *widget,
                                       GtkCombo       *combo);
 static void     reset_popover        (GtkWidget      *popover,
                                       GtkCombo       *combo);
-static void     collapse_list        (GtkCombo       *combo);
-static void     expand_list          (GtkCombo       *combo);
+static void     collapse             (GtkCombo       *combo,
+                                      GtkWidget      *list,
+                                      GtkWidget      *revealer);
+static void     expand               (GtkCombo       *combo,
+                                      GtkWidget      *list);
 static void     list_header_func     (GtkListBoxRow  *row,
                                       GtkListBoxRow  *before,
                                       gpointer        data);
@@ -311,6 +314,8 @@ static gint     list_sort_func       (GtkListBoxRow  *row1,
 static void     custom_header_func   (GtkListBoxRow  *row,
                                       GtkListBoxRow  *before,
                                       gpointer        data);
+static GtkWidget *group_get_list     (GtkCombo       *combo,
+                                      const gchar    *group);
 
 static void     gtk_combo_buildable_init (GtkBuildableIface *iface);
 
@@ -366,6 +371,8 @@ gtk_combo_init (GtkCombo *combo)
 
   gtk_list_box_set_header_func (GTK_LIST_BOX (combo->custom), custom_header_func, combo, NULL);
 
+  g_object_set_data (G_OBJECT (combo->list), "show-more-item", combo->show_more);
+
   reset_popover (combo->popover, combo);
 }
 
@@ -720,12 +727,19 @@ list_filter_func (GtkListBoxRow *row,
   return ret;
 }
 
+static GtkWidget *
+list_get_show_more_item (GtkWidget *list)
+{
+  return (GtkWidget*)g_object_get_data (G_OBJECT (list), "show-more-item");
+}
+
 static gint
 list_sort_func (GtkListBoxRow *row1,
                 GtkListBoxRow *row2,
                 gpointer       data)
 {
   GtkCombo *combo = data;
+  GtkWidget *show_more;
 
   if (row1 == row2)
     return 0;
@@ -741,16 +755,18 @@ list_sort_func (GtkListBoxRow *row1,
       return g_strcmp0 (sort1, sort2);
     }
 
+  show_more = list_get_show_more_item (gtk_widget_get_parent (GTK_WIDGET (row1)));
+
   if ((GtkWidget*)row1 == combo->add_custom)
     return -1;
 
-  if ((GtkWidget*)row1 == combo->show_more)
+  if ((GtkWidget*)row1 == show_more)
     return 1;
 
   if ((GtkWidget*)row2 == combo->add_custom)
     return 1;
 
-  if ((GtkWidget*)row2 == combo->show_more)
+  if ((GtkWidget*)row2 == show_more)
     return -1;
 
   return 0;
@@ -776,7 +792,7 @@ static void
 search_changed (GtkSearchEntry *entry,
                 GtkCombo       *combo)
 {
-  expand_list (combo);
+  expand (combo, combo->list);
   gtk_list_box_invalidate_filter (GTK_LIST_BOX (combo->list));
 }
 
@@ -787,7 +803,7 @@ reset_popover (GtkWidget *widget,
   gtk_stack_set_visible_child_name (GTK_STACK (combo->stack), "list");
   gtk_entry_set_text (GTK_ENTRY (combo->search_entry), "");
   gtk_widget_hide (combo->search_revealer);
-  collapse_list (combo);
+  collapse (combo, combo->list, combo->search_revealer);
   gtk_entry_set_text (GTK_ENTRY (combo->custom_entry), "");
 }
 
@@ -944,9 +960,9 @@ list_row_activated (GtkListBox    *list,
 {
   const gchar *group;
 
-  if ((GtkWidget*)row == combo->show_more)
+  if ((GtkWidget*)row == list_get_show_more_item (GTK_WIDGET (list)))
     {
-      expand_list (combo);
+      expand (combo, GTK_WIDGET (list));
       return;
     }
 
@@ -960,6 +976,8 @@ list_row_activated (GtkListBox    *list,
   group = (const gchar *) g_object_get_data (G_OBJECT (row), "group");
   if (group)
     {
+      if (g_strcmp0 (group, "list") != 0)
+        collapse (combo, group_get_list (combo, group), NULL);
       gtk_stack_set_visible_child_name (GTK_STACK (combo->stack), group);
       return;
     }
@@ -1009,12 +1027,14 @@ custom_entry_changed (GObject    *entry,
 }
 
 static void
-update_scrollbar (GtkCombo *combo,
-                  gboolean  allow)
+update_scrollbar (GtkWidget *list,
+                  gboolean   allow)
 {
   GtkPolicyType policy;
+  GtkWidget *scrolled_window;
 
-  g_object_get (combo->scrolled_window, "vscrollbar-policy", &policy, NULL);
+  scrolled_window = gtk_widget_get_ancestor (list, GTK_TYPE_SCROLLED_WINDOW);
+  g_object_get (scrolled_window, "vscrollbar-policy", &policy, NULL);
 
   if ((allow && policy == GTK_POLICY_AUTOMATIC) ||
       (!allow && policy == GTK_POLICY_NEVER))
@@ -1022,15 +1042,15 @@ update_scrollbar (GtkCombo *combo,
 
   if (allow)
     {
-      gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (combo->scrolled_window),
-                                                  gtk_widget_get_allocated_height (combo->list));
-      g_object_set (combo->scrolled_window, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL);
+      gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window),
+                                                  gtk_widget_get_allocated_height (list));
+      g_object_set (scrolled_window, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL);
     }
   else
     {
-      gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (combo->scrolled_window),
+      gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window),
                                                   -1);
-      g_object_set (combo->scrolled_window, "vscrollbar-policy", GTK_POLICY_NEVER, NULL);
+      g_object_set (scrolled_window, "vscrollbar-policy", GTK_POLICY_NEVER, NULL);
     }
 }
 
@@ -1051,25 +1071,33 @@ show_few (GtkWidget *widget, gpointer data)
 }
 
 static void
-collapse_list (GtkCombo *combo)
+collapse (GtkCombo  *combo,
+          GtkWidget *list,
+          GtkWidget *revealer)
 {
   gint count;
+  GtkWidget *show_more;
 
+  show_more = list_get_show_more_item (list);
   count = 0;
-  gtk_container_foreach (GTK_CONTAINER (combo->list), show_few, &count);
+  gtk_container_foreach (GTK_CONTAINER (list), show_few, &count);
   if (count < 7)
     {
-      gtk_revealer_set_reveal_child (GTK_REVEALER (combo->search_revealer), FALSE);
-      gtk_widget_hide (combo->show_more);
+      if (revealer)
+        gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE);
+      gtk_widget_hide (show_more);
     }
   else
     {
-      gtk_widget_show (combo->search_revealer);
-      gtk_revealer_set_reveal_child (GTK_REVEALER (combo->search_revealer), TRUE);
-      gtk_widget_show (combo->show_more);
+      if (revealer)
+        {
+          gtk_widget_show (revealer);
+          gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE);
+        }
+      gtk_widget_show (show_more);
     }
 
-  update_scrollbar (combo, FALSE);
+  update_scrollbar (list, FALSE);
 }
 
 static void
@@ -1082,13 +1110,17 @@ show_all (GtkWidget *widget, gpointer data)
 }
 
 static void
-expand_list (GtkCombo *combo)
+expand (GtkCombo  *combo,
+        GtkWidget *list)
 {
-  if (gtk_widget_get_visible (combo->show_more))
+  GtkWidget *show_more;
+
+  show_more = list_get_show_more_item (list);
+  if (gtk_widget_get_visible (show_more))
     {
-      gtk_container_foreach (GTK_CONTAINER (combo->list), show_all, NULL);
-      gtk_widget_hide (combo->show_more);
-      update_scrollbar (combo, TRUE);
+      gtk_container_foreach (GTK_CONTAINER (list), show_all, NULL);
+      gtk_widget_hide (show_more);
+      update_scrollbar (list, TRUE);
     }
 }
 
@@ -1285,7 +1317,7 @@ gtk_combo_add (GtkCombo    *combo,
   g_return_if_fail (GTK_IS_COMBO (combo));
 
   add_to_list (combo->list, id, sort, text);
-  collapse_list (combo);
+  collapse (combo, combo->list, combo->search_revealer);
 }
 
 /**
@@ -1312,7 +1344,7 @@ gtk_combo_remove (GtkCombo    *combo,
   if (g_strcmp0 (id, combo->active) == 0)
     set_active (combo, NULL);
 
-  collapse_list (combo);
+  collapse (combo, combo->list, combo->search_revealer);
 }
 
 /**
@@ -1405,6 +1437,19 @@ gtk_combo_get_allow_custom (GtkCombo *combo)
 }
 
 static GtkWidget *
+group_get_list (GtkCombo    *combo,
+                const gchar *group)
+{
+  GtkWidget *tab;
+
+  tab = gtk_stack_get_child_by_name (GTK_STACK (combo->stack), group);
+  if (!tab)
+    return NULL;
+
+  return (GtkWidget*)g_object_get_data (G_OBJECT (tab), "list");
+}
+
+static GtkWidget *
 ensure_group (GtkCombo    *combo,
               const gchar *group)
 {
@@ -1420,10 +1465,16 @@ ensure_group (GtkCombo    *combo,
       GtkWidget *image;
       GtkWidget *label;
       GtkWidget *item;
+      GtkWidget *scrolled_window;
 
       tab = frame = gtk_frame_new (NULL);
       gtk_widget_show (frame);
       g_object_set (frame, "margin", 10, NULL);
+      scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                      GTK_POLICY_NEVER,
+                                      GTK_POLICY_NEVER);
+      gtk_widget_show (scrolled_window);
       list = gtk_list_box_new ();
       gtk_widget_show (list);
       gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
@@ -1442,11 +1493,23 @@ ensure_group (GtkCombo    *combo,
       gtk_box_set_center_widget (GTK_BOX (box), label);
       gtk_container_add (GTK_CONTAINER (header), box);
       gtk_list_box_insert (GTK_LIST_BOX (list), header, -1);
-      gtk_container_add (GTK_CONTAINER (frame), list);
+
+      item = gtk_list_box_row_new ();
+      image = gtk_image_new_from_icon_name ("view-more-symbolic", GTK_ICON_SIZE_MENU);
+      g_object_set (image, "margin", 6, NULL);
+      gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
+      gtk_widget_set_valign (image, GTK_ALIGN_CENTER);
+      gtk_widget_show (image);
+      gtk_container_add (GTK_CONTAINER (item), image);
+      gtk_list_box_insert (GTK_LIST_BOX (list), item, -1);
+
+      gtk_container_add (GTK_CONTAINER (scrolled_window), list);
+      gtk_container_add (GTK_CONTAINER (frame), scrolled_window);
       gtk_stack_add_named (GTK_STACK (combo->stack), frame, group);
 
       g_object_set_data (G_OBJECT (header), "group", (gpointer)"list");
       g_object_set_data (G_OBJECT (tab), "list", list);
+      g_object_set_data (G_OBJECT (list), "show-more-item", item);
 
       g_signal_connect (list, "row-activated", G_CALLBACK (list_row_activated), combo);
       gtk_list_box_set_sort_func (GTK_LIST_BOX (list), list_sort_func, combo, NULL);
@@ -1495,4 +1558,5 @@ gtk_combo_add_with_group (GtkCombo    *combo,
 
   list = ensure_group (combo, group);
   add_to_list (list, id, sort, text);
+  collapse (combo, list, NULL);
 }


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