[gtk+/wip/matthiasc/help-overlay] Add section filtering by view



commit 821505dd47f263e6dbbcc00d0a1bb376d1dcf209
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Oct 13 07:40:08 2015 -0400

    Add section filtering by view
    
    This adds the "Show All" button that can be seen in the mockups.

 gtk/gtkshortcutsgroup.c          |   30 +++++++++++-
 gtk/gtkshortcutssection.c        |   91 +++++++++++++++++++++++++++++++++++---
 gtk/gtkshortcutssectionprivate.h |    2 +
 gtk/gtkshortcutswindow.c         |   49 +++++++++++++++++++-
 4 files changed, 159 insertions(+), 13 deletions(-)
---
diff --git a/gtk/gtkshortcutsgroup.c b/gtk/gtkshortcutsgroup.c
index 59c2012..ca8f3eb 100644
--- a/gtk/gtkshortcutsgroup.c
+++ b/gtk/gtkshortcutsgroup.c
@@ -30,6 +30,7 @@ struct _GtkShortcutsGroup
   GtkBox    parent_instance;
 
   GtkLabel *title;
+  gchar *view;
 };
 
 struct _GtkShortcutsGroupClass
@@ -42,6 +43,7 @@ G_DEFINE_TYPE (GtkShortcutsGroup, gtk_shortcuts_group, GTK_TYPE_BOX)
 enum {
   PROP_0,
   PROP_TITLE,
+  PROP_VIEW,
   LAST_PROP
 };
 
@@ -61,6 +63,10 @@ gtk_shortcuts_group_get_property (GObject    *object,
       g_value_set_string (value, gtk_label_get_label (self->title));
       break;
 
+    case PROP_VIEW:
+      g_value_set_string (value, self->view);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -80,23 +86,41 @@ gtk_shortcuts_group_set_property (GObject      *object,
       gtk_label_set_label (self->title, g_value_get_string (value));
       break;
 
+    case PROP_VIEW:
+      g_free (self->view);
+      self->view = g_value_dup_string (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
 }
 
 static void
+gtk_shortcuts_group_finalize (GObject *object)
+{
+  GtkShortcutsGroup *self = GTK_SHORTCUTS_GROUP (object);
+
+  g_free (self->view);
+
+  G_OBJECT_CLASS (gtk_shortcuts_group_parent_class)->finalize (object);
+}
+
+static void
 gtk_shortcuts_group_class_init (GtkShortcutsGroupClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->finalize = gtk_shortcuts_group_finalize;
   object_class->get_property = gtk_shortcuts_group_get_property;
   object_class->set_property = gtk_shortcuts_group_set_property;
 
   properties[PROP_TITLE] =
-    g_param_spec_string ("title",
-                         P_("Title"),
-                         P_("Title"),
+    g_param_spec_string ("title", P_("Title"), P_("Title"),
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  properties[PROP_VIEW] =
+    g_param_spec_string ("view", P_("View"), P_("View"),
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
diff --git a/gtk/gtkshortcutssection.c b/gtk/gtkshortcutssection.c
index c96c219..29cd57c 100644
--- a/gtk/gtkshortcutssection.c
+++ b/gtk/gtkshortcutssection.c
@@ -21,6 +21,8 @@
 #include "gtkshortcutssectionprivate.h"
 
 #include "gtkshortcutspageprivate.h"
+#include "gtkshortcutsgroupprivate.h"
+#include "gtktogglebutton.h"
 #include "gtkstack.h"
 #include "gtkstackswitcher.h"
 #include "gtkstylecontext.h"
@@ -34,10 +36,13 @@ struct _GtkShortcutsSection
 
   gchar            *name;
   gchar            *title;
+  gchar            *view_name;
 
   GtkStack         *stack;
   GtkStackSwitcher *switcher;
+  GtkWidget        *show_all;
 
+  gboolean          has_filtered_group;
   guint             last_page_num;
 };
 
@@ -52,6 +57,7 @@ enum {
   PROP_0,
   PROP_TITLE,
   PROP_SECTION_NAME,
+  PROP_VIEW_NAME,
   LAST_PROP
 };
 
@@ -124,6 +130,10 @@ gtk_shortcuts_section_get_property (GObject    *object,
       g_value_set_string (value, self->name);
       break;
 
+    case PROP_VIEW_NAME:
+      g_value_set_string (value, self->view_name);
+      break;
+
     case PROP_TITLE:
       g_value_set_string (value, self->title);
       break;
@@ -148,6 +158,10 @@ gtk_shortcuts_section_set_property (GObject      *object,
       self->name = g_value_dup_string (value);
       break;
 
+    case PROP_VIEW_NAME:
+      gtk_shortcuts_section_set_view_name (self, g_value_get_string (value));
+      break;
+
     case PROP_TITLE:
       g_free (self->title);
       self->title = g_value_dup_string (value);
@@ -171,16 +185,17 @@ gtk_shortcuts_section_class_init (GtkShortcutsSectionClass *klass)
   container_class->add = gtk_shortcuts_section_add;
 
   properties[PROP_SECTION_NAME] =
-    g_param_spec_string ("section-name",
-                         P_("Section Name"),
-                         P_("Section Name"),
+    g_param_spec_string ("section-name", P_("Section Name"), P_("Section Name"),
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_VIEW_NAME] =
+    g_param_spec_string ("view-name", P_("View Name"), P_("View Name"),
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   properties[PROP_TITLE] =
-    g_param_spec_string ("title",
-                         P_("Title"),
-                         P_("Title"),
+    g_param_spec_string ("title", P_("Title"), P_("Title"),
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
@@ -188,8 +203,44 @@ gtk_shortcuts_section_class_init (GtkShortcutsSectionClass *klass)
 }
 
 static void
+update_group_visibility (GtkWidget *child, gpointer data)
+{
+  GtkShortcutsSection *self = data;
+
+  if (GTK_IS_SHORTCUTS_GROUP (child))
+    {
+      gchar *view;
+      gboolean match;
+
+      g_object_get (child, "view", &view, NULL);
+      match = view == NULL || self->view_name == NULL ||
+              strcmp (view, self->view_name) == 0;
+
+      gtk_widget_set_visible (child,
+                              match || gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->show_all)));
+      self->has_filtered_group |= !match;
+
+      g_free (view);
+    }
+  else if (GTK_IS_CONTAINER (child))
+    {
+      gtk_container_foreach (GTK_CONTAINER (child), update_group_visibility, data);
+    }
+}
+
+static void
+filter_groups_by_view (GtkShortcutsSection *self)
+{
+  self->has_filtered_group = FALSE;
+  gtk_container_foreach (GTK_CONTAINER (self), update_group_visibility, self);
+  gtk_widget_set_visible (GTK_WIDGET (self->show_all), self->has_filtered_group);
+}
+
+static void
 gtk_shortcuts_section_init (GtkShortcutsSection *self)
 {
+  GtkWidget *box;
+
   gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
   gtk_box_set_homogeneous (GTK_BOX (self), FALSE);
   gtk_box_set_spacing (GTK_BOX (self), 22);
@@ -211,7 +262,19 @@ gtk_shortcuts_section_init (GtkShortcutsSection *self)
                                  NULL);
   gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self->switcher)), "round");
   gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (self->switcher)), "linked");
-  gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->switcher));
+
+  self->show_all = gtk_toggle_button_new_with_label (_("Show All"));
+  gtk_widget_set_no_show_all (self->show_all, TRUE);
+  g_signal_connect_swapped (self->show_all, "toggled",
+                            G_CALLBACK (filter_groups_by_view), self);
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 20);
+  gtk_widget_show (box);
+  gtk_container_add (GTK_CONTAINER (self), box);
+
+  gtk_box_set_center_widget (GTK_BOX (box), GTK_WIDGET (self->switcher));
+  gtk_box_pack_end (GTK_BOX (box), self->show_all, TRUE, TRUE, 0);
+  gtk_widget_set_halign (self->show_all, GTK_ALIGN_END);
 }
 
 const gchar *
@@ -229,3 +292,17 @@ gtk_shortcuts_section_get_title (GtkShortcutsSection *self)
 
   return self->title;
 }
+
+void
+gtk_shortcuts_section_set_view_name (GtkShortcutsSection *self,
+                                     const gchar         *view_name)
+{
+  g_return_if_fail (GTK_IS_SHORTCUTS_SECTION (self));
+
+  g_free (self->view_name);
+  self->view_name = g_strdup (view_name);
+
+  filter_groups_by_view (self);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VIEW_NAME]);
+}
diff --git a/gtk/gtkshortcutssectionprivate.h b/gtk/gtkshortcutssectionprivate.h
index 8ad21ec..776790b 100644
--- a/gtk/gtkshortcutssectionprivate.h
+++ b/gtk/gtkshortcutssectionprivate.h
@@ -39,6 +39,8 @@ GType        gtk_shortcuts_section_get_type (void) G_GNUC_CONST;
 
 const gchar *gtk_shortcuts_section_get_section_name (GtkShortcutsSection *self);
 const gchar *gtk_shortcuts_section_get_title        (GtkShortcutsSection *self);
+void         gtk_shortcuts_section_set_view_name    (GtkShortcutsSection *self,
+                                                     const gchar         *view_name);
 
 G_END_DECLS
 
diff --git a/gtk/gtkshortcutswindow.c b/gtk/gtkshortcutswindow.c
index 19068e1..e0104d5 100644
--- a/gtk/gtkshortcutswindow.c
+++ b/gtk/gtkshortcutswindow.c
@@ -47,6 +47,7 @@ typedef struct
   GHashTable     *keywords;
   gchar          *initial_section;
   gchar          *last_section_name;
+  gchar          *view_name;
   GtkSizeGroup   *search_text_group;
   GtkSizeGroup   *search_image_group;
   GHashTable     *search_items_hash;
@@ -89,6 +90,7 @@ enum {
 enum {
   PROP_0,
   PROP_SECTION_NAME,
+  PROP_VIEW_NAME,
   LAST_PROP
 };
 
@@ -107,6 +109,7 @@ gtk_shortcuts_window_add_section (GtkShortcutsWindow  *self,
 
   name = gtk_shortcuts_section_get_section_name (section);
   title = gtk_shortcuts_section_get_title (section);
+  gtk_shortcuts_section_set_view_name (section, priv->view_name);
 
   gtk_stack_add_titled (priv->stack, GTK_WIDGET (section), name, title);
 
@@ -136,6 +139,27 @@ gtk_shortcuts_window_add (GtkContainer *container,
     GTK_CONTAINER_CLASS (gtk_shortcuts_window_parent_class)->add (container, widget);
 }
 
+static void
+gtk_shortcuts_window_set_view_name (GtkShortcutsWindow *self,
+                                    const gchar        *view_name)
+{
+  GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
+  GList *sections, *l;
+
+  g_free (priv->view_name);
+  priv->view_name = g_strdup (view_name);
+
+  sections = gtk_container_get_children (GTK_CONTAINER (priv->stack));
+  for (l = sections; l; l = l->next)
+    {
+      GtkShortcutsSection *section = l->data;
+
+      if (GTK_IS_SHORTCUTS_SECTION (section))
+        gtk_shortcuts_section_set_view_name (section, priv->view_name);
+    }
+  g_list_free (sections);
+}
+
 static gint
 number_of_children (GtkContainer *container)
 {
@@ -443,11 +467,19 @@ sections_parser_start_element (GMarkupParseContext  *context,
     }
   else if (g_strcmp0 (element_name, "group") == 0)
     {
+      const gchar *view = NULL;
+
       if (!check_parent (context, "column", error))
         return;
 
+      if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
+                                        G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "view", &view,
+                                        G_MARKUP_COLLECT_INVALID))
+        return;
+
       item = g_object_new (GTK_TYPE_SHORTCUTS_GROUP,
                            "visible", TRUE,
+                           "view", view,
                            NULL);
       g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
     }
@@ -742,6 +774,7 @@ gtk_shortcuts_window_finalize (GObject *object)
 
   g_clear_pointer (&priv->keywords, g_hash_table_unref);
   g_clear_pointer (&priv->initial_section, g_free);
+  g_clear_pointer (&priv->view_name, g_free);
   g_clear_pointer (&priv->last_section_name, g_free);
   g_clear_pointer (&priv->search_items_hash, g_hash_table_unref);
 
@@ -785,6 +818,10 @@ gtk_shortcuts_window_get_property (GObject    *object,
       }
       break;
 
+    case PROP_VIEW_NAME:
+      g_value_set_string (value, priv->view_name);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -807,6 +844,10 @@ gtk_shortcuts_window_set_property (GObject      *object,
       gtk_stack_set_visible_child_name (priv->stack, g_value_get_string (value));
       break;
 
+    case PROP_VIEW_NAME:
+      gtk_shortcuts_window_set_view_name (self, g_value_get_string (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -829,9 +870,11 @@ gtk_shortcuts_window_class_init (GtkShortcutsWindowClass *klass)
   klass->close = gtk_shortcuts_window_real_close;
 
   properties[PROP_SECTION_NAME] =
-    g_param_spec_string ("section-name",
-                         P_("View Name"),
-                         P_("View Name"),
+    g_param_spec_string ("section-name", P_("Section Name"), P_("Section Name"),
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  properties[PROP_VIEW_NAME] =
+    g_param_spec_string ("view-name", P_("View Name"), P_("View Name"),
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 


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