[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