Implemented the Window OnClosing() event on GTK+. It works!
This commit is contained in:
parent
be56707c51
commit
60d0953fe9
|
@ -7,6 +7,11 @@ import (
|
|||
)
|
||||
|
||||
// #include "gtk_unix.h"
|
||||
// /* because cgo doesn't like g_signal_connect() */
|
||||
// void gSignalConnect(gpointer obj, gchar *sig, GCallback callback, gpointer data)
|
||||
// {
|
||||
// g_signal_connect(obj, sig, callback, data);
|
||||
// }
|
||||
import "C"
|
||||
|
||||
func fromgstr(s *C.gchar) string {
|
||||
|
@ -20,3 +25,9 @@ func togstr(s string) *C.gchar {
|
|||
func freegstr(s *C.gchar) {
|
||||
C.free(unsafe.Pointer(s))
|
||||
}
|
||||
|
||||
func g_signal_connect(object C.gpointer, name string, to C.GCallback, data C.gpointer) {
|
||||
cname := togstr(name)
|
||||
defer freegstr(cname)
|
||||
C.gSignalConnect(object, cname, to, data)
|
||||
}
|
||||
|
|
|
@ -45,10 +45,23 @@ type event struct {
|
|||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// do should never be nil; TODO should we make setters panic instead?
|
||||
|
||||
func newEvent() *event {
|
||||
return &event{
|
||||
do: func(c Doer) bool {
|
||||
return false
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (e *event) set(f func(Doer)) {
|
||||
e.lock.Lock()
|
||||
defer e.lock.Unlock()
|
||||
|
||||
if f == nil {
|
||||
f = func(c Doer) {}
|
||||
}
|
||||
e.do = func(c Doer) bool {
|
||||
f(c)
|
||||
return false
|
||||
|
@ -59,6 +72,11 @@ func (e *event) setbool(f func(Doer) bool) {
|
|||
e.lock.Lock()
|
||||
defer e.lock.Unlock()
|
||||
|
||||
if f == nil {
|
||||
f = func(c Doer) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
e.do = f
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
)
|
||||
|
||||
// #include "gtk_unix.h"
|
||||
// extern gboolean windowClosing(GtkWidget *, GdkEvent *, gpointer);
|
||||
import "C"
|
||||
|
||||
type window struct {
|
||||
|
@ -14,6 +15,8 @@ type window struct {
|
|||
container *C.GtkContainer
|
||||
bin *C.GtkBin
|
||||
window *C.GtkWindow
|
||||
|
||||
closing *event
|
||||
}
|
||||
|
||||
func newWindow(title string, width int, height int) *Request {
|
||||
|
@ -28,8 +31,14 @@ func newWindow(title string, width int, height int) *Request {
|
|||
container: (*C.GtkContainer)(unsafe.Pointer(widget)),
|
||||
bin: (*C.GtkBin)(unsafe.Pointer(widget)),
|
||||
window: (*C.GtkWindow)(unsafe.Pointer(widget)),
|
||||
closing: newEvent(),
|
||||
}
|
||||
C.gtk_window_set_title(w.window, ctitle)
|
||||
g_signal_connect(
|
||||
C.gpointer(unsafe.Pointer(w.window)),
|
||||
"delete-event",
|
||||
C.GCallback(C.windowClosing),
|
||||
C.gpointer(unsafe.Pointer(w)))
|
||||
// TODO size
|
||||
// TODO content
|
||||
c <- w
|
||||
|
@ -108,6 +117,22 @@ func (w *window) Close() *Request {
|
|||
}
|
||||
|
||||
func (w *window) OnClosing(e func(c Doer) bool) *Request {
|
||||
// TODO
|
||||
return nil
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
w.closing.setbool(e)
|
||||
c <- struct{}{}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
//export windowClosing
|
||||
func windowClosing(wid *C.GtkWidget, e *C.GdkEvent, data C.gpointer) C.gboolean {
|
||||
w := (*window)(unsafe.Pointer(data))
|
||||
close := w.closing.fire()
|
||||
if close {
|
||||
return C.GDK_EVENT_PROPAGATE // will do gtk_widget_destroy(), which is what we want (thanks ebassi in irc.gimp.net/#gtk+)
|
||||
}
|
||||
return C.GDK_EVENT_STOP // keeps window alive
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ func TestPackage(t *testing.T) {
|
|||
go func() {
|
||||
w := GetNewWindow(Do, "Hello", 320, 240)
|
||||
done := make(chan struct{})
|
||||
// Wait(Do, w.OnClosing(func(Doer) bool {
|
||||
// done <- struct{}{}
|
||||
// return true
|
||||
// }))
|
||||
Wait(Do, w.OnClosing(func(Doer) bool {
|
||||
done <- struct{}{}
|
||||
return true
|
||||
}))
|
||||
Wait(Do, w.Show())
|
||||
<-done
|
||||
}()
|
||||
|
|
Loading…
Reference in New Issue