forked from AuroraMiddleware/gtk
Merge branch 'wip/otte/builder' into 'master'
Reorganize various GtkBuilder things See merge request GNOME/gtk!1204
This commit is contained in:
commit
e3c3cbbbcb
@ -59,7 +59,6 @@ do_builder (GtkWidget *do_widget)
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
|
||||
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -24,7 +24,6 @@ do_cursors (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -122,7 +122,6 @@ do_filtermodel (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/filtermodel/filtermodel.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -287,13 +287,13 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
|
||||
g_type_ensure (GTK_TYPE_FISHBOWL);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_callback_symbols (builder,
|
||||
"next_button_clicked_cb", G_CALLBACK (next_button_clicked_cb),
|
||||
"prev_button_clicked_cb", G_CALLBACK (prev_button_clicked_cb),
|
||||
"changes_toggled_cb", G_CALLBACK (changes_toggled_cb),
|
||||
NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_builder_add_from_resource (builder, "/fishbowl/fishbowl.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
@ -1213,15 +1213,14 @@ do_font_features (GtkWidget *do_widget)
|
||||
GtkWidget *feature_list;
|
||||
GtkEventController *controller;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/font_features/font-features.ui");
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_callback_symbol (builder, "update_display", update_display);
|
||||
gtk_builder_add_callback_symbol (builder, "font_changed", font_changed);
|
||||
gtk_builder_add_callback_symbol (builder, "script_changed", script_changed);
|
||||
gtk_builder_add_callback_symbol (builder, "reset", reset_features);
|
||||
gtk_builder_add_callback_symbol (builder, "stop_edit", G_CALLBACK (stop_edit));
|
||||
gtk_builder_add_callback_symbol (builder, "toggle_edit", G_CALLBACK (toggle_edit));
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_builder_add_from_resource (builder, "/font_features/font-features.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
feature_list = GTK_WIDGET (gtk_builder_get_object (builder, "feature_list"));
|
||||
|
@ -248,7 +248,6 @@ do_fontrendering (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fontrendering/fontrendering.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -205,12 +205,12 @@ do_iconscroll (GtkWidget *do_widget)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_callback_symbols (builder,
|
||||
"next_clicked_cb", G_CALLBACK (next_clicked_cb),
|
||||
"prev_clicked_cb", G_CALLBACK (prev_clicked_cb),
|
||||
NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_builder_add_from_resource (builder, "/iconscroll/iconscroll.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
@ -39,9 +39,9 @@ do_modelbutton (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
GActionGroup *actions;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/modelbutton/modelbutton.ui");
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_callback_symbol (builder, "tool_clicked", G_CALLBACK (tool_clicked));
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_builder_add_from_resource (builder, "/modelbutton/modelbutton.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -69,7 +69,6 @@ do_revealer (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/revealer/revealer.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -18,7 +18,6 @@ do_scale (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/scale/scale.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -85,7 +85,7 @@ do_shortcuts (GtkWidget *do_widget)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/shortcuts/shortcuts.ui");
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_callback_symbols (builder,
|
||||
"builder_shortcuts", G_CALLBACK (builder_shortcuts),
|
||||
"gedit_shortcuts", G_CALLBACK (gedit_shortcuts),
|
||||
@ -95,7 +95,7 @@ do_shortcuts (GtkWidget *do_widget)
|
||||
"boxes_shortcuts_wizard", G_CALLBACK (boxes_shortcuts_wizard),
|
||||
"boxes_shortcuts_display", G_CALLBACK (boxes_shortcuts_display),
|
||||
NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_builder_add_from_resource (builder, "/shortcuts/shortcuts.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -190,7 +190,7 @@ do_spinbutton (GtkWidget *do_widget)
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *label;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui");
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_callback_symbols (builder,
|
||||
"hex_spin_input", G_CALLBACK (hex_spin_input),
|
||||
"hex_spin_output", G_CALLBACK (hex_spin_output),
|
||||
@ -199,7 +199,7 @@ do_spinbutton (GtkWidget *do_widget)
|
||||
"month_spin_input", G_CALLBACK (month_spin_input),
|
||||
"month_spin_output", G_CALLBACK (month_spin_output),
|
||||
NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_builder_add_from_resource (builder, "/spinbutton/spinbutton.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -18,7 +18,6 @@ do_stack (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/stack/stack.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@ -1715,7 +1715,7 @@ activate (GApplication *app)
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
g_object_unref (provider);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/org/gtk/WidgetFactory4/widget-factory.ui");
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_callback_symbol (builder, "on_entry_icon_release", (GCallback)on_entry_icon_release);
|
||||
gtk_builder_add_callback_symbol (builder, "on_scale_button_value_changed", (GCallback)on_scale_button_value_changed);
|
||||
gtk_builder_add_callback_symbol (builder, "on_scale_button_query_tooltip", (GCallback)on_scale_button_query_tooltip);
|
||||
@ -1728,8 +1728,7 @@ activate (GApplication *app)
|
||||
gtk_builder_add_callback_symbol (builder, "decrease_icon_size", (GCallback)decrease_icon_size);
|
||||
gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size);
|
||||
gtk_builder_add_callback_symbol (builder, "osd_frame_pressed", (GCallback)osd_frame_pressed);
|
||||
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", NULL);
|
||||
|
||||
window = (GtkWindow *)gtk_builder_get_object (builder, "window");
|
||||
gtk_application_add_window (GTK_APPLICATION (app), window);
|
||||
|
@ -520,7 +520,7 @@ GTK_BUILDABLE_GET_IFACE
|
||||
<FILE>gtkbuilder</FILE>
|
||||
<TITLE>GtkBuilder</TITLE>
|
||||
GtkBuilder
|
||||
GtkBuilderConnectFunc
|
||||
GtkBuilderClosureFunc
|
||||
GtkBuilderError
|
||||
gtk_builder_new
|
||||
gtk_builder_new_from_file
|
||||
@ -529,6 +529,8 @@ gtk_builder_new_from_string
|
||||
gtk_builder_add_callback_symbol
|
||||
gtk_builder_add_callback_symbols
|
||||
gtk_builder_lookup_callback_symbol
|
||||
gtk_builder_create_closure
|
||||
gtk_builder_create_cclosure
|
||||
gtk_builder_add_from_file
|
||||
gtk_builder_add_from_resource
|
||||
gtk_builder_add_from_string
|
||||
@ -539,13 +541,10 @@ gtk_builder_extend_with_template
|
||||
gtk_builder_get_object
|
||||
gtk_builder_get_objects
|
||||
gtk_builder_expose_object
|
||||
gtk_builder_connect_signals
|
||||
gtk_builder_connect_signals_full
|
||||
gtk_builder_set_translation_domain
|
||||
gtk_builder_get_translation_domain
|
||||
gtk_builder_set_application
|
||||
gtk_builder_get_application
|
||||
gtk_builder_get_type_from_name
|
||||
gtk_builder_set_closure_func
|
||||
gtk_builder_value_from_string
|
||||
gtk_builder_value_from_string_type
|
||||
GTK_BUILDER_WARN_INVALID_CHILD_TYPE
|
||||
@ -4667,7 +4666,7 @@ gtk_widget_class_bind_template_child_internal_private
|
||||
gtk_widget_class_bind_template_child_full
|
||||
gtk_widget_class_bind_template_callback
|
||||
gtk_widget_class_bind_template_callback_full
|
||||
gtk_widget_class_set_connect_func
|
||||
gtk_widget_class_set_closure_func
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_widget_observe_children
|
||||
|
552
gtk/gtkbuilder.c
552
gtk/gtkbuilder.c
@ -137,18 +137,6 @@
|
||||
* Internally builder implements this using GBinding objects.
|
||||
* For more information see g_object_bind_property()
|
||||
*
|
||||
* Signal handlers are set up with the <signal> element. The “name”
|
||||
* attribute specifies the name of the signal, and the “handler” attribute
|
||||
* specifies the function to connect to the signal. By default, GTK+ tries
|
||||
* to find the handler using g_module_symbol(), but this can be changed by
|
||||
* passing a custom #GtkBuilderConnectFunc to
|
||||
* gtk_builder_connect_signals_full(). The remaining attributes, “after”,
|
||||
* “swapped” and “object”, have the same meaning as the corresponding
|
||||
* parameters of the g_signal_connect_object() or
|
||||
* g_signal_connect_data() functions. A “last_modification_time”
|
||||
* attribute is also allowed, but it does not have a meaning to the
|
||||
* builder.
|
||||
*
|
||||
* Sometimes it is necessary to refer to widgets which have implicitly
|
||||
* been constructed by GTK+ as part of a composite widget, to set
|
||||
* properties on them or to add further children (e.g. the @vbox of
|
||||
@ -163,6 +151,43 @@
|
||||
* The possible values for the “type” attribute are described in the
|
||||
* sections describing the widget-specific portions of UI definitions.
|
||||
*
|
||||
* # Signal handlers and function pointers
|
||||
*
|
||||
* Signal handlers are set up with the <signal> element. The “name”
|
||||
* attribute specifies the name of the signal, and the “handler” attribute
|
||||
* specifies the function to connect to the signal.
|
||||
* The remaining attributes, “after”, “swapped” and “object”, have the
|
||||
* same meaning as the corresponding parameters of the
|
||||
* g_signal_connect_object() or g_signal_connect_data() functions. A
|
||||
* “last_modification_time” attribute is also allowed, but it does not
|
||||
* have a meaning to the builder.
|
||||
*
|
||||
* By default, GTK+ tries to find functions (like the handlers for
|
||||
* signals) by using g_module_symbol(), but this can be changed by
|
||||
* passing a custom #GtkBuilderClosureFunc to gtk_builder_set_closure_func().
|
||||
* Bindings in particular will want to make use of this functionality to
|
||||
* allow language-specific name mangling and namespacing.
|
||||
*
|
||||
* The default closure function uses symbols explicitly added to @builder
|
||||
* with prior calls to gtk_builder_add_callback_symbol(). In the case that
|
||||
* symbols are not explicitly added; it uses #GModule’s introspective
|
||||
* features (by opening the module %NULL) to look at the application’s symbol
|
||||
* table. From here it tries to match the signal function names given in the
|
||||
* interface description with symbols in the application.
|
||||
*
|
||||
* Note that unless gtk_builder_add_callback_symbol() is called for
|
||||
* all signal callbacks which are referenced by the loaded XML, this
|
||||
* functionality will require that #GModule be supported on the platform.
|
||||
*
|
||||
* If you rely on #GModule support to lookup callbacks in the symbol table,
|
||||
* the following details should be noted:
|
||||
*
|
||||
* When compiling applications for Windows, you must declare signal callbacks
|
||||
* with #G_MODULE_EXPORT, or they will not be put in the symbol table.
|
||||
* On Linux and Unices, this is not necessary; applications should instead
|
||||
* be compiled with the -Wl,--export-dynamic CFLAGS, and linked against
|
||||
* gmodule-export-2.0.
|
||||
*
|
||||
* # A GtkBuilder UI Definition
|
||||
*
|
||||
* |[
|
||||
@ -216,7 +241,6 @@
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtktestutils.h"
|
||||
|
||||
|
||||
static void gtk_builder_finalize (GObject *object);
|
||||
static void gtk_builder_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -226,8 +250,6 @@ static void gtk_builder_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static GType gtk_builder_real_get_type_from_name (GtkBuilder *builder,
|
||||
const gchar *type_name);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -237,6 +259,16 @@ enum {
|
||||
|
||||
static GParamSpec *builder_props[LAST_PROP];
|
||||
|
||||
struct _GtkBuilder
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _GtkBuilderClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *domain;
|
||||
@ -245,10 +277,14 @@ typedef struct
|
||||
GSList *delayed_properties;
|
||||
GSList *signals;
|
||||
GSList *bindings;
|
||||
GModule *module;
|
||||
gchar *filename;
|
||||
gchar *resource_prefix;
|
||||
GType template_type;
|
||||
GtkApplication *application;
|
||||
|
||||
GtkBuilderClosureFunc closure_func;
|
||||
gpointer closure_data;
|
||||
GDestroyNotify closure_destroy;
|
||||
} GtkBuilderPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkBuilder, gtk_builder, G_TYPE_OBJECT)
|
||||
@ -256,16 +292,12 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkBuilder, gtk_builder, G_TYPE_OBJECT)
|
||||
static void
|
||||
gtk_builder_class_init (GtkBuilderClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = gtk_builder_finalize;
|
||||
gobject_class->set_property = gtk_builder_set_property;
|
||||
gobject_class->get_property = gtk_builder_get_property;
|
||||
|
||||
klass->get_type_from_name = gtk_builder_real_get_type_from_name;
|
||||
|
||||
/**
|
||||
* GtkBuilder:translation-domain:
|
||||
*
|
||||
@ -304,6 +336,11 @@ gtk_builder_finalize (GObject *object)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (GTK_BUILDER (object));
|
||||
|
||||
if (priv->closure_destroy)
|
||||
priv->closure_destroy (priv->closure_data);
|
||||
|
||||
g_clear_pointer (&priv->module, g_module_close);
|
||||
|
||||
g_free (priv->domain);
|
||||
g_free (priv->filename);
|
||||
g_free (priv->resource_prefix);
|
||||
@ -390,16 +427,34 @@ type_name_mangle (const gchar *name)
|
||||
return g_string_free (symbol_name, FALSE);
|
||||
}
|
||||
|
||||
static GType
|
||||
_gtk_builder_resolve_type_lazily (const gchar *name)
|
||||
GModule *
|
||||
gtk_builder_get_module (GtkBuilder *builder)
|
||||
{
|
||||
static GModule *module = NULL;
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
|
||||
if (priv->module == NULL)
|
||||
{
|
||||
if (!g_module_supported ())
|
||||
return NULL;
|
||||
|
||||
priv->module = g_module_open (NULL, G_MODULE_BIND_LAZY);
|
||||
}
|
||||
|
||||
return priv->module;
|
||||
}
|
||||
|
||||
static GType
|
||||
gtk_builder_resolve_type_lazily (GtkBuilder *builder,
|
||||
const gchar *name)
|
||||
{
|
||||
GModule *module;
|
||||
GTypeGetFunc func;
|
||||
gchar *symbol;
|
||||
GType gtype = G_TYPE_INVALID;
|
||||
|
||||
module = gtk_builder_get_module (builder);
|
||||
if (!module)
|
||||
module = g_module_open (NULL, 0);
|
||||
return G_TYPE_INVALID;
|
||||
|
||||
symbol = type_name_mangle (name);
|
||||
|
||||
@ -415,24 +470,6 @@ _gtk_builder_resolve_type_lazily (const gchar *name)
|
||||
* GtkBuilder virtual methods
|
||||
*/
|
||||
|
||||
static GType
|
||||
gtk_builder_real_get_type_from_name (GtkBuilder *builder,
|
||||
const gchar *type_name)
|
||||
{
|
||||
GType gtype;
|
||||
|
||||
gtype = g_type_from_name (type_name);
|
||||
if (gtype != G_TYPE_INVALID)
|
||||
return gtype;
|
||||
|
||||
gtype = _gtk_builder_resolve_type_lazily (type_name);
|
||||
if (gtype != G_TYPE_INVALID)
|
||||
return gtype;
|
||||
|
||||
gtk_test_register_all_types ();
|
||||
return g_type_from_name (type_name);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *object;
|
||||
@ -1027,13 +1064,6 @@ gtk_builder_create_bindings (GtkBuilder *builder)
|
||||
priv->bindings = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_builder_finish (GtkBuilder *builder)
|
||||
{
|
||||
gtk_builder_apply_delayed_properties (builder);
|
||||
gtk_builder_create_bindings (builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_new:
|
||||
*
|
||||
@ -1629,153 +1659,54 @@ gtk_builder_expose_object (GtkBuilder *builder,
|
||||
g_object_ref (object));
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
GModule *module;
|
||||
gpointer data;
|
||||
} ConnectArgs;
|
||||
|
||||
static void
|
||||
gtk_builder_connect_signals_default (GtkBuilder *builder,
|
||||
GObject *object,
|
||||
const gchar *signal_name,
|
||||
const gchar *handler_name,
|
||||
GObject *connect_object,
|
||||
GConnectFlags flags,
|
||||
gpointer user_data)
|
||||
{
|
||||
GCallback func;
|
||||
ConnectArgs *args = (ConnectArgs*) user_data;
|
||||
|
||||
func = gtk_builder_lookup_callback_symbol (builder, handler_name);
|
||||
|
||||
if (!func)
|
||||
{
|
||||
/* Only error out for missing GModule support if we've not
|
||||
* found the symbols explicitly added with gtk_builder_add_callback_symbol()
|
||||
*/
|
||||
if (args->module == NULL)
|
||||
g_error ("gtk_builder_connect_signals() requires working GModule");
|
||||
|
||||
if (!g_module_symbol (args->module, handler_name, (gpointer)&func))
|
||||
{
|
||||
g_warning ("Could not find signal handler '%s'. Did you compile with -rdynamic?", handler_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (connect_object)
|
||||
g_signal_connect_object (object, signal_name, func, connect_object, flags);
|
||||
else
|
||||
g_signal_connect_data (object, signal_name, func, args->data, NULL, flags);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_builder_connect_signals:
|
||||
* GtkBuilderClosureFunc:
|
||||
* @builder: a #GtkBuilder
|
||||
* @user_data: user data to pass back with all signals
|
||||
* @function_name: name of the function to create a closure for
|
||||
* @swapped: if the closure should swap user data and instance
|
||||
* @object: (nullable): object to use as user data for the closure
|
||||
* @user_data: user data passed when setting the function
|
||||
* @error: location for error when creating the closure fails
|
||||
*
|
||||
* This method is a simpler variation of gtk_builder_connect_signals_full().
|
||||
* It uses symbols explicitly added to @builder with prior calls to
|
||||
* gtk_builder_add_callback_symbol(). In the case that symbols are not
|
||||
* explicitly added; it uses #GModule’s introspective features (by opening the module %NULL)
|
||||
* to look at the application’s symbol table. From here it tries to match
|
||||
* the signal handler names given in the interface description with
|
||||
* symbols in the application and connects the signals. Note that this
|
||||
* function can only be called once, subsequent calls will do nothing.
|
||||
* Prototype of function used to create closures by @builder. It is meant
|
||||
* for influencing how @function_name is resolved.
|
||||
*
|
||||
* Note that unless gtk_builder_add_callback_symbol() is called for
|
||||
* all signal callbacks which are referenced by the loaded XML, this
|
||||
* function will require that #GModule be supported on the platform.
|
||||
* This function is most useful for bindings and can be used with
|
||||
* gtk_builder_set_closure_func() or gtk_widget_class_set_closure_func()
|
||||
* to allow creating closures for functions defined in the binding's
|
||||
* language.
|
||||
*
|
||||
* If you rely on #GModule support to lookup callbacks in the symbol table,
|
||||
* the following details should be noted:
|
||||
* If the given @function_name does not match a function name or when the
|
||||
* arguments cannot be supported by the bindings, bindings should return
|
||||
* %NULL and set @error. Usually %GTK_BUILDER_ERROR_INVALID_FUNCTION will
|
||||
* be the right error code to use.
|
||||
*
|
||||
* When compiling applications for Windows, you must declare signal callbacks
|
||||
* with #G_MODULE_EXPORT, or they will not be put in the symbol table.
|
||||
* On Linux and Unices, this is not necessary; applications should instead
|
||||
* be compiled with the -Wl,--export-dynamic CFLAGS, and linked against
|
||||
* gmodule-export-2.0.
|
||||
**/
|
||||
void
|
||||
gtk_builder_connect_signals (GtkBuilder *builder,
|
||||
gpointer user_data)
|
||||
{
|
||||
ConnectArgs args;
|
||||
|
||||
g_return_if_fail (GTK_IS_BUILDER (builder));
|
||||
|
||||
args.data = user_data;
|
||||
|
||||
if (g_module_supported ())
|
||||
args.module = g_module_open (NULL, G_MODULE_BIND_LAZY);
|
||||
else
|
||||
args.module = NULL;
|
||||
|
||||
gtk_builder_connect_signals_full (builder,
|
||||
gtk_builder_connect_signals_default,
|
||||
&args);
|
||||
if (args.module)
|
||||
g_module_close (args.module);
|
||||
}
|
||||
|
||||
/**
|
||||
* GtkBuilderConnectFunc:
|
||||
* @builder: a #GtkBuilder
|
||||
* @object: object to connect a signal to
|
||||
* @signal_name: name of the signal
|
||||
* @handler_name: name of the handler
|
||||
* @connect_object: (nullable): a #GObject, if non-%NULL, use g_signal_connect_object()
|
||||
* @flags: #GConnectFlags to use
|
||||
* @user_data: user data
|
||||
*
|
||||
* This is the signature of a function used to connect signals. It is used
|
||||
* by the gtk_builder_connect_signals() and gtk_builder_connect_signals_full()
|
||||
* methods. It is mainly intended for interpreted language bindings, but
|
||||
* could be useful where the programmer wants more control over the signal
|
||||
* connection process. Note that this function can only be called once,
|
||||
* subsequent calls will do nothing.
|
||||
* Returns: (nullable): a new #GClosure or %NULL when no closure could
|
||||
* be created and @error was set.
|
||||
*/
|
||||
|
||||
/**
|
||||
* gtk_builder_connect_signals_full:
|
||||
* @builder: a #GtkBuilder
|
||||
* @func: (scope call): the function used to connect the signals
|
||||
* @user_data: arbitrary data that will be passed to the connection function
|
||||
*
|
||||
* This function can be thought of the interpreted language binding
|
||||
* version of gtk_builder_connect_signals(), except that it does not
|
||||
* require GModule to function correctly.
|
||||
*/
|
||||
void
|
||||
gtk_builder_connect_signals_full (GtkBuilder *builder,
|
||||
GtkBuilderConnectFunc func,
|
||||
gpointer user_data)
|
||||
static gboolean
|
||||
gtk_builder_connect_signals (GtkBuilder *builder,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
GSList *l;
|
||||
GObject *object;
|
||||
GObject *connect_object;
|
||||
GString *detailed_id = NULL;
|
||||
|
||||
g_return_if_fail (GTK_IS_BUILDER (builder));
|
||||
g_return_if_fail (func != NULL);
|
||||
gboolean result = FALSE;
|
||||
|
||||
if (!priv->signals)
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
priv->signals = g_slist_reverse (priv->signals);
|
||||
for (l = priv->signals; l; l = l->next)
|
||||
{
|
||||
SignalInfo *signal = (SignalInfo*)l->data;
|
||||
const gchar *signal_name;
|
||||
GClosure *closure;
|
||||
|
||||
g_assert (signal != NULL);
|
||||
g_assert (signal->id != 0);
|
||||
|
||||
signal_name = g_signal_name (signal->id);
|
||||
|
||||
object = g_hash_table_lookup (priv->objects, signal->object_name);
|
||||
g_assert (object != NULL);
|
||||
|
||||
@ -1786,30 +1717,47 @@ gtk_builder_connect_signals_full (GtkBuilder *builder,
|
||||
connect_object = g_hash_table_lookup (priv->objects,
|
||||
signal->connect_object_name);
|
||||
if (!connect_object)
|
||||
g_warning ("Could not lookup object %s on signal %s of object %s",
|
||||
signal->connect_object_name, signal_name,
|
||||
signal->object_name);
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_ID,
|
||||
"Could not lookup object %s on signal %s of object %s",
|
||||
signal->connect_object_name, g_signal_name (signal->id),
|
||||
signal->object_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (signal->detail)
|
||||
{
|
||||
if (detailed_id == NULL)
|
||||
detailed_id = g_string_new ("");
|
||||
closure = gtk_builder_create_closure (builder,
|
||||
signal->handler,
|
||||
signal->flags & G_CONNECT_SWAPPED ? TRUE : FALSE,
|
||||
connect_object,
|
||||
error);
|
||||
|
||||
g_string_printf (detailed_id, "%s::%s", signal_name,
|
||||
g_quark_to_string (signal->detail));
|
||||
signal_name = detailed_id->str;
|
||||
}
|
||||
if (closure == NULL)
|
||||
break;
|
||||
|
||||
func (builder, object, signal_name, signal->handler,
|
||||
connect_object, signal->flags, user_data);
|
||||
g_signal_connect_closure_by_id (object,
|
||||
signal->id,
|
||||
signal->detail,
|
||||
closure,
|
||||
signal->flags & G_CONNECT_AFTER ? TRUE : FALSE);
|
||||
}
|
||||
if (l == NULL)
|
||||
result = TRUE;
|
||||
|
||||
g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info);
|
||||
priv->signals = NULL;
|
||||
|
||||
if (detailed_id)
|
||||
g_string_free (detailed_id, TRUE);
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_builder_finish (GtkBuilder *builder,
|
||||
GError **error)
|
||||
{
|
||||
gtk_builder_apply_delayed_properties (builder);
|
||||
gtk_builder_create_bindings (builder);
|
||||
return gtk_builder_connect_signals (builder, error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2493,7 +2441,16 @@ gtk_builder_get_type_from_name (GtkBuilder *builder,
|
||||
g_return_val_if_fail (GTK_IS_BUILDER (builder), G_TYPE_INVALID);
|
||||
g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
|
||||
|
||||
type = GTK_BUILDER_GET_CLASS (builder)->get_type_from_name (builder, type_name);
|
||||
type = g_type_from_name (type_name);
|
||||
if (type == G_TYPE_INVALID)
|
||||
{
|
||||
type = gtk_builder_resolve_type_lazily (builder, type_name);
|
||||
if (type == G_TYPE_INVALID)
|
||||
{
|
||||
gtk_test_register_all_types ();
|
||||
type = g_type_from_name (type_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (G_TYPE_IS_CLASSED (type))
|
||||
g_type_class_unref (g_type_class_ref (type));
|
||||
@ -2569,7 +2526,7 @@ _gtk_builder_get_template_type (GtkBuilder *builder)
|
||||
*
|
||||
* Adds the @callback_symbol to the scope of @builder under the given @callback_name.
|
||||
*
|
||||
* Using this function overrides the behavior of gtk_builder_connect_signals()
|
||||
* Using this function overrides the behavior of gtk_builder_create_closure()
|
||||
* for any callback symbols that are added. Using this method allows for better
|
||||
* encapsulation as it does not require that callback symbols be declared in
|
||||
* the global namespace.
|
||||
@ -2645,7 +2602,7 @@ gtk_builder_add_callback_symbols (GtkBuilder *builder,
|
||||
*
|
||||
* This function is intended for possible use in language bindings
|
||||
* or for any case that one might be customizing signal connections
|
||||
* using gtk_builder_connect_signals_full()
|
||||
* using gtk_builder_set_closure_func().
|
||||
*
|
||||
* Returns: (nullable): The callback symbol in @builder for @callback_name, or %NULL
|
||||
*/
|
||||
@ -2664,6 +2621,159 @@ gtk_builder_lookup_callback_symbol (GtkBuilder *builder,
|
||||
return g_hash_table_lookup (priv->callbacks, callback_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_set_closure_func: (skip)
|
||||
* @builder: a #GtkBuilder
|
||||
* @closure_func: (allow-none) function to call when creating
|
||||
* closures or %NULL to use the default
|
||||
* @user_data: (nullable): user data to pass to @closure_func
|
||||
* @user_destroy: destroy function for user data
|
||||
*
|
||||
* Sets the function to call for creating closures.
|
||||
* gtk_builder_create_closure() will use this function instead
|
||||
* of gtk_builder_create_cclosure().
|
||||
*
|
||||
* This is useful for bindings.
|
||||
**/
|
||||
void
|
||||
gtk_builder_set_closure_func (GtkBuilder *builder,
|
||||
GtkBuilderClosureFunc closure_func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
|
||||
g_return_if_fail (GTK_IS_BUILDER (builder));
|
||||
|
||||
if (priv->closure_destroy)
|
||||
priv->closure_destroy (priv->closure_data);
|
||||
|
||||
priv->closure_func = closure_func;
|
||||
priv->closure_data = user_data;
|
||||
priv->closure_destroy = user_destroy;
|
||||
}
|
||||
|
||||
static GClosure *
|
||||
gtk_builder_create_closure_for_funcptr (GtkBuilder *builder,
|
||||
GCallback callback,
|
||||
gboolean swapped,
|
||||
GObject *object)
|
||||
{
|
||||
GClosure *closure;
|
||||
|
||||
if (object)
|
||||
{
|
||||
if (swapped)
|
||||
closure = g_cclosure_new_object_swap (callback, object);
|
||||
else
|
||||
closure = g_cclosure_new_object (callback, object);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (swapped)
|
||||
closure = g_cclosure_new_swap (callback, NULL, NULL);
|
||||
else
|
||||
closure = g_cclosure_new (callback, NULL, NULL);
|
||||
}
|
||||
|
||||
return closure;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_create_closure:
|
||||
* @builder: a #GtkBuilder
|
||||
* @function_name: name of the function to look up
|
||||
* @swapped: %TRUE to create a swapped closure
|
||||
* @object: (nullable): Object to create the closure with
|
||||
* @error: (allow-none): return location for an error, or %NULL
|
||||
*
|
||||
* Creates a closure to invoke the function called @function_name.
|
||||
*
|
||||
* If a closure function was set via gtk_builder_set_closure_func(),
|
||||
* will be invoked.
|
||||
* Otherwise, gtk_builder_create_cclosure() will be called.
|
||||
*
|
||||
* If no closure could be created, %NULL will be returned and @error will
|
||||
* be set.
|
||||
*
|
||||
* Returns: (nullable): A new closure for invoking @function_name
|
||||
**/
|
||||
GClosure *
|
||||
gtk_builder_create_closure (GtkBuilder *builder,
|
||||
const char *function_name,
|
||||
gboolean swapped,
|
||||
GObject *object,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (function_name, NULL);
|
||||
g_return_val_if_fail (object == NULL || G_IS_OBJECT (object), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (priv->closure_func)
|
||||
return priv->closure_func (builder, function_name, swapped, object, priv->closure_data, error);
|
||||
else
|
||||
return gtk_builder_create_cclosure (builder, function_name, swapped, object, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_create_cclosure: (skip)
|
||||
* @builder: a #GtkBuilder
|
||||
* @function_name: name of the function to look up
|
||||
* @swapped: %TRUE to create a swapped closure
|
||||
* @object: (nullable): Object to create the closure with
|
||||
* @error: (allow-none): return location for an error, or %NULL
|
||||
*
|
||||
* This is the default function used by gtk_builder_set_closure_func(). Some bindings
|
||||
* with C support may want to call this function as a fallback from their closure
|
||||
* function.
|
||||
*
|
||||
* This function has no purpose otherwise.
|
||||
*
|
||||
* This function will prefer callbacks added via gtk_builder_add_callback_symbol()
|
||||
* to looking up public symbols.
|
||||
*
|
||||
* Returns: (nullable): A new closure for invoking @function_name
|
||||
**/
|
||||
GClosure *
|
||||
gtk_builder_create_cclosure (GtkBuilder *builder,
|
||||
const char *function_name,
|
||||
gboolean swapped,
|
||||
GObject *object,
|
||||
GError **error)
|
||||
{
|
||||
GModule *module = gtk_builder_get_module (builder);
|
||||
GCallback func;
|
||||
|
||||
func = gtk_builder_lookup_callback_symbol (builder, function_name);
|
||||
if (func)
|
||||
return gtk_builder_create_closure_for_funcptr (builder, func, swapped, object);
|
||||
|
||||
if (module == NULL)
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION,
|
||||
"Could not look up function `%s`: GModule is not supported.",
|
||||
function_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!g_module_symbol (module, function_name, (gpointer)&func))
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION,
|
||||
"No function named `%s`.",
|
||||
function_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gtk_builder_create_closure_for_funcptr (builder, func, swapped, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_new_from_file:
|
||||
* @filename: filename of user interface description file
|
||||
@ -2746,66 +2856,6 @@ gtk_builder_new_from_string (const gchar *string,
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_set_application:
|
||||
* @builder: a #GtkBuilder
|
||||
* @application: a #GtkApplication
|
||||
*
|
||||
* Sets the application associated with @builder.
|
||||
*
|
||||
* You only need this function if there is more than one #GApplication
|
||||
* in your process. @application cannot be %NULL.
|
||||
**/
|
||||
void
|
||||
gtk_builder_set_application (GtkBuilder *builder,
|
||||
GtkApplication *application)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
|
||||
g_return_if_fail (GTK_IS_BUILDER (builder));
|
||||
g_return_if_fail (GTK_IS_APPLICATION (application));
|
||||
|
||||
if (priv->application)
|
||||
g_object_unref (priv->application);
|
||||
|
||||
priv->application = g_object_ref (application);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_builder_get_application:
|
||||
* @builder: a #GtkBuilder
|
||||
*
|
||||
* Gets the #GtkApplication associated with the builder.
|
||||
*
|
||||
* The #GtkApplication is used for creating action proxies as requested
|
||||
* from XML that the builder is loading.
|
||||
*
|
||||
* By default, the builder uses the default application: the one from
|
||||
* g_application_get_default(). If you want to use another application
|
||||
* for constructing proxies, use gtk_builder_set_application().
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the application being used by the builder,
|
||||
* or %NULL
|
||||
**/
|
||||
GtkApplication *
|
||||
gtk_builder_get_application (GtkBuilder *builder)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
|
||||
|
||||
if (!priv->application)
|
||||
{
|
||||
GApplication *application;
|
||||
|
||||
application = g_application_get_default ();
|
||||
if (application && GTK_IS_APPLICATION (application))
|
||||
priv->application = g_object_ref (GTK_APPLICATION (application));
|
||||
}
|
||||
|
||||
return priv->application;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _gtk_builder_prefix_error:
|
||||
* @builder: a #GtkBuilder
|
||||
|
@ -63,7 +63,10 @@ typedef struct _GtkBuilderClass GtkBuilderClass;
|
||||
* @GTK_BUILDER_ERROR_TEMPLATE_MISMATCH: The wrong type was specified in a composite class’s template XML
|
||||
* @GTK_BUILDER_ERROR_INVALID_PROPERTY: The specified property is unknown for the object class.
|
||||
* @GTK_BUILDER_ERROR_INVALID_SIGNAL: The specified signal is unknown for the object class.
|
||||
* @GTK_BUILDER_ERROR_INVALID_ID: An object id is unknown
|
||||
* @GTK_BUILDER_ERROR_INVALID_ID: An object id is unknown.
|
||||
* @GTK_BUILDER_ERROR_INVALID_FUNCTION: A function could not be found. This often happens
|
||||
* when symbols are set to be kept private. Compiling code with -rdynamic or using the
|
||||
* `gmodule-export-2.0` pkgconfig module can fix this problem.
|
||||
*
|
||||
* Error codes that identify various errors that can occur while using
|
||||
* #GtkBuilder.
|
||||
@ -83,34 +86,23 @@ typedef enum
|
||||
GTK_BUILDER_ERROR_TEMPLATE_MISMATCH,
|
||||
GTK_BUILDER_ERROR_INVALID_PROPERTY,
|
||||
GTK_BUILDER_ERROR_INVALID_SIGNAL,
|
||||
GTK_BUILDER_ERROR_INVALID_ID
|
||||
GTK_BUILDER_ERROR_INVALID_ID,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION
|
||||
} GtkBuilderError;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_builder_error_quark (void);
|
||||
|
||||
struct _GtkBuilder
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _GtkBuilderClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
GType (* get_type_from_name) (GtkBuilder *builder,
|
||||
const char *type_name);
|
||||
|
||||
/*< private >*/
|
||||
|
||||
gpointer padding[8];
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_builder_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkBuilder* gtk_builder_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_builder_set_closure_func (GtkBuilder *builder,
|
||||
GtkBuilderClosureFunc closure_func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_builder_add_from_file (GtkBuilder *builder,
|
||||
const gchar *filename,
|
||||
@ -150,13 +142,6 @@ void gtk_builder_expose_object (GtkBuilder *builder,
|
||||
const gchar *name,
|
||||
GObject *object);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_builder_connect_signals (GtkBuilder *builder,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_builder_connect_signals_full (GtkBuilder *builder,
|
||||
GtkBuilderConnectFunc func,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_builder_set_translation_domain (GtkBuilder *builder,
|
||||
const gchar *domain);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@ -197,13 +182,19 @@ void gtk_builder_add_callback_symbols (GtkBuilder *builder,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GCallback gtk_builder_lookup_callback_symbol (GtkBuilder *builder,
|
||||
const gchar *callback_name);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_builder_set_application (GtkBuilder *builder,
|
||||
GtkApplication *application);
|
||||
|
||||
GClosure * gtk_builder_create_closure (GtkBuilder *builder,
|
||||
const char *function_name,
|
||||
gboolean swapped,
|
||||
GObject *object,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkApplication * gtk_builder_get_application (GtkBuilder *builder);
|
||||
GClosure * gtk_builder_create_cclosure (GtkBuilder *builder,
|
||||
const char *function_name,
|
||||
gboolean swapped,
|
||||
GObject *object,
|
||||
GError **error);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1594,7 +1594,9 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
if (!gtk_buildable_parse_context_parse (&data.ctx, buffer, length, error))
|
||||
goto out;
|
||||
|
||||
_gtk_builder_finish (builder);
|
||||
if (!_gtk_builder_finish (builder, error))
|
||||
goto out;
|
||||
|
||||
if (_gtk_builder_lookup_failed (builder, error))
|
||||
goto out;
|
||||
|
||||
|
@ -175,7 +175,8 @@ void _gtk_builder_add (GtkBuilder *builder,
|
||||
ChildInfo *child_info);
|
||||
void _gtk_builder_add_signals (GtkBuilder *builder,
|
||||
GSList *signals);
|
||||
void _gtk_builder_finish (GtkBuilder *builder);
|
||||
gboolean _gtk_builder_finish (GtkBuilder *builder,
|
||||
GError **error);
|
||||
void _free_signal_info (SignalInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
@ -227,6 +228,7 @@ GObject *_gtk_builder_lookup_object (GtkBuilder *builder,
|
||||
gint col);
|
||||
gboolean _gtk_builder_lookup_failed (GtkBuilder *builder,
|
||||
GError **error);
|
||||
GModule *gtk_builder_get_module (GtkBuilder *builder);
|
||||
|
||||
|
||||
|
||||
|
@ -51,14 +51,12 @@ typedef struct _GtkWidget GtkWidget;
|
||||
typedef struct _GtkWidgetPath GtkWidgetPath;
|
||||
typedef struct _GtkWindow GtkWindow;
|
||||
|
||||
|
||||
typedef void (*GtkBuilderConnectFunc) (GtkBuilder *builder,
|
||||
GObject *object,
|
||||
const gchar *signal_name,
|
||||
const gchar *handler_name,
|
||||
GObject *connect_object,
|
||||
GConnectFlags flags,
|
||||
gpointer user_data);
|
||||
typedef GClosure* (* GtkBuilderClosureFunc) (GtkBuilder *builder,
|
||||
const char *function_name,
|
||||
gboolean swapped,
|
||||
GObject *object,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -490,9 +490,9 @@ typedef struct {
|
||||
GBytes *data;
|
||||
GSList *children;
|
||||
GSList *callbacks;
|
||||
GtkBuilderConnectFunc connect_func;
|
||||
gpointer connect_data;
|
||||
GDestroyNotify destroy_notify;
|
||||
GtkBuilderClosureFunc closure_func;
|
||||
gpointer closure_data;
|
||||
GDestroyNotify closure_destroy;
|
||||
} GtkWidgetTemplate;
|
||||
|
||||
struct _GtkWidgetClassPrivate
|
||||
@ -12027,9 +12027,9 @@ template_data_free (GtkWidgetTemplate *template_data)
|
||||
g_slist_free_full (template_data->children, (GDestroyNotify)template_child_class_free);
|
||||
g_slist_free_full (template_data->callbacks, (GDestroyNotify)callback_symbol_free);
|
||||
|
||||
if (template_data->connect_data &&
|
||||
template_data->destroy_notify)
|
||||
template_data->destroy_notify (template_data->connect_data);
|
||||
if (template_data->closure_data &&
|
||||
template_data->closure_destroy)
|
||||
template_data->closure_destroy (template_data->closure_data);
|
||||
|
||||
g_slice_free (GtkWidgetTemplate, template_data);
|
||||
}
|
||||
@ -12113,6 +12113,24 @@ setup_template_child (GtkWidgetTemplate *template_data,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GClosure *
|
||||
gtk_widget_template_closure_func (GtkBuilder *builder,
|
||||
const char *function_name,
|
||||
gboolean swapped,
|
||||
GObject *object,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
if (object == NULL)
|
||||
object = user_data;
|
||||
|
||||
return gtk_builder_create_cclosure (builder,
|
||||
function_name,
|
||||
swapped,
|
||||
object,
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_init_template:
|
||||
* @widget: a #GtkWidget
|
||||
@ -12154,6 +12172,17 @@ gtk_widget_init_template (GtkWidget *widget)
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
|
||||
/* Setup closure handling. All signal data from a template receive the
|
||||
* template instance as user data automatically.
|
||||
*
|
||||
* A GtkBuilderClosureFunc can be provided to gtk_widget_class_set_signal_closure_func()
|
||||
* in order for templates to be usable by bindings.
|
||||
*/
|
||||
if (template->closure_func)
|
||||
gtk_builder_set_closure_func (builder, template->closure_func, template->closure_data, NULL);
|
||||
else
|
||||
gtk_builder_set_closure_func (builder, gtk_widget_template_closure_func, widget, NULL);
|
||||
|
||||
/* Add any callback symbols declared for this GType to the GtkBuilder namespace */
|
||||
for (l = template->callbacks; l; l = l->next)
|
||||
{
|
||||
@ -12203,17 +12232,6 @@ gtk_widget_init_template (GtkWidget *widget)
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect signals. All signal data from a template receive the
|
||||
* template instance as user data automatically.
|
||||
*
|
||||
* A GtkBuilderConnectFunc can be provided to gtk_widget_class_set_signal_connect_func()
|
||||
* in order for templates to be usable by bindings.
|
||||
*/
|
||||
if (template->connect_func)
|
||||
gtk_builder_connect_signals_full (builder, template->connect_func, template->connect_data);
|
||||
else
|
||||
gtk_builder_connect_signals (builder, object);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
@ -12332,36 +12350,36 @@ gtk_widget_class_bind_template_callback_full (GtkWidgetClass *widget_class,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_class_set_connect_func:
|
||||
* gtk_widget_class_set_closure_func:
|
||||
* @widget_class: A #GtkWidgetClass
|
||||
* @connect_func: The #GtkBuilderConnectFunc to use when connecting signals in the class template
|
||||
* @connect_data: The data to pass to @connect_func
|
||||
* @connect_data_destroy: The #GDestroyNotify to free @connect_data, this will only be used at
|
||||
* @closure_func: The #GtkBuilderClosureFunc to use when creating closure in the class template
|
||||
* @closure_data: The data to pass to @closure_func
|
||||
* @closure_data_destroy: The #GDestroyNotify to free @closure_data, this will only be used at
|
||||
* class finalization time, when no classes of type @widget_type are in use anymore.
|
||||
*
|
||||
* For use in language bindings, this will override the default #GtkBuilderConnectFunc to be
|
||||
* For use in language bindings, this will override the default #GtkBuilderClosureFunc to be
|
||||
* used when parsing GtkBuilder XML from this class’s template data.
|
||||
*
|
||||
* Note that this must be called from a composite widget classes class
|
||||
* initializer after calling gtk_widget_class_set_template().
|
||||
*/
|
||||
void
|
||||
gtk_widget_class_set_connect_func (GtkWidgetClass *widget_class,
|
||||
GtkBuilderConnectFunc connect_func,
|
||||
gpointer connect_data,
|
||||
GDestroyNotify connect_data_destroy)
|
||||
gtk_widget_class_set_closure_func (GtkWidgetClass *widget_class,
|
||||
GtkBuilderClosureFunc closure_func,
|
||||
gpointer closure_data,
|
||||
GDestroyNotify closure_data_destroy)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
|
||||
g_return_if_fail (widget_class->priv->template != NULL);
|
||||
|
||||
/* Defensive, destroy any previously set data */
|
||||
if (widget_class->priv->template->connect_data &&
|
||||
widget_class->priv->template->destroy_notify)
|
||||
widget_class->priv->template->destroy_notify (widget_class->priv->template->connect_data);
|
||||
if (widget_class->priv->template->closure_data &&
|
||||
widget_class->priv->template->closure_destroy)
|
||||
widget_class->priv->template->closure_destroy (widget_class->priv->template->closure_data);
|
||||
|
||||
widget_class->priv->template->connect_func = connect_func;
|
||||
widget_class->priv->template->connect_data = connect_data;
|
||||
widget_class->priv->template->destroy_notify = connect_data_destroy;
|
||||
widget_class->priv->template->closure_func = closure_func;
|
||||
widget_class->priv->template->closure_data = closure_data;
|
||||
widget_class->priv->template->closure_destroy = closure_data_destroy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -956,10 +956,10 @@ void gtk_widget_class_bind_template_callback_full (GtkWidgetClass *
|
||||
const gchar *callback_name,
|
||||
GCallback callback_symbol);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_class_set_connect_func (GtkWidgetClass *widget_class,
|
||||
GtkBuilderConnectFunc connect_func,
|
||||
gpointer connect_data,
|
||||
GDestroyNotify connect_data_destroy);
|
||||
void gtk_widget_class_set_closure_func (GtkWidgetClass *widget_class,
|
||||
GtkBuilderClosureFunc closure_func,
|
||||
gpointer closure_data,
|
||||
GDestroyNotify closure_destroy);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_class_bind_template_child_full (GtkWidgetClass *widget_class,
|
||||
const gchar *name,
|
||||
|
@ -34,7 +34,6 @@ main (int argc, char *argv[])
|
||||
gtk_builder_add_callback_symbol (builder, "back_to_main", G_CALLBACK (back_to_main));
|
||||
gtk_builder_add_callback_symbol (builder, "go_to_secondary", G_CALLBACK (go_to_secondary));
|
||||
gtk_builder_add_from_file (builder, "teststackedheaders.ui", NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
|
||||
win = (GtkWidget *)gtk_builder_get_object (builder, "window");
|
||||
header_stack = (GtkWidget *)gtk_builder_get_object (builder, "header_stack");
|
||||
|
@ -68,7 +68,6 @@ main (int argc, char *argv[])
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_file (builder, filename, NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
g_object_unref (G_OBJECT (builder));
|
||||
|
@ -244,7 +244,6 @@ test_connect_signals (void)
|
||||
"</interface>";
|
||||
|
||||
builder = builder_new_from_string (buffer, -1, NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
|
||||
window = gtk_builder_get_object (builder, "window1");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "test");
|
||||
@ -258,7 +257,6 @@ test_connect_signals (void)
|
||||
g_object_unref (builder);
|
||||
|
||||
builder = builder_new_from_string (buffer_order, -1, NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = gtk_builder_get_object (builder, "window1");
|
||||
normal = 0;
|
||||
gtk_window_set_title (GTK_WINDOW (window), "test");
|
||||
@ -270,7 +268,6 @@ test_connect_signals (void)
|
||||
strlen (buffer_extra), NULL);
|
||||
gtk_builder_add_from_string (builder, buffer_extra2,
|
||||
strlen (buffer_extra2), NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = gtk_builder_get_object (builder, "window2");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "test");
|
||||
g_assert (normal == 30);
|
||||
@ -289,7 +286,6 @@ test_connect_signals (void)
|
||||
|
||||
builder = builder_new_from_string (buffer_after_child, -1, NULL);
|
||||
window = gtk_builder_get_object (builder, "window1");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "test");
|
||||
|
||||
g_assert (normal == 1);
|
||||
@ -2601,7 +2597,6 @@ test_anaconda_signal (void)
|
||||
"</interface>";
|
||||
|
||||
builder = builder_new_from_string (buffer, -1, NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
@ -145,14 +145,13 @@ snapshot_widget (GtkWidget *widget)
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
connect_signals (GtkBuilder *builder,
|
||||
GObject *object,
|
||||
const gchar *signal_name,
|
||||
const gchar *handler_name,
|
||||
GObject *connect_object,
|
||||
GConnectFlags flags,
|
||||
gpointer user_data)
|
||||
static GClosure *
|
||||
create_closure (GtkBuilder *builder,
|
||||
const char *function_name,
|
||||
gboolean swapped,
|
||||
GObject *object,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ReftestModule *module;
|
||||
const char *directory;
|
||||
@ -161,7 +160,7 @@ connect_signals (GtkBuilder *builder,
|
||||
char **split;
|
||||
|
||||
directory = user_data;
|
||||
split = g_strsplit (handler_name, ":", -1);
|
||||
split = g_strsplit (function_name, ":", -1);
|
||||
|
||||
switch (g_strv_length (split))
|
||||
{
|
||||
@ -177,14 +176,20 @@ connect_signals (GtkBuilder *builder,
|
||||
module = reftest_module_new_self ();
|
||||
if (module == NULL)
|
||||
{
|
||||
g_error ("glib compiled without module support.");
|
||||
return;
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION,
|
||||
"glib compiled without module support.");
|
||||
return NULL;
|
||||
}
|
||||
func = reftest_module_lookup (module, split[0]);
|
||||
if (!func)
|
||||
{
|
||||
g_error ("failed to lookup handler for name '%s' when connecting signals", split[0]);
|
||||
return;
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION,
|
||||
"failed to lookup function for name '%s'", split[0]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -194,33 +199,42 @@ connect_signals (GtkBuilder *builder,
|
||||
module = reftest_module_new (directory, split[0]);
|
||||
if (module == NULL)
|
||||
{
|
||||
g_error ("Could not load module '%s' from '%s' when looking up '%s': %s", split[0], directory, handler_name, g_module_error ());
|
||||
return;
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION,
|
||||
"Could not load module '%s' from '%s' when looking up '%s': %s", split[0], directory, function_name, g_module_error ());
|
||||
return NULL;
|
||||
}
|
||||
func = reftest_module_lookup (module, split[1]);
|
||||
if (!func)
|
||||
{
|
||||
g_error ("failed to lookup handler for name '%s' in module '%s'", split[1], split[0]);
|
||||
return;
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION,
|
||||
"failed to lookup function for name '%s' in module '%s'", split[1], split[0]);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_error ("Could not connect signal handler named '%s'", handler_name);
|
||||
return;
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_FUNCTION,
|
||||
"Could not find function named '%s'", function_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_strfreev (split);
|
||||
|
||||
if (connect_object)
|
||||
if (object)
|
||||
{
|
||||
if (flags & G_CONNECT_SWAPPED)
|
||||
closure = g_cclosure_new_object_swap (func, connect_object);
|
||||
if (swapped)
|
||||
closure = g_cclosure_new_object_swap (func, object);
|
||||
else
|
||||
closure = g_cclosure_new_object (func, connect_object);
|
||||
closure = g_cclosure_new_object (func, object);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & G_CONNECT_SWAPPED)
|
||||
if (swapped)
|
||||
closure = g_cclosure_new_swap (func, NULL, NULL);
|
||||
else
|
||||
closure = g_cclosure_new (func, NULL, NULL);
|
||||
@ -229,7 +243,7 @@ connect_signals (GtkBuilder *builder,
|
||||
if (module)
|
||||
g_closure_add_finalize_notifier (closure, module, (GClosureNotify) reftest_module_unref);
|
||||
|
||||
g_signal_connect_closure (object, signal_name, closure, flags & G_CONNECT_AFTER ? TRUE : FALSE);
|
||||
return closure;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
@ -243,12 +257,11 @@ reftest_snapshot_ui_file (const char *ui_file)
|
||||
directory = g_path_get_dirname (ui_file);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_closure_func (builder, create_closure, directory, g_free);
|
||||
gtk_builder_add_from_file (builder, ui_file, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_builder_connect_signals_full (builder, connect_signals, directory);
|
||||
window = builder_get_toplevel (builder);
|
||||
g_object_unref (builder);
|
||||
g_free (directory);
|
||||
g_assert (window);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
Loading…
Reference in New Issue
Block a user