diff --git a/button.go b/button.go new file mode 100644 index 0000000..17a729f --- /dev/null +++ b/button.go @@ -0,0 +1,114 @@ +// 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 Window. 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/checkbox.go b/checkbox.go new file mode 100644 index 0000000..173dc84 --- /dev/null +++ b/checkbox.go @@ -0,0 +1,124 @@ +// 12 december 2015 + +package ui + +import ( + "unsafe" +) + +// #include "ui.h" +// extern void doCheckboxOnToggled(uiCheckbox *, void *); +// static inline void realuiCheckboxOnToggled(uiCheckbox *c) +// { +// uiCheckboxOnToggled(c, doCheckboxOnToggled, NULL); +// } +import "C" + +// no need to lock this; only the GUI thread can access it +var checkboxes = make(map[*C.uiCheckbox]*Checkbox) + +// Checkbox is a Control that represents a box with a text label at its +// side. When the user clicks the checkbox, a check mark will appear +// in the box; clicking it again removes the check. +type Checkbox struct { + co *C.uiControl + c *C.uiCheckbox + + onToggled func(*Checkbox) +} + +// NewCheckbox creates a new Checkbox with the given text as its label. +func NewCheckbox(text string) *Checkbox { + c := new(Checkbox) + + ctext := C.CString(text) + c.c = C.uiNewCheckbox(ctext) + c.co = (*C.uiControl)(unsafe.Pointer(c.c)) + freestr(ctext) + + C.realuiCheckboxOnToggled(c.c) + checkboxes[c.c] = c + + return c +} + +// Destroy destroys the Checkbox. +func (c *Checkbox) Destroy() { + delete(checkboxes, c.c) + C.uiControlDestroy(c.co) +} + +// LibuiControl returns the libui uiControl pointer that c.coks +// the Window. This is only used by package ui itself and should +// not be called by programs. +func (c *Checkbox) LibuiControl() uintptr { + return uintptr(unsafe.Pointer(c.co)) +} + +// Handle returns the OS-level handle associated with this Checkbox. +// 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 GtkCheckButton. +// On OS X this is a pointer to a NSButton. +func (c *Checkbox) Handle() uintptr { + return uintptr(C.uiControlHandle(c.co)) +} + +// Show shows the Checkbox. +func (c *Checkbox) Show() { + C.uiControlShow(c.co) +} + +// Hide hides the Checkbox. +func (c *Checkbox) Hide() { + C.uiControlHide(c.co) +} + +// Enable enables the Checkbox. +func (c *Checkbox) Enable() { + C.uiControlEnable(c.co) +} + +// Disable disables the Checkbox. +func (c *Checkbox) Disable() { + C.uiControlDisable(c.co) +} + +// Text returns the Checkbox's text. +func (c *Checkbox) Text() string { + ctext := C.uiCheckboxText(c.c) + text := C.GoString(ctext) + C.uiFreeText(ctext) + return text +} + +// SetText sets the Checkbox's text to text. +func (c *Checkbox) SetText(text string) { + ctext := C.CString(text) + C.uiCheckboxSetText(c.c, ctext) + freestr(ctext) +} + +// OnToggled registers f to be run when the user clicks the Checkbox. +// Only one function can be registered at a time. +func (c *Checkbox) OnToggled(f func(*Checkbox)) { + c.onToggled = f +} + +//export doCheckboxOnToggled +func doCheckboxOnToggled(cc *C.uiCheckbox, data unsafe.Pointer) { + c := checkboxes[cc] + if c.onToggled != nil { + c.onToggled(c) + } +} + +// Checked returns whether the Checkbox is checked. +func (c *Checkbox) Checked() bool { + return tobool(C.uiCheckboxChecked(c.c)) +} + +// SetChecked sets whether the Checkbox is checked. +func (c *Checkbox) SetChecked(checked bool) { + C.uiCheckboxSetChecked(c.c, frombool(checked)) +} diff --git a/control.go b/control.go index 73c9953..94ea34f 100644 --- a/control.go +++ b/control.go @@ -23,6 +23,11 @@ type Control interface { // 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 diff --git a/window.go b/window.go index 53147f2..bdd230c 100644 --- a/window.go +++ b/window.go @@ -63,6 +63,13 @@ func (w *Window) Destroy() { C.uiControlDestroy(w.c) } +// LibuiControl returns the libui uiControl pointer that backs +// the Window. This is only used by package ui itself and should +// not be called by programs. +func (w *Window) LibuiControl() uintptr { + return uintptr(unsafe.Pointer(w.c)) +} + // Handle returns the OS-level handle associated with this Window. // On Windows this is an HWND of a libui-internal class. // On GTK+ this is a pointer to a GtkWindow. @@ -134,7 +141,7 @@ func (w *Window) SetChild(child Control) { w.child = child c := (*C.uiControl)(nil) if w.child != nil { - c = touiControl(w.child.Handle()) + c = touiControl(w.child.LibuiControl()) } C.uiWindowSetChild(w.w, c) } diff --git a/zz_test.go b/zz_test.go index 92ce522..06c9cda 100644 --- a/zz_test.go +++ b/zz_test.go @@ -11,6 +11,11 @@ func TestIt(t *testing.T) { Quit() return true }) + c := NewCheckbox("Click Me") + c.OnToggled(func(c *Checkbox) { + w.SetMargined(c.Checked()) + }) + w.SetChild(c) w.Show() }) if err != nil {