eb05362005-11-05Henrik Grubbström (Grubba) /* -*- C -*- */
1a05542005-07-28Martin Nilsson require libglade; class GTK2.GladeXML; inherit G.Object; %{ #include <glade/glade.h> /* This function is used by signal_autoconnect to handle signal connection. * Basically it uses a mapping and data from the stack to do signal callbacks * exactly in the same way as normal signals in PiGTK. */
ba9e802006-02-27Martin Stjernholm static void pgtk2__signal_connect(const gchar *handler_name,
1a05542005-07-28Martin Nilsson  GObject *object, const gchar *signal_name, const gchar *signal_data, GObject *connect_object, gboolean after, gpointer args) { struct mapping *callbacks; struct svalue *data; int id; struct signal_data *b; struct svalue *cb; struct pike_string *funname; guint signal_id;
f284492006-08-03Lance Dillon  GClosure *gc;
1a05542005-07-28Martin Nilsson #ifdef GLADE_CONNECT_DEBUG fprintf(stderr,"Connecting handler %s, signal %s,\n data %s, " "after: %d\n", handler_name,signal_name,signal_data,after); #endif get_all_args("GTK2.GladeXML->_signal_connect",*(INT32 *)args, "%m%*",&callbacks,&data); /* funname=make_shared_string(handler_name); cb=low_mapping_string_lookup(callbacks,funname); free_string(funname); */ cb=simple_mapping_string_lookup(callbacks,handler_name); if (cb==NULL) { fprintf(stderr,"** WARNING **: Unknown function %s for signal %s\n", handler_name,signal_name); return; } else if (cb->type!=PIKE_T_FUNCTION) { fprintf(stderr,"** WARNING **: Value for handler %s for signal %s not a function.\n", handler_name,signal_name); return; } b=(struct signal_data *)g_malloc(sizeof(struct signal_data)); if (b==NULL)
32353e2005-12-30Martin Nilsson  Pike_error(msg_out_of_mem);
1a05542005-07-28Martin Nilsson  assign_svalue_no_free(&b->cb,cb); assign_svalue_no_free(&b->args,data); b->signal_id=g_signal_lookup(signal_name,G_TYPE_FROM_INSTANCE(object)); if (!b->signal_id) { g_free(b); fprintf(stderr, "** WARNING **; Signal \"%s\" not defined in the '%s' " "class ancestry.\n", signal_name,g_type_name(G_TYPE_FROM_INSTANCE(object))); }
f284492006-08-03Lance Dillon /*
1a05542005-07-28Martin Nilsson  id=g_signal_connect_data(G_OBJECT(object),signal_name,
ba9e802006-02-27Martin Stjernholm  G_CALLBACK(pgtk2_signal_func_wrapper),b, (GClosureNotify)pgtk2_free_signal_data,
1a05542005-07-28Martin Nilsson  G_CONNECT_SWAPPED);
f284492006-08-03Lance Dillon */ gc=g_cclosure_new_swap(G_CALLBACK(pgtk2_signal_func_wrapper),b, (GClosureNotify)pgtk2_free_signal_data); g_closure_set_marshal(gc,pgtk2_marshaller); id=g_signal_connect_closure(G_OBJECT(object),signal_name,gc,1);
3f16012006-08-29Lance Dillon  g_object_set_data(G_OBJECT(object),"signal-data",b);
1a05542005-07-28Martin Nilsson } %} //! Glade is a free GUI builder for GTK2+ and Gnome. It's normally used to //! create C-code, but can also produce code for other languages. Libglade //! is a utility library that builds the GI from the Glade XML save files. //! This module uses libglade and allows you to easily make GUI designs to be //! used with your Pike applications. void create(string filename_or_buffer, ?int size, ?string root, ?string domain) //! Creates a new GladeXML object (and the corresponding widgets) from the //! XML file. Optionally it will only build the interface from the widget //! node root. This feature is useful if you only want to build say a //! toolbar or menu from the XML file, but not the window it is embedded in. //! Note also that the XML parse tree is cached to speed up creating another //! GladeXML object from the same file. The third optional argument is used to //! specify a different translation domain from the default to be used. //! If xml description is in a string buffer instead, specify the size (or -1 //! to auto-calculate). If size is 0, then it will assume a file with root //! and/or domain specified. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_not_inited(); pgtk2_verify_setup();
1a05542005-07-28Martin Nilsson  {
3d76632005-11-03Lance Dillon  GladeXML *gl;
0e2f102006-08-02Martin Nilsson  struct pike_string *fname; char *root=NULL,*dom=NULL;
cac4202005-12-17Marcus Comstedt  INT_TYPE size=0;
7df7b62006-08-02Henrik Grubbström (Grubba)  get_all_args("create",args,"%n.%i%s%s",&fname,&size,&root,&dom);
1a05542005-07-28Martin Nilsson  if (size==0)
0e2f102006-08-02Martin Nilsson  gl=glade_xml_new(fname->str,root,dom);
7df7b62006-08-02Henrik Grubbström (Grubba)  else if ((size < 0) || (size > fname->len))
0e2f102006-08-02Martin Nilsson  gl=glade_xml_new_from_buffer(fname->str,fname->len,root,dom);
1a05542005-07-28Martin Nilsson  else
0e2f102006-08-02Martin Nilsson  gl=glade_xml_new_from_buffer(fname->str,size,root,dom);
3d76632005-11-03Lance Dillon  THIS->obj=G_OBJECT(gl);
1a05542005-07-28Martin Nilsson  }
ba9e802006-02-27Martin Stjernholm  pgtk2_pop_n_elems(args); pgtk2__init_this_object();
1a05542005-07-28Martin Nilsson }
f284492006-08-03Lance Dillon +GTK2.Widget get_widget(string name)
1a05542005-07-28Martin Nilsson //! This function is used to get the widget corresponding to name in the //! interface description. You would use this if you have to do anything to //! the widget after loading. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { char *name; GtkWidget *widget; get_all_args("get_widget",args,"%s",&name); widget=glade_xml_get_widget(GLADE_XML(THIS->obj),name);
ba9e802006-02-27Martin Stjernholm  pgtk2_pop_n_elems(args);
1a05542005-07-28Martin Nilsson  push_gobject(widget); } } array(GTK2.Widget) get_widget_prefix(string name) //! This function is used to get a list GTK2.Widgets with names that start with //! the string name in the interface description. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { char *name; GList *gl,*g2; int i=0; get_all_args("get_widget_prefix",args,"%s",&name); gl=g2=glade_xml_get_widget_prefix(GLADE_XML(THIS->obj),name);
ba9e802006-02-27Martin Stjernholm  pgtk2_pop_n_elems(args);
1a05542005-07-28Martin Nilsson  while (g2) { push_gobject(g2->data); g_object_ref(g2->data); i++; g2=g_list_next(g2); } f_aggregate(i); g_list_free(gl); } } string get_widget_name(GTK2.Widget widget) //! Used to get the name of a widget that was generated by a GladeXML object. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  { const char *s; struct object *o1; GtkWidget *widget; get_all_args("get_widget_name",args,"%o",&o1); widget=GTK_WIDGET(get_gobject(o1)); if (!widget) Pike_error("GladeXML->get_widget_name: Invalid argument 1, wanted GTK2 object of type WIDGET.\n"); s=glade_get_widget_name(widget);
ba9e802006-02-27Martin Stjernholm  pgtk2_pop_n_elems(args);
1a05542005-07-28Martin Nilsson  push_text(s); g_free((void *)s); } }
3f16012006-08-29Lance Dillon int get_signal_id(GTK2.Widget widget) //! Used to get the signal id attached to a GladeXML object. { pgtk2_verify_inited(); { int id; struct object *o1; GtkWidget *w; struct signal_data *sd; get_all_args("get_signal_id",args,"%o",&o1); w=GTK_WIDGET(get_gobject(o1)); if (!w) Pike_error("GladeXML->get_signal_id: Invalid argument 1, wanted GTK2 object of type WIDGET.\n"); sd=g_object_get_data(G_OBJECT(w),"signal-data"); if (sd) push_int(sd->signal_id); else push_int(-1); } }
1a05542005-07-28Martin Nilsson void signal_autoconnect(mapping(string:function) callbacks, mixed data) //! Try to connect functions to all signals in the interface. The mapping //! should consist of handler name : function pairs. The data argument will //! be saved and sent as the first argument to all callback functions. {
ba9e802006-02-27Martin Stjernholm  pgtk2_verify_inited();
1a05542005-07-28Martin Nilsson  if (args!=2 || Pike_sp[-args].type!=PIKE_T_MAPPING) Pike_error("GTK2.GladeXML->signal_autoconnect: Invalid arguments, expected (mapping,mixed)\n");
ba9e802006-02-27Martin Stjernholm  glade_xml_signal_autoconnect_full(GLADE_XML(THIS->obj),pgtk2__signal_connect,&args);
1a05542005-07-28Martin Nilsson  RETURN_THIS(); } endrequire;