Quick-and-dirty GtkBuilder integration
This makes GtkBuilder accept a GMenuMarkup tree at the toplevel (ie with <menu id='foo'> being a child of <interface>) and the resulting GMenu object can be obtained via gtk_builder_get_object (builder, "foo").
This commit is contained in:
committed by
Ryan Lortie
parent
fd9df1864b
commit
1ddaf01aed
@ -731,6 +731,13 @@ _gtk_builder_construct (GtkBuilder *builder,
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_builder_add_object (GtkBuilder *builder,
|
||||||
|
const gchar *id,
|
||||||
|
GObject *object)
|
||||||
|
{
|
||||||
|
g_hash_table_insert (builder->priv->objects, g_strdup (id), g_object_ref (object));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gtk_builder_add (GtkBuilder *builder,
|
_gtk_builder_add (GtkBuilder *builder,
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
#include "gtkbuilderprivate.h"
|
#include "gtkbuilderprivate.h"
|
||||||
#include "gtkbuilder.h"
|
#include "gtkbuilder.h"
|
||||||
#include "gtkbuildable.h"
|
#include "gtkbuildable.h"
|
||||||
@ -823,6 +824,34 @@ parse_custom (GMarkupParseContext *context,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_menu (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
const gchar **names,
|
||||||
|
const gchar **values,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gchar *id;
|
||||||
|
ParserData *data = user_data;
|
||||||
|
ObjectInfo *object_info;
|
||||||
|
|
||||||
|
if (!g_markup_collect_attributes (element_name, names, values, error,
|
||||||
|
G_MARKUP_COLLECT_STRING, "id", &id,
|
||||||
|
G_MARKUP_COLLECT_INVALID))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
object_info = g_slice_new0 (ObjectInfo);
|
||||||
|
object_info->class_name = g_strdup ("GMenu");
|
||||||
|
object_info->id = g_strdup (id);
|
||||||
|
object_info->tag.name = element_name;
|
||||||
|
state_push (data, object_info);
|
||||||
|
|
||||||
|
g_menu_markup_parser_start_menu (context, NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
start_element (GMarkupParseContext *context,
|
start_element (GMarkupParseContext *context,
|
||||||
const gchar *element_name,
|
const gchar *element_name,
|
||||||
@ -883,6 +912,8 @@ start_element (GMarkupParseContext *context,
|
|||||||
parse_signal (data, element_name, names, values, error);
|
parse_signal (data, element_name, names, values, error);
|
||||||
else if (strcmp (element_name, "interface") == 0)
|
else if (strcmp (element_name, "interface") == 0)
|
||||||
parse_interface (data, element_name, names, values, error);
|
parse_interface (data, element_name, names, values, error);
|
||||||
|
else if (strcmp (element_name, "menu") == 0)
|
||||||
|
parse_menu (context, element_name, names, values, data, error);
|
||||||
else if (strcmp (element_name, "placeholder") == 0)
|
else if (strcmp (element_name, "placeholder") == 0)
|
||||||
{
|
{
|
||||||
/* placeholder has no special treatmeant, but it needs an
|
/* placeholder has no special treatmeant, but it needs an
|
||||||
@ -954,6 +985,18 @@ end_element (GMarkupParseContext *context,
|
|||||||
else if (strcmp (element_name, "interface") == 0)
|
else if (strcmp (element_name, "interface") == 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
else if (strcmp (element_name, "menu") == 0)
|
||||||
|
{
|
||||||
|
ObjectInfo *object_info;
|
||||||
|
GObject *menu;
|
||||||
|
|
||||||
|
object_info = state_pop_info (data, ObjectInfo);
|
||||||
|
menu = (GObject*)g_menu_markup_parser_end_menu (context);
|
||||||
|
_gtk_builder_add_object (data->builder, object_info->id, menu);
|
||||||
|
g_object_unref (menu);
|
||||||
|
|
||||||
|
free_object_info (object_info);
|
||||||
|
}
|
||||||
else if (data->requested_objects && !data->inside_requested_object)
|
else if (data->requested_objects && !data->inside_requested_object)
|
||||||
{
|
{
|
||||||
/* If outside a requested object, simply ignore this tag */
|
/* If outside a requested object, simply ignore this tag */
|
||||||
|
|||||||
@ -117,6 +117,9 @@ void _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
|||||||
GObject * _gtk_builder_construct (GtkBuilder *builder,
|
GObject * _gtk_builder_construct (GtkBuilder *builder,
|
||||||
ObjectInfo *info,
|
ObjectInfo *info,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
void _gtk_builder_add_object (GtkBuilder *builder,
|
||||||
|
const gchar *id,
|
||||||
|
GObject *object);
|
||||||
void _gtk_builder_add (GtkBuilder *builder,
|
void _gtk_builder_add (GtkBuilder *builder,
|
||||||
ChildInfo *child_info);
|
ChildInfo *child_info);
|
||||||
void _gtk_builder_add_signals (GtkBuilder *builder,
|
void _gtk_builder_add_signals (GtkBuilder *builder,
|
||||||
|
|||||||
@ -2572,6 +2572,48 @@ test_message_area (void)
|
|||||||
g_object_unref (builder);
|
g_object_unref (builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_gmenu (void)
|
||||||
|
{
|
||||||
|
GtkBuilder *builder;
|
||||||
|
GError *error;
|
||||||
|
GObject *obj, *obj1;
|
||||||
|
const gchar buffer[] =
|
||||||
|
"<interface>"
|
||||||
|
" <object class=\"GtkWindow\" id=\"window\">"
|
||||||
|
" </object>"
|
||||||
|
" <menu id='edit-menu'>"
|
||||||
|
" <section>"
|
||||||
|
" <item label='Undo' action='undo'/>"
|
||||||
|
" <item label='Redo' action='redo'/>"
|
||||||
|
" </section>"
|
||||||
|
" <section></section>"
|
||||||
|
" <section label='Copy & Paste'>"
|
||||||
|
" <item label='Cut' action='cut'/>"
|
||||||
|
" <item label='Copy' action='copy'/>"
|
||||||
|
" <item label='Paste' action='paste'/>"
|
||||||
|
" </section>"
|
||||||
|
" <section>"
|
||||||
|
" <item label='Bold' action='bold'/>"
|
||||||
|
" <submenu label='Language'>"
|
||||||
|
" <item label='Latin' action='lang' target='latin'/>"
|
||||||
|
" <item label='Greek' action='lang' target='greek'/>"
|
||||||
|
" <item label='Urdu' action='lang' target='urdu'/>"
|
||||||
|
" </submenu>"
|
||||||
|
" </section>"
|
||||||
|
" </menu>"
|
||||||
|
"</interface>";
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
builder = builder_new_from_string (buffer, -1, NULL);
|
||||||
|
g_assert (error == NULL);
|
||||||
|
obj = gtk_builder_get_object (builder, "window");
|
||||||
|
g_assert (GTK_IS_WINDOW (obj));
|
||||||
|
obj1 = gtk_builder_get_object (builder, "edit-menu");
|
||||||
|
g_assert (G_IS_MENU_MODEL (obj1));
|
||||||
|
g_object_unref (builder);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -2618,6 +2660,7 @@ main (int argc, char **argv)
|
|||||||
g_test_add_func ("/Builder/Menus", test_menus);
|
g_test_add_func ("/Builder/Menus", test_menus);
|
||||||
g_test_add_func ("/Builder/MessageArea", test_message_area);
|
g_test_add_func ("/Builder/MessageArea", test_message_area);
|
||||||
g_test_add_func ("/Builder/MessageDialog", test_message_dialog);
|
g_test_add_func ("/Builder/MessageDialog", test_message_dialog);
|
||||||
|
g_test_add_func ("/Builder/GMenu", test_gmenu);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user