[glade/headerbar: 1/7] Initial GtkHeaderBar support



commit 47ee8d1aaa971251826c84a2558c19f7c48f2b76
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 99b1978..3b4701d 100644
--- a/plugins/gtk+/Makefile.am
+++ b/plugins/gtk+/Makefile.am
@@ -118,6 +118,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 66ebf32..b3a2ebe 100644
--- a/plugins/gtk+/gtk+.xml.in
+++ b/plugins/gtk+/gtk+.xml.in
@@ -2399,7 +2399,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>
@@ -5176,6 +5215,7 @@
       <glade-widget-class-ref name="GtkAlignment"/>
       <glade-widget-class-ref name="GtkRevealer" />
       <glade-widget-class-ref name="GtkSearchBar" />
+      <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 1ff862a..7ea1da1 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 e80866f..411d6cd 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]