Started dropping the whole request/response system because it fell apart... time to make a ui.Do(func(){ ... })

This commit is contained in:
Pietro Gagliardi 2014-07-19 09:44:32 -04:00
parent 47c0f573a9
commit 48c5055eb9
8 changed files with 202 additions and 460 deletions

View File

@ -16,24 +16,15 @@ type Control interface {
type Button interface { type Button interface {
Control Control
// OnClicked creates a Request to set the event handler for when the Button is clicked. // OnClicked sets the event handler for when the Button is clicked.
OnClicked(func(d Doer)) *Request OnClicked(func())
// Text and SetText creates a Request that get and set the Button's label text. // Text and SetText get and set the Button's label text.
Text() *Request Text() string
SetText(text string) *Request SetText(text string)
} }
// NewButton creates a Request to create a new Button with the given label text. // NewButton creates a new Button with the given label text.
func NewButton(text string) *Request { func NewButton(text string) {
return newButton(text) return newButton(text)
} }
// GetNewButton is like NewButton but sends the Request along the given Doer and returns the resultant Button.
// Example:
// b := ui.GetNewButton(ui.Do, "OK")
func GetNewButton(c Doer, text string) Button {
req := newButton(text)
c <- req
return (<-req.resp).(Button)
}

View File

@ -50,10 +50,7 @@ type button struct {
clicked *event clicked *event
} }
func newButton(text string) *Request { func newButton(text string) *button {
c := make(chan interface{})
return &Request{
op: func() {
ctext := C.CString(text) ctext := C.CString(text)
defer C.free(unsafe.Pointer(ctext)) defer C.free(unsafe.Pointer(ctext))
b := &button{ b := &button{
@ -61,21 +58,11 @@ func newButton(text string) *Request {
clicked: newEvent(), clicked: newEvent(),
} }
C.buttonSetDelegate(b.id, unsafe.Pointer(b)) C.buttonSetDelegate(b.id, unsafe.Pointer(b))
c <- b return b
},
resp: c,
}
} }
func (b *button) OnClicked(e func(c Doer)) *Request { func (b *button) OnClicked(e func()) {
c := make(chan interface{})
return &Request{
op: func() {
b.clicked.set(e) b.clicked.set(e)
c <- struct{}{}
},
resp: c,
}
} }
//export buttonClicked //export buttonClicked
@ -85,25 +72,12 @@ func buttonClicked(xb unsafe.Pointer) {
println("button clicked") println("button clicked")
} }
func (b *button) Text() *Request { func (b *button) Text() string {
c := make(chan interface{}) return C.GoString(C.buttonText(b.id))
return &Request{
op: func() {
c <- C.GoString(C.buttonText(b.id))
},
resp: c,
}
} }
func (b *button) SetText(text string) *Request { func (b *button) SetText(text string) {
c := make(chan interface{})
return &Request{
op: func() {
ctext := C.CString(text) ctext := C.CString(text)
defer C.free(unsafe.Pointer(ctext)) defer C.free(unsafe.Pointer(ctext))
C.buttonSetText(b.id, ctext) C.buttonSetText(b.id, ctext)
c <- struct{}{}
},
resp: c,
}
} }

View File

@ -53,10 +53,7 @@ type button struct {
clicked *event clicked *event
} }
func newButton(text string) *Request { func newButton(text string) *button {
c := make(chan interface{})
return &Request{
op: func() {
ctext := togstr(text) ctext := togstr(text)
defer freegstr(ctext) defer freegstr(ctext)
widget := C.gtk_button_new_with_label(ctext) widget := C.gtk_button_new_with_label(ctext)
@ -70,21 +67,11 @@ func newButton(text string) *Request {
"clicked", "clicked",
C.GCallback(C.buttonClicked), C.GCallback(C.buttonClicked),
C.gpointer(unsafe.Pointer(b))) C.gpointer(unsafe.Pointer(b)))
c <- b return b
},
resp: c,
}
} }
func (b *button) OnClicked(e func(c Doer)) *Request { func (b *button) OnClicked(e func()) {
c := make(chan interface{})
return &Request{
op: func() {
b.clicked.set(e) b.clicked.set(e)
c <- struct{}{}
},
resp: c,
}
} }
//export buttonClicked //export buttonClicked
@ -94,25 +81,12 @@ func buttonClicked(bwid *C.GtkButton, data C.gpointer) {
println("button clicked") println("button clicked")
} }
func (b *button) Text() *Request { func (b *button) Text() string {
c := make(chan interface{}) return fromgstr(C.gtk_button_get_label(b.button))
return &Request{
op: func() {
c <- fromgstr(C.gtk_button_get_label(b.button))
},
resp: c,
}
} }
func (b *button) SetText(text string) *Request { func (b *button) SetText(text string) {
c := make(chan interface{})
return &Request{
op: func() {
ctext := togstr(text) ctext := togstr(text)
defer freegstr(ctext) defer freegstr(ctext)
C.gtk_button_set_label(b.button, ctext) C.gtk_button_set_label(b.button, ctext)
c <- struct{}{}
},
resp: c,
}
} }

View File

@ -31,25 +31,12 @@ func (w *widgetbase) parent(win *window) {
// don't embed these as exported; let each Control decide if it should // don't embed these as exported; let each Control decide if it should
func (w *widgetbase) text() *Request { func (w *widgetbase) text() string {
c := make(chan interface{}) return getWindowText(w.hwnd)
return &Request{
op: func() {
c <- getWindowText(w.hwnd)
},
resp: c,
}
} }
func (w *widgetbase) settext(text string) *Request { func (w *widgetbase) settext(text string) {
c := make(chan interface{})
return &Request{
op: func() {
C.setWindowText(w.hwnd, toUTF16(text)) C.setWindowText(w.hwnd, toUTF16(text))
c <- struct{}{}
},
resp: c,
}
} }
type button struct { type button struct {
@ -59,9 +46,7 @@ type button struct {
var buttonclass = toUTF16("BUTTON") var buttonclass = toUTF16("BUTTON")
func newButton(text string) *Request { func newButton(text string) *button {
c := make(chan interface{})
return &Request{
op: func() { op: func() {
w := newWidget(buttonclass, w := newWidget(buttonclass,
C.BS_PUSHBUTTON | C.WS_TABSTOP, C.BS_PUSHBUTTON | C.WS_TABSTOP,
@ -73,28 +58,18 @@ func newButton(text string) *Request {
clicked: newEvent(), clicked: newEvent(),
} }
C.setButtonSubclass(w.hwnd, unsafe.Pointer(b)) C.setButtonSubclass(w.hwnd, unsafe.Pointer(b))
c <- b return b
},
resp: c,
}
} }
func (b *button) OnClicked(e func(c Doer)) *Request { func (b *button) OnClicked(e func()) {
c := make(chan interface{})
return &Request{
op: func() {
b.clicked.set(e) b.clicked.set(e)
c <- struct{}{}
},
resp: c,
}
} }
func (b *button) Text() *Request { func (b *button) Text() string {
return b.text() return b.text()
} }
func (b *button) SetText(text string) *Request { func (b *button) SetText(text string) {
return b.settext(text) return b.settext(text)
} }

View File

@ -6,41 +6,32 @@ package ui
// Windows in package ui can only contain one control; the Stack and Grid layout Controls allow you to pack multiple Controls in a Window. // Windows in package ui can only contain one control; the Stack and Grid layout Controls allow you to pack multiple Controls in a Window.
// Note that a Window is not itself a Control. // Note that a Window is not itself a Control.
type Window interface { type Window interface {
// SetControl creates a Request to the Window's child Control. // SetControl sets the Window's child Control.
SetControl(c Control) *Request SetControl(c Control)
// Title and SetTitle create Requests to get and set the Window's title, respectively. // Title and SetTitle get and set the Window's title, respectively.
Title() *Request Title() string
SetTitle(title string) *Request SetTitle(title string)
// Show and Hide create Requests to bring the Window on-screen and off-screen, respectively. // Show and Hide bring the Window on-screen and off-screen, respectively.
Show() *Request Show()
Hide() *Request Hide()
// Close creates a Request to close the Window. // Close closes the Window.
// Any Controls within the Window are destroyed, and the Window itself is also destroyed. // Any Controls within the Window are destroyed, and the Window itself is also destroyed.
// Attempting to use a Window after it has been closed results in undefined behavior. // Attempting to use a Window after it has been closed results in undefined behavior.
// Close unconditionally closes the Window; it neither raises OnClosing nor checks for a return from OnClosing. // Close unconditionally closes the Window; it neither raises OnClosing nor checks for a return from OnClosing.
// TODO make sure the above happens on GTK+ and Mac OS X; it does on Windows // TODO make sure the above happens on GTK+ and Mac OS X; it does on Windows
Close() *Request Close()
// OnClosing creates a Request to register an event handler that is triggered when the user clicks the Window's close button. // OnClosing registers an event handler that is triggered when the user clicks the Window's close button.
// On systems where whole applications own windows, OnClosing is also triggered when the user asks to close the application. // On systems where whole applications own windows, OnClosing is also triggered when the user asks to close the application.
// If this handler returns true, the Window is closed as defined by Close above. // If this handler returns true, the Window is closed as defined by Close above.
// If this handler returns false, the Window is not closed. // If this handler returns false, the Window is not closed.
OnClosing(func(c Doer) bool) *Request OnClosing(func() bool)
} }
// NewWindow returns a Request to create a new Window with the given title text and size. // NewWindow creates a new Window with the given title text and size.
func NewWindow(title string, width int, height int) *Request { func NewWindow(title string, width int, height int) Window {
return newWindow(title, width, height) return newWindow(title, width, height)
} }
// GetNewWindow is like NewWindow but sends the Request along the given Doer and returns the resultant Window.
// Example:
// w := ui.GetNewWindow(ui.Do, "Main Window")
func GetNewWindow(c Doer, title string, width int, height int) Window {
req := newWindow(title, width, height)
c <- req
return (<-req.resp).(Window)
}

View File

@ -20,10 +20,7 @@ type window struct {
spaced bool spaced bool
} }
func newWindow(title string, width int, height int) *Request { func newWindow(title string, width int, height int) *window {
c := make(chan interface{})
return &Request{
op: func() {
id := C.newWindow(C.intptr_t(width), C.intptr_t(height)) id := C.newWindow(C.intptr_t(width), C.intptr_t(height))
ctitle := C.CString(title) ctitle := C.CString(title)
defer C.free(unsafe.Pointer(ctitle)) defer C.free(unsafe.Pointer(ctitle))
@ -33,93 +30,42 @@ func newWindow(title string, width int, height int) *Request {
closing: newEvent(), closing: newEvent(),
} }
C.windowSetDelegate(id, unsafe.Pointer(w)) C.windowSetDelegate(id, unsafe.Pointer(w))
c <- w return w
},
resp: c,
}
} }
func (w *window) SetControl(control Control) *Request { func (w *window) SetControl(control Control) {
c := make(chan interface{})
return &Request{
op: func() {
if w.child != nil { // unparent existing control if w.child != nil { // unparent existing control
w.child.unparent() w.child.unparent()
} }
control.unparent() control.unparent()
control.parent(w) control.parent(w)
w.child = control w.child = control
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Title() *Request { func (w *window) Title() string {
c := make(chan interface{}) return C.GoString(C.windowTitle(w.id))
return &Request{
op: func() {
c <- C.GoString(C.windowTitle(w.id))
},
resp: c,
}
} }
func (w *window) SetTitle(title string) *Request { func (w *window) SetTitle(title string) {
c := make(chan interface{})
return &Request{
op: func() {
ctitle := C.CString(title) ctitle := C.CString(title)
defer C.free(unsafe.Pointer(ctitle)) defer C.free(unsafe.Pointer(ctitle))
C.windowSetTitle(w.id, ctitle) C.windowSetTitle(w.id, ctitle)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Show() *Request { func (w *window) Show() {
c := make(chan interface{})
return &Request{
op: func() {
C.windowShow(w.id) C.windowShow(w.id)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Hide() *Request { func (w *window) Hide() {
c := make(chan interface{})
return &Request{
op: func() {
C.windowHide(w.id) C.windowHide(w.id)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Close() *Request { func (w *window) Close() {
c := make(chan interface{})
return &Request{
op: func() {
C.windowClose(w.id) C.windowClose(w.id)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) OnClosing(e func(c Doer) bool) *Request { func (w *window) OnClosing(e func() bool) {
c := make(chan interface{})
return &Request{
op: func() {
w.closing.setbool(e) w.closing.setbool(e)
c <- struct{}{}
},
resp: c,
}
} }
//export windowClosing //export windowClosing

View File

@ -30,10 +30,7 @@ type window struct {
spaced bool spaced bool
} }
func newWindow(title string, width int, height int) *Request { func newWindow(title string, width int, height int) *window {
c := make(chan interface{})
return &Request{
op: func() {
widget := C.gtk_window_new(C.GTK_WINDOW_TOPLEVEL) widget := C.gtk_window_new(C.GTK_WINDOW_TOPLEVEL)
ctitle := togstr(title) ctitle := togstr(title)
defer freegstr(ctitle) defer freegstr(ctitle)
@ -64,94 +61,42 @@ func newWindow(title string, width int, height int) *Request {
C.gpointer(unsafe.Pointer(w))) C.gpointer(unsafe.Pointer(w)))
// TODO size // TODO size
C.gtk_container_add(w.container, layoutw) C.gtk_container_add(w.container, layoutw)
c <- w return w
},
resp: c,
}
} }
func (w *window) SetControl(control Control) *Request { func (w *window) SetControl(control Control) {
c := make(chan interface{})
return &Request{
op: func() {
if w.child != nil { // unparent existing control if w.child != nil { // unparent existing control
w.child.unparent() w.child.unparent()
} }
control.unparent() control.unparent()
control.parent(w) control.parent(w)
w.child = control w.child = control
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Title() *Request { func (w *window) Title() string {
c := make(chan interface{}) return fromgstr(C.gtk_window_get_title(w.window))
return &Request{
op: func() {
c <- fromgstr(C.gtk_window_get_title(w.window))
},
resp: c,
}
} }
func (w *window) SetTitle(title string) *Request { func (w *window) SetTitle(title string) {
c := make(chan interface{})
return &Request{
op: func() {
ctitle := togstr(title) ctitle := togstr(title)
defer freegstr(ctitle) defer freegstr(ctitle)
C.gtk_window_set_title(w.window, ctitle) C.gtk_window_set_title(w.window, ctitle)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Show() {
func (w *window) Show() *Request {
c := make(chan interface{})
return &Request{
op: func() {
C.gtk_widget_show_all(w.widget) C.gtk_widget_show_all(w.widget)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Hide() *Request { func (w *window) Hide() {
c := make(chan interface{})
return &Request{
op: func() {
C.gtk_widget_hide(w.widget) C.gtk_widget_hide(w.widget)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Close() *Request { func (w *window) Close() {
c := make(chan interface{})
return &Request{
op: func() {
C.gtk_widget_destroy(w.widget) C.gtk_widget_destroy(w.widget)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) OnClosing(e func(c Doer) bool) *Request { func (w *window) OnClosing(e func() bool) {
c := make(chan interface{})
return &Request{
op: func() {
w.closing.setbool(e) w.closing.setbool(e)
c <- struct{}{}
},
resp: c,
}
} }
//export windowClosing //export windowClosing

View File

@ -35,10 +35,7 @@ func makeWindowWindowClass() error {
return nil return nil
} }
func newWindow(title string, width int, height int) *Request { func newWindow(title string, width int, height int) *window {
c := make(chan interface{})
return &Request{
op: func() {
w := &window{ w := &window{
// hwnd set in WM_CREATE handler // hwnd set in WM_CREATE handler
closing: newEvent(), closing: newEvent(),
@ -47,53 +44,27 @@ func newWindow(title string, width int, height int) *Request {
if hwnd != w.hwnd { if hwnd != w.hwnd {
panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in window (%p) differ", hwnd, w.hwnd)) panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in window (%p) differ", hwnd, w.hwnd))
} }
c <- w return w
},
resp: c,
}
} }
func (w *window) SetControl(control Control) *Request { func (w *window) SetControl(control Control) {
c := make(chan interface{})
return &Request{
op: func() {
if w.child != nil { // unparent existing control if w.child != nil { // unparent existing control
w.child.unparent() w.child.unparent()
} }
control.unparent() control.unparent()
control.parent(w) control.parent(w)
w.child = control w.child = control
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Title() *Request { func (w *window) Title() string {
c := make(chan interface{}) return getWindowText(w.hwnd)
return &Request{
op: func() {
c <- getWindowText(w.hwnd)
},
resp: c,
}
} }
func (w *window) SetTitle(title string) *Request { func (w *window) SetTitle(title string) {
c := make(chan interface{})
return &Request{
op: func() {
C.setWindowText(w.hwnd, toUTF16(title)) C.setWindowText(w.hwnd, toUTF16(title))
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Show() *Request { func (w *window) Show() {
c := make(chan interface{})
return &Request{
op: func() {
if !w.shownbefore { if !w.shownbefore {
C.ShowWindow(w.hwnd, C.nCmdShow) C.ShowWindow(w.hwnd, C.nCmdShow)
C.updateWindow(w.hwnd) C.updateWindow(w.hwnd)
@ -101,43 +72,18 @@ func (w *window) Show() *Request {
} else { } else {
C.ShowWindow(w.hwnd, C.SW_SHOW) C.ShowWindow(w.hwnd, C.SW_SHOW)
} }
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Hide() *Request { func (w *window) Hide() {
c := make(chan interface{})
return &Request{
op: func() {
C.ShowWindow(w.hwnd, C.SW_HIDE) C.ShowWindow(w.hwnd, C.SW_HIDE)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) Close() *Request { func (w *window) Close() {
c := make(chan interface{})
return &Request{
op: func() {
C.windowClose(w.hwnd) C.windowClose(w.hwnd)
c <- struct{}{}
},
resp: c,
}
} }
func (w *window) OnClosing(e func(Doer) bool) *Request { func (w *window) OnClosing(e func() bool) {
c := make(chan interface{})
return &Request{
op: func() {
w.closing.setbool(e) w.closing.setbool(e)
c <- struct{}{}
},
resp: c,
}
} }
//export storeWindowHWND //export storeWindowHWND