[Gtk-sharp-list] UIManager, et. al.

Jeroen Zwartepoorte jeroen@xs4all.nl
Mon, 12 Apr 2004 21:05:08 +0200


Hi Artum,

You might be interested to know that preliminary support for GTK 2.4 is
available on a branch of gtk-sharp: jeroen-gtk-2-4. The branch has
support for GtkUIManager amongst other new classes. Take a look at the
actions.cs sample.

Regards,

Jeroen

On Sat, 2004-04-10 at 13:44 +0700, Artem Popov wrote:

> Hello, I've recently been playing with gtk 2.4 stuff and tried wrapping
> the new UIManager api (wrapper attached). I ran into a problem described
> below (sorry for the long message).
> 
> this code worked as expected:
> 
> 	action = new Action ("Save", "_Save", "", Gtk.Stock.Save);
> 	action_group.AddAction (action);
> 	action.Activated += new EventHandler (ActionHandler);
> 
> But I wanted to create actions from struct arrays like this:
> 
> 	ActionEntry[] actions =  {
> 	new ActionEntry ("Open", ... , callback),
> 	new ActionEntry ("Save", ... , callback),
> 	};
> 	...
> 	action_group.AddActions (actions);
> 
> At first, that didn't work, because the generator didn't add GCallback
> field in ActionEntry structs (there was an "unknown type: GCallback"
> warning), so the structs in arrays with more than 1 struct were
> "shifted". As a workaround (for the generator to know about GCallback)
> I've created a delegate like this:
> 
> 	namespace GLib { public delegate void Callback (); }
> 
> gclosure.h declares GCallback as typedef void (*GCallback) (void);
> 
> (in symbols):
> <symbol type="manual" cname="GCallback" name="GLib.Callback"/>
> 
> I've also written custom versions of Add*Actions. Works well, but it's
> impossible to create one callback for several actions. gtk-demo makes it
> this way:
> 
> 	static void activate_action (GtkAction *action) {...}
> 	static void activate_radio_action (GtkAction *action, GtkRadioAction
> *current)
> 	{...}
> 	static GtkActionEntry entries[] = {
> 		{ "New", ... , G_CALLBACK (activate_action) },
> 		...
> 	}
> 	...
> 	gtk_action_group_add_radio_actions (..., G_CALLBACK
> (activate_radio_action), NULL);
> 	...
> 
> See, here function with args is casted to (supposedly argless) GCallback
> and the callback knows its action well. To allow simular behavior, I
> pointed the generator to pass GCallback as a generic delegate:
> <symbol type="manual" cname="GCallback" name="System.Delegate"/>
> 
> This allows to run (working) code like this:
> 	delegate void ActionCallback (IntPtr handle);
> 	static void cb ()
> 	{ ... }
> 	static void cb2 (IntPtr handle)
> 	{ Action action = new Action (handle); ... }
> 	
> 	ActionEntry[] actions =  {
> 		new ActionEntry (..., new GLib.Callback (cb)),
> 		new ActionEntry (..., new ActionCallback (cb2)),
> 	};
> 
> >From the gtk-demo it seems there also may be a delegate for (Action,
> RadioAction) args, but as you can see they're passed as IntPtrs in the
> code above.
> 
> Now I want the callbacks to be "real" ones with "Action" or object args.
> And I don't want to have lots of "void-(void)" functions for every
> imaginable task. I beleive there's a smart way to do this, but I don't
> know gtk# internals well and probably I missed anything?
> 
> --Artem