summaryrefslogtreecommitdiff
path: root/sysdata_darwin.go
diff options
context:
space:
mode:
Diffstat (limited to 'sysdata_darwin.go')
-rw-r--r--sysdata_darwin.go237
1 files changed, 237 insertions, 0 deletions
diff --git a/sysdata_darwin.go b/sysdata_darwin.go
new file mode 100644
index 0000000..0c6208c
--- /dev/null
+++ b/sysdata_darwin.go
@@ -0,0 +1,237 @@
+// 1 march 2014
+package ui
+
+import (
+ "unsafe"
+)
+
+// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
+// #include "objc_darwin.h"
+import "C"
+
+type sysData struct {
+ cSysData
+
+ id C.id
+}
+
+type classData struct {
+ make: func(parentWindow C.id) C.id
+ show: func(what C.id)
+ hide: func(what C.id)
+ settextsel C.SEL
+ textsel C.SEL
+}
+
+var (
+ _NSWindow = objc_getClass("NSWindow")
+
+ _initWithContentRect = sel_getUid("initWithContentRect:styleMask:backing:defer:")
+ _makeKeyAndOrderFront = sel_getUid("makeKeyAndOrderFront:")
+ _orderOut = sel_getUid("orderOut:")
+ _setHidden = sel_getUid("setHidden:")
+ _setTitle = sel_getUid("setTitle:")
+ _setStringValue = sel_getUid("setStringValue:")
+ _setFrame = sel_getUid("setFrame:")
+ _state = sel_getUid("state")
+ _title = sel_getUid("title")
+ _stringValue = sel_getUid("stringValue")
+ // TODO others
+ _setFrameDisplay = sel_getUid("setFrame:display:")
+)
+
+func controlShow(what C.id) {
+ C.objc_msgSend_bool(what, _setHidden, C.BOOL(C.NO))
+}
+
+func controlHide(what C.id) {
+ C.objc_msgSend_bool(what, _setHidden, C.BOOL(C.YES))
+}
+
+var classTypes = [nctypes]*classData{
+ c_window: &classData{
+ make: func(parentWindow C.id) C.id {
+ const (
+ NSBorderlessWindowMask = 0
+ NSTitledWindowMask = 1 << 0
+ NSClosableWindowMask = 1 << 1
+ NSMiniaturizableWindowMask = 1 << 2
+ NSResizableWindowMask = 1 << 3
+ NSTexturedBackgroundWindowMask = 1 << 8
+ )
+
+ // we have to specify a content rect to start; it will be overridden soon though
+ win := objc_alloc(_NSWindow)
+ return objc_msgSend_rect_uint_uint_bool(win,
+ _initWithContentRect,
+ 0, 0, 100, 100,
+ NSTitledWindowMask | NSClosableWindowMask | NSClosableWindowMask | NSResizableWindowMask,
+ 2, // NSBackingStoreBuffered - the only backing store method that Apple says we should use (the others are legacy)
+ C.BOOL(C.YES)) // defer creation of device until we show the window
+ },
+ show: func(what C.id) {
+ C.objc_sendMsg_id(what, _makeKeyAndOrderFront, what)
+ },
+ hide: func(what C.id) {
+ C.objc_sendMsg_id(what, _orderOut, what)
+ },
+ settextsel: _setTitle,
+ textsel: _title,
+ },
+ c_button: &classData{
+ },
+ c_checkbox: &classData{
+ },
+ c_combobox: &classData{
+ },
+ c_lineedit: &classData{
+ },
+ c_label: &classData{
+ },
+ c_listbox: &classData{
+ },
+ c_progressbar: &classData{
+ },
+}
+
+func (s *sysData) make(initText string, window *sysData) error {
+ var parentWindow C.id
+
+ ct := classTypes[s.ctype]
+ if ct.make == nil {
+ println(s.ctype, "not implemented")
+ return nil
+ }
+ if window != nil {
+ parentWindow = window.id
+ }
+ ret := make(chan C.id)
+ defer close(ret)
+ uitask <- func() {
+ ret <- ct.make(parentWindow)
+ }
+ s.id = <-ret
+ err := s.setText(initText)
+ if err != nil {
+ return fmt.Errorf("error setting initial text of new window/control: %v", err)
+ }
+ return nil
+}
+
+func (s *sysData) show() error {
+if classTypes[s.ctype].show == nil { return nil }
+ ret := make(chan struct{})
+ defer close(ret)
+ uitask <- func() {
+ classTypes[s.ctype].show(s.id)
+ ret <- struct{}{}
+ }
+ <-ret
+ return nil
+}
+
+func (s *sysData) hide() error {
+if classTypes[s.ctype].hide == nil { return nil }
+ ret := make(chan struct{})
+ defer close(ret)
+ uitask <- func() {
+ classTypes[s.ctype].hide(s.id)
+ ret <- struct{}{}
+ }
+ <-ret
+ return nil
+}
+
+func (s *sysData) setText(text string) error {
+var zero C.SEL
+if classTypes[s.ctype].settextsel == zero { return nil }
+ ret := make(chan struct{})
+ defer close(ret)
+ uitask <- func() {
+ C.objc_msgSend_id(s.id, classTypes[s.ctype].settextsel, toNSString(text))
+ ret <- struct{}{}
+ }
+ <-ret
+ return nil
+}
+
+func (s *sysData) setRect(x int, y int, width int, height int) error {
+if classTypes[s.ctype].make == nil { return nil }
+ C.objc_msgSend_rect(s.id, _setFrame,
+ C.int64_t(x), C.int64_t(y), C.int64_t(width), C.int64_t(height))
+ return nil
+}
+
+func (s *sysData) isChecked() bool {
+if classTypes[s.ctype].make == nil { return nil }
+ const (
+ NSOnState = 1
+ )
+
+ ret := make(chan bool)
+ defer close(ret)
+ uitask <- func() {
+ k := C.objc_msgSend_noargs(s.id, _state)
+ ret <- uintptr(unsafe.Pointer(k)) == NSOnState
+ }
+ return <-ret
+}
+
+func (s *sysData) text() string {
+var zero C.SEL
+if classTypes[s.ctype].textsel == zero { return nil }
+ ret := make(chan string)
+ defer close(ret)
+ uitask <- func() {
+ str := C.objc_msgSend_noargs(s.id, classTypes[s.ctype].textsel)
+ ret <- fromNSString(str)
+ }
+ return <-ret
+}
+
+func (s *sysData) append(what string) error {
+ // TODO
+ return nil
+}
+
+func (s *sysData) insertBefore(what string, before int) error {
+ // TODO
+ return nil
+}
+
+func (s *sysData) selectedIndex() int {
+ // TODO
+ reteurn -1
+}
+
+func (s *sysData) selectedIndices() []int {
+ // TODO
+ return nil
+}
+
+func (s *sysData) selectedTexts() []string {
+ // TODO
+ return nil
+}
+
+func (s *sysData) setWindowSize(x int, y int, width int, height int) error {
+ ret := make(chan struct{})
+ defer close(ret)
+ uitask <- func() {
+ objc_msgSend_rect_bool(s.id, _setFrameDisplay,
+ x, y, w, h,
+ C.BOOL(C.YES)) // TODO set to NO to prevent subviews from being redrawn before they are resized?
+ ret <- struct{}{}
+ }
+ <-ret
+ return nil
+}
+
+func (s *sysData) delete(index int) error {
+ // TODO
+ return nil
+}
+
+func (s *sysData) setProgress(percent int) {
+ // TODO
+}