gtk+ r19726 - in trunk: . docs/reference/gtk/tmpl gtk tests
- From: johan svn gnome org
- To: svn-commits-list gnome org
- Subject: gtk+ r19726 - in trunk: . docs/reference/gtk/tmpl gtk tests
- Date: Fri, 7 Mar 2008 00:08:17 +0000 (GMT)
Author: johan
Date: Fri Mar 7 00:08:16 2008
New Revision: 19726
URL: http://svn.gnome.org/viewvc/gtk+?rev=19726&view=rev
Log:
2008-03-06 Johan Dahlin <jdahlin async com br>
* docs/reference/gtk/tmpl/gtkiconfactory.sgml:
* gtk/gtkbuilder.c:
* gtk/gtkbuilderprivate.h:
* gtk/gtkiconfactory.c:
* tests/buildertest.c:
Implement GtkBuildable on GtkIconFactory, to make
it possible to register custom stock icons.
Fixes #517066
Modified:
trunk/ChangeLog
trunk/docs/reference/gtk/tmpl/gtkiconfactory.sgml
trunk/gtk/gtkbuilder.c
trunk/gtk/gtkbuilderprivate.h
trunk/gtk/gtkiconfactory.c
trunk/tests/buildertest.c
Modified: trunk/docs/reference/gtk/tmpl/gtkiconfactory.sgml
==============================================================================
--- trunk/docs/reference/gtk/tmpl/gtkiconfactory.sgml (original)
+++ trunk/docs/reference/gtk/tmpl/gtkiconfactory.sgml Fri Mar 7 00:08:16 2008
@@ -35,6 +35,77 @@
looking up the icon to use for a given stock ID.
</para>
+<refsect2 id="GtkIconFactory-BUILDER-UI"><title>GtkIconFactory as GtkBuildable</title>
+<para>
+GtkIconFactory supports a custom <sources> element, which
+can contain multiple <source> elements.
+The following attributes are allowed:
+<variablelist>
+
+<varlistentry>
+<term>stock-id</term>
+<listitem><para>The stock id of the source, a string.
+This attribute is mandatory</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term>filename</term>
+<listitem><para>The filename of the source, a string.
+This attribute is mandatory</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>icon-name</term>
+<listitem><para>The icon name for the source, a string.
+This attribute is optional.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>size</term>
+<listitem><para>Size of the icon, a #GtkIconSize enum value.
+This attribute is optional.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>direction</term>
+<listitem><para>Direction of the source, a #GtkTextDirection enum value.
+This attribute is optional.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>state</term>
+<listitem><para>State of the source, a #GtkStateType enum value.
+This attribute is optional.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+<example>
+<title>A <structname>GtkIconFactory</structname> UI definition fragment.</title>
+<programlisting><![CDATA[
+<object class="GtkIconFactory" id="iconfactory1">
+ <sources>
+ <source stock-id="apple-red" filename="apple-red.png"/>
+ </sources>
+</object>
+<object class="GtkWindow" id="window1">
+ <child>
+ <object class="GtkButton" id="apple_button">
+ <property name="label">apple-red</property>
+ <property name="use-stock">True</property>
+ </object>
+ </child>
+</object>
+]]></programlisting>
+</example>
+</refsect2>
+
<!-- ##### SECTION See_Also ##### -->
<para>
Modified: trunk/gtk/gtkbuilder.c
==============================================================================
--- trunk/gtk/gtkbuilder.c (original)
+++ trunk/gtk/gtkbuilder.c Fri Mar 7 00:08:16 2008
@@ -1234,18 +1234,7 @@
return FALSE;
}
- if (g_path_is_absolute (string))
- filename = g_strdup (string);
- else
- {
- gchar *dirname;
-
- dirname = g_path_get_dirname (builder->priv->filename);
- filename = g_build_filename (dirname, string, NULL);
-
- g_free (dirname);
- }
-
+ filename = _gtk_builder_get_absolute_filename (builder, string);
pixbuf = gdk_pixbuf_new_from_file (filename, &tmp_error);
if (pixbuf == NULL)
@@ -1466,6 +1455,26 @@
return g_quark_from_static_string ("gtk-builder-error-quark");
}
+gchar *
+_gtk_builder_get_absolute_filename (GtkBuilder *builder, const gchar *string)
+{
+ gchar *filename;
+ gchar *dirname = NULL;
+
+ if (g_path_is_absolute (string))
+ return g_strdup (string);
+
+ if (builder->priv->filename &&
+ strcmp (builder->priv->filename, ".") != 0)
+ dirname = g_path_get_dirname (builder->priv->filename);
+ else
+ dirname = g_get_current_dir ();
+
+ filename = g_build_filename (dirname, string, NULL);
+ g_free (dirname);
+
+ return filename;
+}
#define __GTK_BUILDER_C__
#include "gtkaliasdef.c"
Modified: trunk/gtk/gtkbuilderprivate.h
==============================================================================
--- trunk/gtk/gtkbuilderprivate.h (original)
+++ trunk/gtk/gtkbuilderprivate.h Fri Mar 7 00:08:16 2008
@@ -125,5 +125,7 @@
gchar * _gtk_builder_parser_translate (const gchar *domain,
const gchar *context,
const gchar *text);
+gchar * _gtk_builder_get_absolute_filename (GtkBuilder *builder,
+ const gchar *string);
#endif /* __GTK_BUILDER_PRIVATE_H__ */
Modified: trunk/gtk/gtkiconfactory.c
==============================================================================
--- trunk/gtk/gtkiconfactory.c (original)
+++ trunk/gtk/gtkiconfactory.c Fri Mar 7 00:08:16 2008
@@ -1,6 +1,6 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2000 Red Hat, Inc.
- *
+ * 2008 Johan Dahlin
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -37,6 +37,8 @@
#include "gtkstock.h"
#include "gtkwidget.h"
#include "gtkintl.h"
+#include "gtkbuildable.h"
+#include "gtkbuilderprivate.h"
#include "gtkalias.h"
@@ -83,6 +85,20 @@
};
+static void
+gtk_icon_factory_buildable_init (GtkBuildableIface *iface);
+
+static gboolean gtk_icon_factory_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data);
+static void gtk_icon_factory_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *user_data);
static void gtk_icon_factory_finalize (GObject *object);
static void get_default_icons (GtkIconFactory *icon_factory);
static void icon_source_clear (GtkIconSource *source);
@@ -96,7 +112,9 @@
0, 0, 0, \
any_direction, any_state, any_size }
-G_DEFINE_TYPE (GtkIconFactory, gtk_icon_factory, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (GtkIconFactory, gtk_icon_factory, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ gtk_icon_factory_buildable_init))
static void
gtk_icon_factory_init (GtkIconFactory *factory)
@@ -114,6 +132,13 @@
}
static void
+gtk_icon_factory_buildable_init (GtkBuildableIface *iface)
+{
+ iface->custom_tag_start = gtk_icon_factory_buildable_custom_tag_start;
+ iface->custom_tag_end = gtk_icon_factory_buildable_custom_tag_end;
+}
+
+static void
free_icon_set (gpointer key, gpointer value, gpointer data)
{
g_free (key);
@@ -2700,6 +2725,204 @@
return ids;
}
+typedef struct {
+ GSList *sources;
+ gboolean in_source;
+
+} IconFactoryParserData;
+
+typedef struct {
+ gchar *stock_id;
+ gchar *filename;
+ gchar *icon_name;
+ GtkTextDirection direction;
+ GtkIconSize size;
+ GtkStateType state;
+} IconSourceParserData;
+
+static void
+icon_source_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ gint i;
+ gchar *stock_id = NULL;
+ gchar *filename = NULL;
+ gchar *icon_name = NULL;
+ GtkIconSize size = -1;
+ GtkTextDirection direction = -1;
+ GtkStateType state = -1;
+ IconFactoryParserData *parser_data;
+ IconSourceParserData *source_data;
+
+ parser_data = (IconFactoryParserData*)user_data;
+
+ if (!parser_data->in_source)
+ {
+ if (strcmp (element_name, "sources") != 0)
+ {
+ g_warning ("Unexpected element %s, expected <sources>", element_name);
+ return;
+ }
+ parser_data->in_source = TRUE;
+ return;
+ }
+ else
+ {
+ if (strcmp (element_name, "source") != 0)
+ {
+ g_warning ("Unexpected element %s, expected <source>", element_name);
+ return;
+ }
+ }
+
+ for (i = 0; names[i]; i++)
+ {
+ if (strcmp (names[i], "stock-id") == 0)
+ stock_id = g_strdup (values[i]);
+ else if (strcmp (names[i], "filename") == 0)
+ filename = g_strdup (values[i]);
+ else if (strcmp (names[i], "icon-name") == 0)
+ icon_name = g_strdup (values[i]);
+ else if (strcmp (names[i], "size") == 0)
+ {
+ if (!_gtk_builder_flags_from_string (GTK_TYPE_ICON_SIZE,
+ values[i],
+ &size,
+ error))
+ return;
+ }
+ else if (strcmp (names[i], "direction") == 0)
+ {
+ if (!_gtk_builder_flags_from_string (GTK_TYPE_TEXT_DIRECTION,
+ values[i],
+ &direction,
+ error))
+ return;
+ }
+ else if (strcmp (names[i], "state") == 0)
+ {
+ if (!_gtk_builder_flags_from_string (GTK_TYPE_STATE_TYPE,
+ values[i],
+ &state,
+ error))
+ return;
+ }
+ }
+
+ if (!stock_id || !filename)
+ {
+ g_warning ("<source> requires a stock_id and a filename");
+ return;
+ }
+
+ source_data = g_slice_new (IconSourceParserData);
+ source_data->stock_id = stock_id;
+ source_data->filename = filename;
+ source_data->icon_name = icon_name;
+ source_data->size = size;
+ source_data->direction = direction;
+ source_data->state = state;
+
+ parser_data->sources = g_slist_prepend (parser_data->sources, source_data);
+}
+
+static const GMarkupParser icon_source_parser =
+ {
+ icon_source_start_element,
+ };
+
+static gboolean
+gtk_icon_factory_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data)
+{
+ g_assert (buildable);
+
+ if (strcmp (tagname, "sources") == 0)
+ {
+ IconFactoryParserData *parser_data;
+
+ parser_data = g_slice_new0 (IconFactoryParserData);
+ *parser = icon_source_parser;
+ *data = parser_data;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+gtk_icon_factory_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *user_data)
+{
+ GtkIconFactory *icon_factory;
+
+ icon_factory = GTK_ICON_FACTORY (buildable);
+
+ if (strcmp (tagname, "sources") == 0)
+ {
+ IconFactoryParserData *parser_data;
+ GtkIconSource *icon_source;
+ GtkIconSet *icon_set;
+ GSList *l;
+
+ parser_data = (IconFactoryParserData*)user_data;
+
+ for (l = parser_data->sources; l; l = l->next)
+ {
+ IconSourceParserData *source_data = l->data;
+
+ icon_set = gtk_icon_factory_lookup (icon_factory, source_data->stock_id);
+ if (!icon_set)
+ {
+ icon_set = gtk_icon_set_new ();
+ gtk_icon_factory_add (icon_factory, source_data->stock_id, icon_set);
+ }
+
+ icon_source = gtk_icon_source_new ();
+
+ if (source_data->filename)
+ {
+ gchar *filename;
+ filename = _gtk_builder_get_absolute_filename (builder, source_data->filename);
+ gtk_icon_source_set_filename (icon_source, filename);
+ g_free (filename);
+ }
+ if (source_data->icon_name)
+ gtk_icon_source_set_icon_name (icon_source, source_data->icon_name);
+ if (source_data->size != -1)
+ gtk_icon_source_set_size (icon_source, source_data->size);
+ if (source_data->direction != -1)
+ gtk_icon_source_set_direction (icon_source, source_data->direction);
+ if (source_data->state != -1)
+ gtk_icon_source_set_state (icon_source, source_data->state);
+
+ /* Inline source_add() to avoid creating a copy */
+ g_assert (source->type != GTK_ICON_SOURCE_EMPTY);
+ icon_set->sources = g_slist_insert_sorted (icon_set->sources,
+ icon_source,
+ icon_source_compare);
+ gtk_icon_set_unref (icon_set);
+
+ g_free (source_data->stock_id);
+ g_free (source_data->filename);
+ g_free (source_data->icon_name);
+ g_slice_free (IconSourceParserData, source_data);
+ }
+ g_slist_free (parser_data->sources);
+ g_slice_free (IconFactoryParserData, parser_data);
+ }
+}
+
#ifdef G_OS_WIN32
/* DLL ABI stability backward compatibility versions */
Modified: trunk/tests/buildertest.c
==============================================================================
--- trunk/tests/buildertest.c (original)
+++ trunk/tests/buildertest.c Fri Mar 7 00:08:16 2008
@@ -1793,6 +1793,34 @@
g_object_unref (builder);
}
+static void
+test_icon_factory (void)
+{
+ GtkBuilder *builder;
+ const gchar buffer1[] =
+ "<interface>"
+ " <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
+ " <sources>"
+ " <source stock-id=\"apple-red\" filename=\"apple-red.png\"/>"
+ " </sources>"
+ " </object>"
+ "</interface>";
+ GObject *factory;
+ GtkIconSet *icon_set;
+ GtkWidget *image;
+
+ builder = builder_new_from_string (buffer1, -1, NULL);
+ factory = gtk_builder_get_object (builder, "iconfactory1");
+ g_assert (factory != NULL);
+
+ icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (factory), "apple-red");
+ g_assert (icon_set != NULL);
+
+ gtk_icon_factory_add_default (GTK_ICON_FACTORY (factory));
+ image = gtk_image_new_from_stock ("apple-red", GTK_ICON_SIZE_BUTTON);
+ g_assert (image != NULL);
+}
+
static void
test_file (const gchar *filename)
{
@@ -1874,5 +1902,7 @@
g_test_add_func ("/Builder/Value From String", test_value_from_string);
g_test_add_func ("/Builder/Reference Counting", test_reference_counting);
g_test_add_func ("/Builder/Window", test_window);
+ g_test_add_func ("/Builder/IconFactory", test_icon_factory);
+
return g_test_run();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]