/* -*- c-file-style: "ruby" -*- */ /************************************************ rbgtkbuilder.c - Copyright (C) 2008 Ruby-GNOME2 Project Team ************************************************/ #include "global.h" #include /* From Ruby/GLib2 */ #if GTK_CHECK_VERSION(2, 12, 0) #define _SELF(self) (GTK_BUILDER(RVAL2GOBJ(self))) static ID id___connect_signals__; static void builder_mark(gpointer object) { GtkBuilder *builder = object; GSList *objects; objects = gtk_builder_get_objects(builder); g_slist_foreach(objects, (GFunc)rbgobj_gc_mark_instance, NULL); g_slist_free(objects); } static VALUE builder_initialize(VALUE self) { GtkBuilder *builder; builder = gtk_builder_new(); G_INITIALIZE(self, builder); return Qnil; } static VALUE builder_add_from_file(VALUE self, VALUE filename) { GError *error = NULL; if (gtk_builder_add_from_file(_SELF(self), RVAL2CSTR(filename), &error) == 0) RAISE_GERROR(error); return self; } static VALUE builder_add_from_string(VALUE self, VALUE string) { GError *error = NULL; if (gtk_builder_add_from_string(_SELF(self), RVAL2CSTR(string), RSTRING_LEN(string), &error) == 0) RAISE_GERROR(error); return self; } static VALUE builder_add(VALUE self, VALUE filename_or_xml) { const char xml_detect_re_str[] = "(?:\\A<|[\\r\\n])"; VALUE xml_detect_re; xml_detect_re = rb_reg_new(xml_detect_re_str, strlen(xml_detect_re_str), 0); if (NIL_P(rb_reg_match(xml_detect_re, filename_or_xml))) return builder_add_from_file(self, filename_or_xml); else return builder_add_from_string(self, filename_or_xml); } static VALUE builder_get_object(VALUE self, VALUE name) { return GOBJ2RVAL(gtk_builder_get_object(_SELF(self), RVAL2CSTR(name))); } static VALUE builder_get_objects(VALUE self) { return GSLIST2ARY_FREE(gtk_builder_get_objects(_SELF(self))); } static void connect_signals(GtkBuilder *builder, GObject *object, const gchar *signal_name, const gchar *handler_name, GObject *connect_object, GConnectFlags flags, gpointer user_data) { VALUE signal_connector = (VALUE)user_data; rb_funcall(GOBJ2RVAL(builder), id___connect_signals__, 6, signal_connector, GOBJ2RVAL(object), CSTR2RVAL(signal_name), CSTR2RVAL(handler_name), GOBJ2RVAL(connect_object), GFLAGS2RVAL(flags, G_TYPE_CONNECT_FLAGS)); } static VALUE builder_connect_signals(VALUE self) { VALUE signal_connector; signal_connector = rb_block_proc(); G_CHILD_ADD(self, signal_connector); gtk_builder_connect_signals_full(_SELF(self), connect_signals, (gpointer)signal_connector); G_CHILD_REMOVE(self, signal_connector); return self; } static VALUE builder_get_type_from_name(VALUE self, VALUE name) { return GTYPE2CLASS(gtk_builder_get_type_from_name(_SELF(self), RVAL2CSTR(name))); } #endif void Init_gtk_builder() { #if GTK_CHECK_VERSION(2, 12, 0) VALUE gBuilder; id___connect_signals__ = rb_intern("__connect_signals__"); gBuilder = G_DEF_CLASS_WITH_GC_FUNC(GTK_TYPE_BUILDER, "Builder", mGtk, builder_mark, NULL); G_DEF_CLASS(GTK_TYPE_BUILDER_ERROR, "BuilderError", mGtk); rb_define_method(gBuilder, "initialize", builder_initialize, 0); rb_define_method(gBuilder, "add_from_file", builder_add_from_file, 1); rb_define_method(gBuilder, "add_from_string", builder_add_from_string, 1); rb_define_method(gBuilder, "add", builder_add, 1); rb_define_alias(gBuilder, "<<", "add"); rb_define_method(gBuilder, "get_object", builder_get_object, 1); rb_define_alias(gBuilder, "[]", "get_object"); rb_define_method(gBuilder, "objects", builder_get_objects, 0); rb_define_method(gBuilder, "connect_signals", builder_connect_signals, 0); rb_define_method(gBuilder, "get_type", builder_get_type_from_name, 1); #endif }