summaryrefslogtreecommitdiff
path: root/window.go
diff options
context:
space:
mode:
Diffstat (limited to 'window.go')
-rw-r--r--window.go152
1 files changed, 152 insertions, 0 deletions
diff --git a/window.go b/window.go
new file mode 100644
index 0000000..53147f2
--- /dev/null
+++ b/window.go
@@ -0,0 +1,152 @@
+// 12 december 2015
+
+package ui
+
+import (
+ "unsafe"
+)
+
+// #include "ui.h"
+// extern int doOnClosing(uiWindow *, void *);
+// static inline void realuiWindowOnClosing(uiWindow *w)
+// {
+// uiWindowOnClosing(w, doOnClosing, NULL);
+// }
+import "C"
+
+// no need to lock this; only the GUI thread can access it
+var windows = make(map[*C.uiWindow]*Window)
+
+// Window is a Control that represents a top-level window.
+// A Window contains one child Control that occupies the
+// entirety of the window. Though a Window is a Control,
+// a Window cannot be the child of another Control.
+type Window struct {
+ c *C.uiControl
+ w *C.uiWindow
+
+ child Control
+
+ onClosing func(w *Window) bool
+}
+
+// NewWindow creates a new Window.
+func NewWindow(title string, width int, height int, hasMenubar bool) *Window {
+ w := new(Window)
+
+ ctitle := C.CString(title)
+ // TODO wait why did I make these ints and not intmax_ts?
+ w.w = C.uiNewWindow(ctitle, C.int(width), C.int(height), frombool(hasMenubar))
+ w.c = (*C.uiControl)(unsafe.Pointer(w.w))
+ freestr(ctitle)
+
+ C.realuiWindowOnClosing(w.w)
+ windows[w.w] = w
+
+ return w
+}
+
+// Destroy destroys the Window. If the Window has a child,
+// Destroy calls Destroy on that as well.
+func (w *Window) Destroy() {
+ // first hide ourselves
+ w.Hide()
+ // get rid of the child
+ if w.child != nil {
+ c := w.child
+ w.SetChild(nil)
+ c.Destroy()
+ }
+ // unregister events
+ delete(windows, w.w)
+ // and finally destroy ourselves
+ C.uiControlDestroy(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.
+// On OS X this is a pointer to a NSWindow.
+func (w *Window) Handle() uintptr {
+ return uintptr(C.uiControlHandle(w.c))
+}
+
+// Show shows the Window. It uses the OS conception of "presenting"
+// the Window, whatever that may be on a given OS.
+func (w *Window) Show() {
+ C.uiControlShow(w.c)
+}
+
+// Hide hides the Window.
+func (w *Window) Hide() {
+ C.uiControlHide(w.c)
+}
+
+// Enable enables the Window.
+func (w *Window) Enable() {
+ C.uiControlEnable(w.c)
+}
+
+// Disable disables the Window.
+func (w *Window) Disable() {
+ C.uiControlDisable(w.c)
+}
+
+// Title returns the Window's title.
+func (w *Window) Title() string {
+ ctitle := C.uiWindowTitle(w.w)
+ title := C.GoString(ctitle)
+ C.uiFreeText(ctitle)
+ return title
+}
+
+// SetTitle sets the Window's title to title.
+func (w *Window) SetTitle(title string) {
+ ctitle := C.CString(title)
+ C.uiWindowSetTitle(w.w, ctitle)
+ freestr(ctitle)
+}
+
+// OnClosing registers f to be run when the user clicks the Window's
+// close button. Only one function can be registered at a time.
+// If f returns true, the window is destroyed with the Destroy method.
+// If f returns false, or if OnClosing is never called, the window is not
+// destroyed and is kept visible.
+func (w *Window) OnClosing(f func(*Window) bool) {
+ w.onClosing = f
+}
+
+//export doOnClosing
+func doOnClosing(ww *C.uiWindow, data unsafe.Pointer) C.int {
+ w := windows[ww]
+ if w.onClosing == nil {
+ return 0
+ }
+ if w.onClosing(w) {
+ w.Destroy()
+ }
+ return 0
+}
+
+// SetChild sets the Window's child to child. If child is nil, the Window
+// will not have a child.
+func (w *Window) SetChild(child Control) {
+ w.child = child
+ c := (*C.uiControl)(nil)
+ if w.child != nil {
+ c = touiControl(w.child.Handle())
+ }
+ C.uiWindowSetChild(w.w, c)
+}
+
+// Margined returns whether the Window has margins around its child.
+func (w *Window) Margined() bool {
+ return tobool(C.uiWindowMargined(w.w))
+}
+
+// SetMargined controls whether the Window has margins around its
+// child. The size of the margins are determined by the OS and its
+// best practices.
+func (w *Window) SetMargined(margined bool) {
+ C.uiWindowSetMargined(w.w, frombool(margined))
+}