diff --git a/AAA_GOFILES/button.go b/AAA_GOFILES/button.go deleted file mode 100644 index 2696f82..0000000 --- a/AAA_GOFILES/button.go +++ /dev/null @@ -1,114 +0,0 @@ -// 12 december 2015 - -package ui - -import ( - "unsafe" -) - -// #include "ui.h" -// extern void doButtonOnClicked(uiButton *, void *); -// static inline void realuiButtonOnClicked(uiButton *b) -// { -// uiButtonOnClicked(b, doButtonOnClicked, NULL); -// } -import "C" - -// no need to lock this; only the GUI thread can access it -var buttons = make(map[*C.uiButton]*Button) - -// Button is a Control that represents a button that the user can -// click to perform an action. A Button has a text label that should -// describe what the button does. -type Button struct { - c *C.uiControl - b *C.uiButton - - onClicked func(*Button) -} - -// NewButton creates a new Button with the given text as its label. -func NewButton(text string) *Button { - b := new(Button) - - ctext := C.CString(text) - b.b = C.uiNewButton(ctext) - b.c = (*C.uiControl)(unsafe.Pointer(b.b)) - freestr(ctext) - - C.realuiButtonOnClicked(b.b) - buttons[b.b] = b - - return b -} - -// Destroy destroys the Button. -func (b *Button) Destroy() { - delete(buttons, b.b) - C.uiControlDestroy(b.c) -} - -// LibuiControl returns the libui uiControl pointer that backs -// the Button. This is only used by package ui itself and should -// not be called by programs. -func (b *Button) LibuiControl() uintptr { - return uintptr(unsafe.Pointer(b.c)) -} - -// Handle returns the OS-level handle associated with this Button. -// On Windows this is an HWND of a standard Windows API BUTTON -// class (as provided by Common Controls version 6). -// On GTK+ this is a pointer to a GtkButton. -// On OS X this is a pointer to a NSButton. -func (b *Button) Handle() uintptr { - return uintptr(C.uiControlHandle(b.c)) -} - -// Show shows the Button. -func (b *Button) Show() { - C.uiControlShow(b.c) -} - -// Hide hides the Button. -func (b *Button) Hide() { - C.uiControlHide(b.c) -} - -// Enable enables the Button. -func (b *Button) Enable() { - C.uiControlEnable(b.c) -} - -// Disable disables the Button. -func (b *Button) Disable() { - C.uiControlDisable(b.c) -} - -// Text returns the Button's text. -func (b *Button) Text() string { - ctext := C.uiButtonText(b.b) - text := C.GoString(ctext) - C.uiFreeText(ctext) - return text -} - -// SetText sets the Button's text to text. -func (b *Button) SetText(text string) { - ctext := C.CString(text) - C.uiButtonSetText(b.b, ctext) - freestr(ctext) -} - -// OnClicked registers f to be run when the user clicks the Button. -// Only one function can be registered at a time. -func (b *Button) OnClicked(f func(*Button)) { - b.onClicked = f -} - -//export doButtonOnClicked -func doButtonOnClicked(bb *C.uiButton, data unsafe.Pointer) { - b := buttons[bb] - if b.onClicked != nil { - b.onClicked(b) - } -} diff --git a/AAA_GOFILES/control.go b/AAA_GOFILES/control.go deleted file mode 100644 index 94ea34f..0000000 --- a/AAA_GOFILES/control.go +++ /dev/null @@ -1,107 +0,0 @@ -// 12 december 2015 - -package ui - -import ( - "unsafe" -) - -// #include "ui.h" -import "C" - -// Control represents a GUI control. It provdes methods -// common to all Controls. -// -// To create a new Control, implement the control on -// the libui side, then provide access to that control on -// the Go side via an implementation of Control as -// described. -type Control interface { - // Destroy destroys the Control. - // - // Implementations should do any necessary cleanup, - // then call LibuiControlDestroy. - Destroy() - - // LibuiControl returns the libui uiControl pointer that backs - // the Control. This is only used by package ui itself and should - // not be called by programs. - LibuiControl() uintptr - - // Handle returns the OS-level handle that backs the - // Control. On OSs that use reference counting for - // controls, Handle does not increment the reference - // count; you are sharing package ui's reference. - // - // Implementations should call LibuiControlHandle and - // document exactly what kind of handle is returned. - Handle() uintptr - - // Show shows the Control. - // - // Implementations should call LibuiControlShow. - Show() - - // Hide shows the Control. Hidden controls do not participate - // in layout (that is, Box, Grid, etc. does not reserve space for - // hidden controls). - // - // Implementations should call LibuiControlHide. - Hide() - - // Enable enables the Control. - // - // Implementations should call LibuiControlEnable. - Enable() - - // Disable disables the Control. - // - // Implementations should call LibuiControlDisable. - Disable() -} - -func touiControl(c uintptr) *C.uiControl { - return (*C.uiControl)(unsafe.Pointer(c)) -} - -// LibuiControlDestroy allows implementations of Control -// to call the libui function uiControlDestroy. -func LibuiControlDestroy(c uintptr) { - C.uiControlDestroy(touiControl(c)) -} - -// LibuiControlHandle allows implementations of Control -// to call the libui function uiControlHandle. -func LibuiControlHandle(c uintptr) uintptr { - return uintptr(C.uiControlHandle(touiControl(c))) -} - -// LibuiControlShow allows implementations of Control -// to call the libui function uiControlShow. -func LibuiControlShow(c uintptr) { - C.uiControlShow(touiControl(c)) -} - -// LibuiControlHide allows implementations of Control -// to call the libui function uiControlHide. -func LibuiControlHide(c uintptr) { - C.uiControlHide(touiControl(c)) -} - -// LibuiControlEnable allows implementations of Control -// to call the libui function uiControlEnable. -func LibuiControlEnable(c uintptr) { - C.uiControlEnable(touiControl(c)) -} - -// LibuiControlDisable allows implementations of Control -// to call the libui function uiControlDisable. -func LibuiControlDisable(c uintptr) { - C.uiControlDisable(touiControl(c)) -} - -// LibuiFreeText allows implementations of Control -// to call the libui function uiFreeText. -func LibuiFreeText(c uintptr) { - C.uiFreeText((*C.char)(unsafe.Pointer(c))) -} diff --git a/button.go b/button.go new file mode 100644 index 0000000..a0c4e67 --- /dev/null +++ b/button.go @@ -0,0 +1,63 @@ +// 12 december 2015 + +package ui + +import ( + "unsafe" +) + +// #include "ui.h" +// extern void doButtonOnClicked(uiButton *, void *); +import "C" + +// Button is a Control that represents a button that the user can +// click to perform an action. A Button has a text label that should +// describe what the button does. +type Button struct { + ControlBase + b *C.uiButton + onClicked func(*Button) +} + +// NewButton creates a new Button with the given text as its label. +func NewButton(text string) *Button { + b := new(Button) + + ctext := C.CString(text) + b.b = C.uiNewButton(ctext) + freestr(ctext) + + C.uiButtonOnClicked(b.b, C.doButtonOnClicked, nil) + + b.ControlBase = NewControlBase(b, uintptr(unsafe.Pointer(b.b))) + return b +} + +// Text returns the Button's text. +func (b *Button) Text() string { + ctext := C.uiButtonText(b.b) + text := C.GoString(ctext) + C.uiFreeText(ctext) + return text +} + +// SetText sets the Button's text to text. +func (b *Button) SetText(text string) { + ctext := C.CString(text) + C.uiButtonSetText(b.b, ctext) + freestr(ctext) +} + +// OnClicked registers f to be run when the user clicks the Button. +// Only one function can be registered at a time. +func (b *Button) OnClicked(f func(*Button)) { + b.onClicked = f +} + +//export doButtonOnClicked +func doButtonOnClicked(bb *C.uiButton, data unsafe.Pointer) { + b := ControlFromLibui(uintptr(unsafe.Pointer(bb))).(*Button) + if b.onClicked != nil { + b.onClicked(b) + } +} diff --git a/control.go b/control.go new file mode 100644 index 0000000..3bcdfbe --- /dev/null +++ b/control.go @@ -0,0 +1,132 @@ +// 12 december 2015 + +package ui + +import ( + "unsafe" +) + +// #include "ui.h" +import "C" + +// no need to lock this; only the GUI thread can access it +var controls = make(map[*C.uiControl]Control) + +// Control represents a GUI control. It provdes methods +// common to all Controls. +// +// The preferred way to create new Controls is to use +// ControlBase; see ControlBase below. +type Control interface { + // Destroy destroys the Control. + Destroy() + + // Handle returns the OS-level handle that backs the + // Control. On OSs that use reference counting for + // controls, Handle does not increment the reference + // count; you are sharing package ui's reference. + Handle() uintptr + + // Visible returns whether the Control is visible. + Visible() bool + + // Show shows the Control. + Show() + + // Hide shows the Control. Hidden controls do not participate + // in layout (that is, Box, Grid, etc. does not reserve space for + // hidden controls). + Hide() + + // Enabled returns whether the Control is enabled. + Enabled() bool + + // Enable enables the Control. + Enable() + + // Disable disables the Control. + Disable() +} + +// ControlBase is an implementation of Control that provides +// all the methods that Control requires. To use it, embed a +// ControlBase (not a *ControlBase) into your structure, then +// assign the result of NewControlBase to that field: +// +// type MyControl struct { +// ui.ControlBase +// c *C.MyControl +// } +// +// func NewMyControl() *MyControl { +// m := &NewMyControl{ +// c: C.newMyControl(), +// } +// m.ControlBase = ui.NewControlBase(m, uintptr(unsafe.Pointer(c))) +// return m +// } +type ControlBase struct { + iface Control + c *C.uiControl +} + +// NewControlBase creates a new ControlBase. See the +// documentation of ControlBase for an example. +// NewControl should only be called once per instance of Control. +func NewControlBase(iface Control, c uintptr) ControlBase { + b := ControlBase{ + iface: iface, + c: (*C.uiControl)(unsafe.Pointer(c)), + } + controls[b.c] = b.iface + return b +} + +func (c *ControlBase) Destroy() { + delete(controls, c.c) + C.uiControlDestroy(c.c) +} + +func (c *ControlBase) Handle() uintptr { + return uintptr(C.uiControlHandle(c.c)) +} + +func (c *ControlBase) Visible() bool { + return frombool(C.uiControlVisible(c.c)) +} + +func (c *ControlBase) Show() { + C.uiControlShow(c.c) +} + +func (c *ControlBase) Hide() { + C.uiControlHide(c.c) +} + +func (c *ControlBase) Enabled() bool { + return frombool(C.uiControlEnabled(c.c)) +} + +func (c *ControlBase) Enable() { + C.uiControlEnable(c.c) +} + +func (c *ControlBase) Disable() { + C.uiControlDisable(c.c) +} + +// ControlFromLibui returns the Control associated with a libui +// uiControl. This is intended for implementing event handlers +// on the Go side, to prevent sharing Go pointers with C. +// This function only works on Controls that use ControlBase. +func ControlFromLibui(c uintptr) Control { + // comma-ok form to avoid creating nil entries + c, _ := controls[(*C.uiControl)(unsafe.Pointer(c))] + return c +} + +// LibuiFreeText allows implementations of Control +// to call the libui function uiFreeText. +func LibuiFreeText(c uintptr) { + C.uiFreeText((*C.char)(unsafe.Pointer(c))) +}