summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2014-04-26 01:22:29 -0400
committerTristan Van Berkom <tristan@upstairslabs.com>2014-11-07 17:20:22 +0900
commit15b4f639031995ef4e0c0a7c600b23533786b239 (patch)
tree62b2ba657bfbf21d47a0fa4fd217a9ff633bae07
parent9d373e1293443854bf1f0baa1290bc6fc8d202d4 (diff)
downloadglade-15b4f639031995ef4e0c0a7c600b23533786b239.tar.gz
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
-rw-r--r--plugins/gtk+/Makefile.am1
-rw-r--r--plugins/gtk+/glade-gtk-header-bar.c326
-rw-r--r--plugins/gtk+/gtk+.xml.in42
-rw-r--r--plugins/gtk+/icons/16x16/Makefile.am1
-rw-r--r--plugins/gtk+/icons/16x16/widget-gtk-headerbar.pngbin0 -> 186 bytes
-rw-r--r--plugins/gtk+/icons/22x22/Makefile.am1
-rw-r--r--plugins/gtk+/icons/22x22/widget-gtk-headerbar.pngbin0 -> 200 bytes
7 files changed, 370 insertions, 1 deletions
diff --git a/plugins/gtk+/Makefile.am b/plugins/gtk+/Makefile.am
index 99b1978e..3b4701d1 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 00000000..5d8ef44a
--- /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 66ebf32f..b3a2ebe3 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 1ff862ae..7ea1da10 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 00000000..dd3cffb9
--- /dev/null
+++ b/plugins/gtk+/icons/16x16/widget-gtk-headerbar.png
Binary files differ
diff --git a/plugins/gtk+/icons/22x22/Makefile.am b/plugins/gtk+/icons/22x22/Makefile.am
index e80866fc..411d6cd0 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 00000000..087aceb3
--- /dev/null
+++ b/plugins/gtk+/icons/22x22/widget-gtk-headerbar.png
Binary files differ