2014-02-16 15:43:48 -06:00
// +build !windows,!darwin,!plan9
// 16 february 2014
2014-03-12 20:55:45 -05:00
2014-02-19 10:41:10 -06:00
package ui
2014-02-16 15:43:48 -06:00
import (
"unsafe"
)
/ *
cgo doesn ' t support calling Go functions by default ; we have to mark them for export . Not a problem , except arguments to GTK + callbacks depend on the callback itself . Since we ' re generating callback functions as simple closures of one type , this file will wrap the generated callbacks in the appropriate callback type . We pass the actual generated pointer to the extra data parameter of the callback .
2014-02-16 16:09:58 -06:00
2014-03-12 19:00:29 -05:00
while we ' re at it the callback for our idle function will be handled here too
2014-02-16 15:43:48 -06:00
* /
2014-03-16 09:34:12 -05:00
// #include "gtk_unix.h"
2014-03-14 19:03:02 -05:00
// extern gboolean our_window_delete_event_callback(GtkWidget *, GdkEvent *, gpointer);
// extern gboolean our_window_configure_event_callback(GtkWidget *, GdkEvent *, gpointer);
// extern void our_button_clicked_callback(GtkButton *, gpointer);
// /* because cgo is flaky with macros; static inline because we have //exports */
// static inline void gSignalConnect(GtkWidget *widget, char *signal, GCallback callback, void *data) { g_signal_connect(widget, signal, callback, data); }
2014-02-16 15:43:48 -06:00
import "C"
2014-03-14 19:03:02 -05:00
//export our_window_delete_event_callback
func our_window_delete_event_callback ( widget * C . GtkWidget , event * C . GdkEvent , what C . gpointer ) C . gboolean {
// called when the user tries to close the window
s := ( * sysData ) ( unsafe . Pointer ( what ) )
2014-07-01 08:44:57 -05:00
return togbool ( ! s . close ( ) ) // ! because TRUE means don't close
2014-02-16 15:43:48 -06:00
}
2014-03-14 19:03:02 -05:00
var window_delete_event_callback = C . GCallback ( C . our_window_delete_event_callback )
//export our_window_configure_event_callback
func our_window_configure_event_callback ( widget * C . GtkWidget , event * C . GdkEvent , what C . gpointer ) C . gboolean {
// called when the window is resized
s := ( * sysData ) ( unsafe . Pointer ( what ) )
2014-06-25 22:44:22 -05:00
if s . container != nil && s . allocate != nil { // wait for init
2014-03-14 19:03:02 -05:00
width , height := gtk_window_get_size ( s . widget )
2014-06-25 22:44:22 -05:00
// top-left is (0,0) here
s . resizeWindow ( width , height )
2014-03-14 19:03:02 -05:00
}
2014-06-02 21:07:50 -05:00
// no need to manually redraw everything: since we use gtk_widget_set_size_request(), that queues both resize and redraw for us (thanks Company in irc.gimp.net/#gtk+)
2014-06-10 13:59:39 -05:00
return C . FALSE // continue the event chain
2014-03-14 19:03:02 -05:00
}
var window_configure_event_callback = C . GCallback ( C . our_window_configure_event_callback )
//export our_button_clicked_callback
func our_button_clicked_callback ( button * C . GtkButton , what C . gpointer ) {
// called when the user clicks a button
s := ( * sysData ) ( unsafe . Pointer ( what ) )
2014-06-30 21:48:12 -05:00
s . event ( )
2014-03-14 19:03:02 -05:00
}
var button_clicked_callback = C . GCallback ( C . our_button_clicked_callback )
// this is the type of the signals fields in classData; here to avoid needing to import C
type callbackMap map [ string ] C . GCallback
// this is what actually connects a signal
2014-04-01 15:30:38 -05:00
func g_signal_connect ( obj * C . GtkWidget , sig string , callback C . GCallback , sysData * sysData ) {
2014-03-14 19:03:02 -05:00
csig := C . CString ( sig )
defer C . free ( unsafe . Pointer ( csig ) )
2014-04-01 15:30:38 -05:00
C . gSignalConnect ( obj , csig , callback , unsafe . Pointer ( sysData ) )
2014-02-16 16:09:58 -06:00
}
2014-06-08 10:50:11 -05:00
func g_signal_connect_pointer ( obj * C . GtkWidget , sig string , callback C . GCallback , p unsafe . Pointer ) {
csig := C . CString ( sig )
defer C . free ( unsafe . Pointer ( csig ) )
C . gSignalConnect ( obj , csig , callback , p )
}