diff --git a/area_unix.go b/area_unix.go index aacccaf..f9c898f 100644 --- a/area_unix.go +++ b/area_unix.go @@ -16,7 +16,7 @@ import ( // #define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_4 // #define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_4 // #include -// extern gboolean our_draw_callback(GtkWidget *, cairo_t *, gpointer); +// extern gboolean our_area_draw_callback(GtkWidget *, cairo_t *, gpointer); // /* HACK - see https://code.google.com/p/go/issues/detail?id=7548 */ // struct _cairo {}; import "C" @@ -30,8 +30,14 @@ func gtkAreaNew() *gtkWidget { return fromgtkwidget(scrollarea) } -//export our_draw_callback -func our_draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) C.gboolean { +func gtkAreaGetControl(scrollarea *gtkWidget) *gtkWidget { + viewport := C.gtk_bin_get_child((*C.GtkBin)(unsafe.Pointer(scrollarea))) + control := C.gtk_bin_get_child((*C.GtkBin)(unsafe.Pointer(viewport))) + return fromgtkwidget(control) +} + +//export our_area_draw_callback +func our_area_draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) C.gboolean { var x, y, w, h C.double s := (*sysData)(unsafe.Pointer(data)) @@ -64,4 +70,4 @@ func our_draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) C.gb return C.FALSE // signals handled without stopping the event chain (thanks to desrt again) } -var draw_callback = C.GCallback(C.our_draw_callback) +var area_draw_callback = C.GCallback(C.our_area_draw_callback) diff --git a/implementation.md b/implementation.md index 9fa1341..2bd4232 100644 --- a/implementation.md +++ b/implementation.md @@ -49,7 +49,7 @@ As the GTK+ main loop system does not quite run in a sane way (it allows recursi GTK+ layout managers are not used since the UI library's layout managers are coded in a portable way. (`GtkFixed` is used instead.) This isn't ideal, but it works for now. -All event handlers take the `sysData` as their user data parameter; this means all the event-handling code is stored in static functions in callbacks_unix.go. (Early versions of the package generated signal handlers for each control on the fly, but this needed to be changed to accommodoate Area, which not only needs the `sysData` but also needs to connect to a subwidget of a subwidget (specifically the subwidget of the `GtkViewport` of a `GtkScrolledWindow`); the current setup also avoids creating closures for each and every Window and Button created, and also means we can stop having to shove those callbacks in an ever-growing slice to prevent them from being garbage collected.) +All event handlers take the `sysData` as their user data parameter; this means all the event-handling code is stored in static functions in callbacks_unix.go. (Early versions of the package generated signal handlers for each control on the fly, but this needed to be changed to accommodoate Area, which not only needs the `sysData` but also needs to connect to a subwidget of a subwidget (specifically the subwidget of the `GtkViewport` of a `GtkScrolledWindow`); the current setup also avoids creating closures for each and every Window and Button created, and also means we can stop having to shove those callbacks in an ever-growing slice to prevent them from being garbage collected.) Should the widget actually be a child widget of a `GtkScrolledWindow`, the `child` function and `childsigs` signal list are used to assign signals as well. The only major snag with the GTK+ implementation is the implementation of `Listbox`; see `listbox_unix.go` for details. diff --git a/sysdata_unix.go b/sysdata_unix.go index 7a14ae9..8d753da 100644 --- a/sysdata_unix.go +++ b/sysdata_unix.go @@ -30,6 +30,8 @@ type classData struct { len func(widget *gtkWidget) int // ... signals callbackMap + child func(widget *gtkWidget) *gtkWidget + childsigs callbackMap } var classTypes = [nctypes]*classData{ @@ -94,6 +96,10 @@ var classTypes = [nctypes]*classData{ }, c_area: &classData{ make: gtkAreaNew, + child: gtkAreaGetControl, + childsigs: callbackMap{ + "draw": area_draw_callback, + }, }, } @@ -127,6 +133,12 @@ func (s *sysData) make(initText string, window *sysData) error { for signame, sigfunc := range ct.signals { g_signal_connect(s.widget, signame, sigfunc, s) } + if ct.child != nil { + child := ct.child(s.widget) + for signame, sigfunc := range ct.childsigs { + g_signal_connect(child, signame, sigfunc, s) + } + } ret <- nil } <-ret