forked from AuroraMiddleware/gtk
Implement GtkBuildable on GtkIconFactory, to make it possible to register
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 svn path=/trunk/; revision=19726
This commit is contained in:
parent
6f9bcaa8b7
commit
61be2a7127
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
||||
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
|
||||
|
||||
2008-03-06 Johan Dahlin <johan@gnome.org>
|
||||
|
||||
Make gtk-doc happy:
|
||||
|
@ -35,6 +35,77 @@ gtk_widget_render_icon(). These functions take the theme into account when
|
||||
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>
|
||||
|
||||
|
@ -1234,18 +1234,7 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
|
||||
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 @@ gtk_builder_error_quark (void)
|
||||
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"
|
||||
|
@ -125,5 +125,7 @@ gboolean _gtk_builder_flags_from_string (GType type,
|
||||
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__ */
|
||||
|
@ -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 @@ struct _GtkIconSource
|
||||
};
|
||||
|
||||
|
||||
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 @@ static GtkIconSize icon_size_register_intern (const gchar *name,
|
||||
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)
|
||||
@ -113,6 +131,13 @@ gtk_icon_factory_class_init (GtkIconFactoryClass *klass)
|
||||
object_class->finalize = gtk_icon_factory_finalize;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -2700,6 +2725,204 @@ _gtk_icon_factory_list_ids (void)
|
||||
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 */
|
||||
|
@ -1793,6 +1793,34 @@ test_reference_counting (void)
|
||||
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 @@ main (int argc, char **argv)
|
||||
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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user