summaryrefslogtreecommitdiff
path: root/control.go
diff options
context:
space:
mode:
Diffstat (limited to 'control.go')
-rw-r--r--control.go145
1 files changed, 145 insertions, 0 deletions
diff --git a/control.go b/control.go
new file mode 100644
index 0000000..ab8673c
--- /dev/null
+++ b/control.go
@@ -0,0 +1,145 @@
+// 12 december 2015
+
+package ui
+
+import (
+ "unsafe"
+)
+
+// #include "pkgui.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 {
+ // LibuiControl returns the uiControl pointer for the Control.
+ // This is intended for use when adding a control to a
+ // container.
+ LibuiControl() uintptr
+
+ // 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) LibuiControl() uintptr {
+ return uintptr(unsafe.Pointer(c.c))
+}
+
+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 tobool(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 tobool(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
+ cc, _ := controls[(*C.uiControl)(unsafe.Pointer(c))]
+ return cc
+}
+
+func touiControl(c uintptr) *C.uiControl {
+ return (*C.uiControl)(unsafe.Pointer(c))
+}
+
+// LibuiFreeText allows implementations of Control
+// to call the libui function uiFreeText.
+func LibuiFreeText(c uintptr) {
+ C.uiFreeText((*C.char)(unsafe.Pointer(c)))
+}