[glade/headerbar] Initial GtkHeaderBar support



commit 2885d55a7c53f565a9d81388e62dccc556dd77e0
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Apr 26 01:22:29 2014 -0400

    Initial GtkHeaderBar support
    
    Add support for GtkHeaderBar. Based on a patch by John Stowers.
    This allows setting custom titles, and adding multiple children
    at either end of the header bar. Repositioning children is not
    really working, due to limitations of the GtkHeaderBar API.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=700914

 plugins/gtk+/Makefile.am                          |    1 +
 plugins/gtk+/glade-gtk-header-bar.c               |  326 +++++++++++++++++++++
 plugins/gtk+/gtk+.xml.in                          |   42 +++-
 plugins/gtk+/icons/16x16/Makefile.am              |    1 +
 plugins/gtk+/icons/16x16/widget-gtk-headerbar.png |  Bin 0 -> 186 bytes
 plugins/gtk+/icons/22x22/Makefile.am              |    1 +
 plugins/gtk+/icons/22x22/widget-gtk-headerbar.png |  Bin 0 -> 200 bytes
 7 files changed, 370 insertions(+), 1 deletions(-)
---
diff --git a/plugins/gtk+/Makefile.am b/plugins/gtk+/Makefile.am
index 6f17c31..86924b6 100644
--- a/plugins/gtk+/Makefile.am
+++ b/plugins/gtk+/Makefile.am
@@ -117,6 +117,7 @@ libgladegtk_la_SOURCES =            \
        glade-gtk-viewport.c            \
        glade-gtk-widget.c              \
        glade-gtk-window.c              \
+       glade-gtk-header-bar.c          \
        glade-icon-factory-editor.c     \
        glade-icon-sources.c            \
        glade-icon-view-editor.c        \
diff --git a/plugins/gtk+/glade-gtk-header-bar.c b/plugins/gtk+/glade-gtk-header-bar.c
new file mode 100644
index 0000000..5d8ef44
--- /dev/null
+++ b/plugins/gtk+/glade-gtk-header-bar.c
@@ -0,0 +1,326 @@
+#include <config.h>
+#include <glib/gi18n-lib.h>
+#include <gladeui/glade.h>
+#include "glade-gtk.h"
+
+static gint
+glade_gtk_header_bar_get_num_children (GObject *hb, GtkPackType type)
+{
+  GList *children, *l;
+  GtkPackType pt;
+  gint num;
+  GtkWidget *custom_title;
+
+  custom_title = gtk_header_bar_get_custom_title (GTK_HEADER_BAR (hb));
+
+  num = 0;
+
+  children = gtk_container_get_children (GTK_CONTAINER (hb));
+  for (l = children; l; l = l->next)
+    {
+      if (l->data == custom_title)
+        continue;
+      gtk_container_child_get (GTK_CONTAINER (hb), GTK_WIDGET (l->data), "pack-type", &pt, NULL);
+      if (type == pt)
+        num++;
+    }
+  g_list_free (children);
+
+  return num;
+}
+
+static void
+glade_gtk_header_bar_parse_finished (GladeProject * project, GObject * object)
+{
+  GladeWidget *gbox;
+
+  gbox = glade_widget_get_from_gobject (object);
+  glade_widget_property_set (gbox, "start-size", glade_gtk_header_bar_get_num_children (object, 
GTK_PACK_START));
+  glade_widget_property_set (gbox, "end-size", glade_gtk_header_bar_get_num_children (object, GTK_PACK_END));
+  glade_widget_property_set (gbox, "use-custom-title", gtk_header_bar_get_custom_title (GTK_HEADER_BAR 
(object)) != NULL);
+}
+
+void glade_gtk_header_bar_post_create(GladeWidgetAdaptor *adaptor, GObject *container, GladeCreateReason 
reason) {
+  GladeWidget *parent = glade_widget_get_from_gobject (container);
+  GladeProject *project = glade_widget_get_project (parent);
+
+  if (reason == GLADE_CREATE_LOAD)
+    {
+      g_signal_connect (project, "parse-finished",
+                        G_CALLBACK (glade_gtk_header_bar_parse_finished),
+                        container);
+    }
+  else if (reason == GLADE_CREATE_USER)
+    {
+      gtk_header_bar_pack_start( GTK_HEADER_BAR(container), glade_placeholder_new() );
+      gtk_header_bar_pack_end( GTK_HEADER_BAR(container), glade_placeholder_new() );
+    }
+}
+
+void glade_gtk_header_bar_add_child(GladeWidgetAdaptor *adaptor, GObject *parent, GObject *child) {
+  GladeWidget *gbox, *gchild;
+  GtkPackType pack_type;
+  gint num_children;
+  gchar *special_child_type;
+  special_child_type = g_object_get_data (child, "special-child-type");
+  if (special_child_type && !strcmp (special_child_type, "title"))
+    {
+      gtk_header_bar_set_custom_title (GTK_HEADER_BAR (parent), GTK_WIDGET (child));
+      return;
+    }
+
+    // check if its a placeholder bein added, and add it to the end if anything is at the start
+    if (GLADE_IS_PLACEHOLDER(child)) {
+        GList *list = gtk_container_get_children(GTK_CONTAINER(parent));
+        GList *l;
+        if (list) {
+            for(l = list; l; l = g_list_next(l)) {
+                GObject *c = l->data;
+                GtkPackType t;
+                gtk_container_child_get( GTK_CONTAINER(parent), GTK_WIDGET(c), "pack-type", &t, NULL);
+                if (t == GTK_PACK_START) {
+                    gtk_header_bar_pack_end( GTK_HEADER_BAR(parent), GTK_WIDGET(child) );
+                    g_list_free(list);
+                    return;
+                }
+            }
+            g_list_free(list);
+        }
+    }
+    GWA_GET_CLASS (GTK_TYPE_CONTAINER)->add(adaptor, parent, child);
+  
+  gbox = glade_widget_get_from_gobject (parent);
+
+  gtk_container_child_get (GTK_CONTAINER (parent), GTK_WIDGET (child), "pack-type", &pack_type, NULL);
+  num_children = glade_gtk_header_bar_get_num_children (parent, pack_type);
+  if (pack_type == GTK_PACK_START)
+    glade_widget_property_set (gbox, "start-size", num_children);
+  else
+    glade_widget_property_set (gbox, "end-size", num_children);
+
+  gchild = glade_widget_get_from_gobject (child);
+  if (gchild)
+    glade_widget_set_pack_action_visible (gchild, "remove_slot", FALSE);
+
+}
+
+void
+glade_gtk_header_bar_child_insert_remove_action (GladeWidgetAdaptor * adaptor,
+                                                 GObject * container,
+                                                 GObject * object,
+                                                 const gchar * group_format,
+                                                 gboolean remove,
+                                                 GtkPackType pack_type)
+{
+  GladeWidget *parent;
+
+  parent = glade_widget_get_from_gobject (container);
+  glade_command_push_group (group_format, glade_widget_get_name (parent));
+
+  if (remove)
+    gtk_container_remove (GTK_CONTAINER (container), GTK_WIDGET (object));
+  else if (pack_type == GTK_PACK_START)
+    gtk_header_bar_pack_start (GTK_HEADER_BAR (container), glade_placeholder_new ());
+  else
+    gtk_header_bar_pack_end (GTK_HEADER_BAR (container), glade_placeholder_new ());
+
+  glade_command_pop_group ();
+}
+
+void
+glade_gtk_header_bar_child_action_activate (GladeWidgetAdaptor * adaptor,
+                                            GObject * container,
+                                            GObject * object,
+                                            const gchar * action_path)
+{
+  if (strcmp (action_path, "add_start") == 0)
+    {
+      glade_gtk_header_bar_child_insert_remove_action (adaptor, container, object,
+                                                       _("Insert placeholder to %s"),
+                                                        FALSE, GTK_PACK_START);
+    }
+  else if (strcmp (action_path, "add_end") == 0)
+    {
+      glade_gtk_header_bar_child_insert_remove_action (adaptor, container, object,
+                                                       _("Insert placeholder to %s"),
+                                                        FALSE, GTK_PACK_END);
+    }
+  else if (strcmp (action_path, "remove_slot") == 0)
+    {
+      glade_gtk_header_bar_child_insert_remove_action (adaptor, container, object,
+                                                       _("Remove placeholder from %s"),
+                                                       TRUE, GTK_PACK_START);
+    }
+  else
+    GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_action_activate (adaptor,
+                                                               container,
+                                                               object,
+                                                               action_path);
+}
+
+void
+glade_gtk_header_bar_get_property (GladeWidgetAdaptor * adaptor,
+                            GObject * object, const gchar * id, GValue * value)
+{
+  if (!strcmp (id, "use-custom-title"))
+    {
+      g_value_reset (value);
+      g_value_set_boolean (value, gtk_header_bar_get_custom_title (GTK_HEADER_BAR (object)) != NULL);
+    }
+  else if (!strcmp (id, "start-size"))
+    {
+      g_value_reset (value);
+       g_value_set_int (value, glade_gtk_header_bar_get_num_children (object, GTK_PACK_START));
+    }
+  else if (!strcmp (id, "end-size"))
+    {
+      g_value_reset (value);
+      g_value_set_int (value, glade_gtk_header_bar_get_num_children (object, GTK_PACK_END));
+    }
+  else
+    GWA_GET_CLASS (GTK_TYPE_CONTAINER)->get_property (adaptor, object, id,
+                                                      value);
+}
+
+static void
+glade_gtk_header_bar_set_size (GObject * object, const GValue * value, GtkPackType type)
+{
+  GList *l, *next, *children;
+  GtkWidget *child;
+  guint new_size, old_size, i;
+  GtkPackType pt;
+
+  g_return_if_fail (GTK_IS_HEADER_BAR (object));
+
+  if (glade_util_object_is_loading (object))
+    return;
+
+  children = gtk_container_get_children (GTK_CONTAINER (object));
+  l = children;
+  while (l)
+    {
+      next = l->next;
+      gtk_container_child_get (GTK_CONTAINER (object), GTK_WIDGET (l->data), "pack-type", &pt, NULL);
+      if (type != pt || l->data == gtk_header_bar_get_custom_title (GTK_HEADER_BAR (object)))
+        children = g_list_delete_link (children, l);
+      l = next;
+    }
+ 
+  old_size = g_list_length (children);
+  new_size = g_value_get_int (value);
+
+  if (old_size == new_size)
+    {
+      g_list_free (children);
+      return;
+    }
+
+  for (i = 0; i < new_size; i++)
+    {
+      if (g_list_length (children) < i + 1)
+        {
+          GtkWidget *placeholder = glade_placeholder_new ();
+          if (type == GTK_PACK_START)
+            gtk_header_bar_pack_start (GTK_HEADER_BAR (object), placeholder);
+          else
+            gtk_header_bar_pack_end (GTK_HEADER_BAR (object), placeholder);
+        }
+    }
+  for (l = g_list_last (children); l && old_size > new_size; l = l->prev)
+    {
+      child = l->data;
+      if (glade_widget_get_from_gobject (child) ||
+          !GLADE_IS_PLACEHOLDER (child))
+        continue;
+
+      g_object_ref (G_OBJECT (child));
+      gtk_container_remove (GTK_CONTAINER (object), child);
+      gtk_widget_destroy (child);
+      old_size--;
+    }
+
+  g_list_free (children);
+}
+
+void
+glade_gtk_header_bar_set_property (GladeWidgetAdaptor * adaptor,
+                            GObject * object,
+                            const gchar * id, const GValue * value)
+{
+  if (!strcmp (id, "use-custom-title"))
+    {
+      GtkWidget *child;
+
+      if (g_value_get_boolean (value))
+        {
+          child = gtk_header_bar_get_custom_title (GTK_HEADER_BAR (object));
+          if (!child)
+            child = glade_placeholder_new ();
+          g_object_set_data (G_OBJECT (child), "special-child-type", "title");
+        }
+      else
+        child = NULL;
+
+      gtk_header_bar_set_custom_title (GTK_HEADER_BAR (object), child);
+    }
+  else if (!strcmp (id, "start-size"))
+    glade_gtk_header_bar_set_size (object, value, GTK_PACK_START);
+  else if (!strcmp (id, "end-size"))
+    glade_gtk_header_bar_set_size (object, value, GTK_PACK_END);
+  else
+    GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object, id,
+                                                      value);
+}
+
+void
+glade_gtk_header_bar_remove_child (GladeWidgetAdaptor * adaptor,
+                            GObject * object, GObject * child)
+{
+  GladeWidget *gbox;
+  gint num_children;
+  GtkPackType pack_type;
+  gchar *special_child_type;
+
+  special_child_type = g_object_get_data (child, "special-child-type");
+  if (special_child_type && !strcmp (special_child_type, "title"))
+    {
+      gtk_header_bar_set_custom_title (GTK_HEADER_BAR (object), glade_placeholder_new ());
+      return;
+    }
+  
+  gbox = glade_widget_get_from_gobject (object);
+
+  gtk_container_child_get (GTK_CONTAINER (object), GTK_WIDGET (child), "pack-type", &pack_type, NULL);
+
+  gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
+
+  if (!glade_widget_superuser ())
+    {
+      num_children = glade_gtk_header_bar_get_num_children (object, pack_type);
+      glade_widget_property_set (gbox, "start-size", num_children);
+    }
+}
+
+void
+glade_gtk_header_bar_replace_child (GladeWidgetAdaptor * adaptor,
+                             GObject * container,
+                             GObject * current, GObject * new_widget)
+{
+  gchar *special_child_type;
+
+  special_child_type =
+      g_object_get_data (G_OBJECT (current), "special-child-type");
+
+  if (special_child_type && !strcmp (special_child_type, "title"))
+    {
+      g_object_set_data (G_OBJECT (new_widget), "special-child-type", "title");
+      gtk_header_bar_set_custom_title (GTK_HEADER_BAR (container), GTK_WIDGET (new_widget));
+      return;
+    }
+
+  GWA_GET_CLASS
+      (GTK_TYPE_CONTAINER)->replace_child (adaptor,
+                                           G_OBJECT (container),
+                                           G_OBJECT (current),
+                                           G_OBJECT (new_widget));
+}
diff --git a/plugins/gtk+/gtk+.xml.in b/plugins/gtk+/gtk+.xml.in
index bf5b006..f71bdc4 100644
--- a/plugins/gtk+/gtk+.xml.in
+++ b/plugins/gtk+/gtk+.xml.in
@@ -2367,7 +2367,46 @@
           <property id="tab-label" disabled="True"/>
         </packing-properties>
       </glade-widget-class>
-      
+     
+    <glade-widget-class name="GtkHeaderBar" generic-name="headerbar" _title="HeaderBar" since="3.10">
+      <post-create-function>glade_gtk_header_bar_post_create</post-create-function>
+      <add-child-function>glade_gtk_header_bar_add_child</add-child-function>
+      
<child-action-activate-function>glade_gtk_header_bar_child_action_activate</child-action-activate-function>
+      <set-property-function>glade_gtk_header_bar_set_property</set-property-function>
+      <get-property-function>glade_gtk_header_bar_get_property</get-property-function>
+      <add-child-function>glade_gtk_header_bar_add_child</add-child-function>
+      <remove-child-function>glade_gtk_header_bar_remove_child</remove-child-function>
+      <replace-child-function>glade_gtk_header_bar_replace_child</replace-child-function>
+      <special-child-type>type</special-child-type>
+      <properties>
+        <property id="custom-title" disabled="True"/>
+        <property id="use-custom-title" _name="Custom Title" default="FALSE" visible="True" save="False">
+          <parameter-spec>
+            <type>GParamBoolean</type>
+          </parameter-spec>
+        </property>
+        <property visible="True" save="False" id="start-size" default="1" _name="Number of items at the 
start">
+          <parameter-spec>
+            <type>GParamInt</type>
+            <min>0</min>
+          </parameter-spec>
+          <_tooltip>The number of items at the start</_tooltip>
+        </property>
+        <property visible="True" save="False" id="end-size" default="1" _name="Number of items at the end">
+          <parameter-spec>
+            <type>GParamInt</type>
+            <min>0</min>
+          </parameter-spec>
+          <_tooltip>The number of items at the end</_tooltip>
+        </property>
+      </properties>
+      <packing-actions>
+        <action id="add_start" _name="Add Slot at start" stock="gtk-add"/>
+        <action id="add_end" _name="Add Slot at end" stock="gtk-add"/>
+        <action id="remove_slot" _name="Remove Slot" stock="gtk-remove"/>
+      </packing-actions>
+    </glade-widget-class>
+
       <glade-widget-class name="GtkRevealer" generic-name="revealer" _title="Revealer" since="3.10">
         <post-create-function>glade_gtk_revealer_post_create</post-create-function>
         <properties>
@@ -5141,6 +5180,7 @@
       <glade-widget-class-ref name="GtkScrolledWindow"/>
       <glade-widget-class-ref name="GtkAlignment"/>
       <glade-widget-class-ref name="GtkRevealer" />
+      <glade-widget-class-ref name="GtkHeaderBar" />
     </glade-widget-group>
     
     <glade-widget-group name="gtk-control-display" _title="Control and Display">
diff --git a/plugins/gtk+/icons/16x16/Makefile.am b/plugins/gtk+/icons/16x16/Makefile.am
index baaeba7..e25ea57 100644
--- a/plugins/gtk+/icons/16x16/Makefile.am
+++ b/plugins/gtk+/icons/16x16/Makefile.am
@@ -54,6 +54,7 @@ icons_DATA = \
        widget-gtk-handlebox.png \
        widget-gtk-hbox.png \
        widget-gtk-hbuttonbox.png \
+       widget-gtk-headerbar.png \
        widget-gtk-hpaned.png \
        widget-gtk-hscale.png \
        widget-gtk-hscrollbar.png \
diff --git a/plugins/gtk+/icons/16x16/widget-gtk-headerbar.png 
b/plugins/gtk+/icons/16x16/widget-gtk-headerbar.png
new file mode 100644
index 0000000..dd3cffb
Binary files /dev/null and b/plugins/gtk+/icons/16x16/widget-gtk-headerbar.png differ
diff --git a/plugins/gtk+/icons/22x22/Makefile.am b/plugins/gtk+/icons/22x22/Makefile.am
index ff45e33..fa5600b 100644
--- a/plugins/gtk+/icons/22x22/Makefile.am
+++ b/plugins/gtk+/icons/22x22/Makefile.am
@@ -54,6 +54,7 @@ icons_DATA = \
        widget-gtk-handlebox.png \
        widget-gtk-hbox.png \
        widget-gtk-hbuttonbox.png \
+       widget-gtk-headerbar.png \
        widget-gtk-hpaned.png \
        widget-gtk-hscale.png \
        widget-gtk-hscrollbar.png \
diff --git a/plugins/gtk+/icons/22x22/widget-gtk-headerbar.png 
b/plugins/gtk+/icons/22x22/widget-gtk-headerbar.png
new file mode 100644
index 0000000..087aceb
Binary files /dev/null and b/plugins/gtk+/icons/22x22/widget-gtk-headerbar.png differ


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