mattn / go-gtk

Go binding for GTK
http://mattn.github.com/go-gtk
BSD 3-Clause "New" or "Revised" License
2.11k stars 247 forks source link

REQ: gtk.Builder: support for attribute "object" in glib.CallbackContext #382

Open pebbe opened 6 years ago

pebbe commented 6 years ago

I tried to convert a simple C example into Go with go-gtk.

Here is the original: Werkzeugleiste.

Here is my Go version: 16werkzeug.go

It has to do with how this fragment is used by the builder:

<signal name="activate" handler="fettschreiben" object="textview" />

The C version uses the simple gtk_builder_connect_signals, without a custom connect function, to set up the signals, and all works fine. The handler receives a pointer to the GtkWidget "textview"

In the Go version, I have to use a custom connect function to get to the "textview" widget from within the handler. Is it possible to include access to such an object from the default context, with something like glib.CallbackContext.GetObject() ?

mattn commented 6 years ago
gtk.WidgetFromObject(ctx.Target().(*glib.GObject))

This is way to get gtk.Widget from event callback context.

pebbe commented 6 years ago

That gives me the widget that made the callback, not the widget the signal is linked to through the "object" attribute.

mattn commented 6 years ago

Do you want API to gtk_builder_get_object ?

pebbe commented 6 years ago

Suppose you got this in your builder interface:

<object class="GtkButton" id="my-button">
  <signal name="clicked" handler="myHandler" swapped="no"/>
</object>

In Go, you can do something like this:

func myHandler(ctx interface{}) {
    widget := gtk.WidgetFromObject(ctx.(*glib.CallbackContext).Target().(*glib.GObject))
    /* ... */
}

But when you have something like this:

<object class="GtkAction" id="fettschrift">
  <signal name="activate" handler="myHandler" object="textview" />
</object>

<object class="GtkTextView" id="textview" />

... and you try the same thing in Go, you get an error:

GLib-GObject-WARNING **: invalid cast from 'GtkAction' to 'GtkWidget'

How, in this case, do I get to the widget "textview"?

In C, the handler simply gets a pointer to "textview" directly. See this example: Werkzeugleiste

mattn commented 6 years ago

The first arguments of ConnectSignalsFull is BuilderConnectFunc.

type BuilderConnectFunc func(builder *Builder, obj *glib.GObject, sig, handler string, conn *glib.GObject, flags glib.ConnectFlags, user_data interface{})

Second argument conn should be the object attribute, as I can see the doc of GtkBuilder.