summaryrefslogtreecommitdiff
path: root/sysdata_darwin.go
diff options
context:
space:
mode:
Diffstat (limited to 'sysdata_darwin.go')
-rw-r--r--sysdata_darwin.go324
1 files changed, 324 insertions, 0 deletions
diff --git a/sysdata_darwin.go b/sysdata_darwin.go
new file mode 100644
index 0000000..cd25748
--- /dev/null
+++ b/sysdata_darwin.go
@@ -0,0 +1,324 @@
+// 1 march 2014
+
+package ui
+
+import (
+ "fmt"
+ "sync"
+)
+
+// #include "objc_darwin.h"
+import "C"
+
+type sysData struct {
+ cSysData
+
+ id C.id
+ trackingArea C.id // for Area
+}
+
+type classData struct {
+ make func(parentWindow C.id, alternate bool, s *sysData) C.id
+ getinside func(scrollview C.id) C.id
+ show func(what C.id)
+ hide func(what C.id)
+ settext func(what C.id, text C.id)
+ text func(what C.id, alternate bool) C.id
+ append func(id C.id, what string, alternate bool)
+ insertBefore func(id C.id, what string, before int, alternate bool)
+ selIndex func(id C.id) int
+ selIndices func(id C.id) []int
+ selTexts func(id C.id) []string
+ delete func(id C.id, index int)
+ len func(id C.id) int
+}
+
+func addControl(parentWindow C.id, control C.id) {
+ C.addControl(parentWindow, control)
+}
+
+func controlShow(what C.id) {
+ C.controlShow(what)
+}
+
+func controlHide(what C.id) {
+ C.controlHide(what)
+}
+
+// By default some controls do not use the correct font.
+// These functions set the appropriate control font.
+// Which one is used on each control was determined by comparing https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/AppleHIGuidelines/Characteristics/Characteristics.html#//apple_ref/doc/uid/TP40002721-SW10 to what Interface Builder says for each control.
+// (not applicable to ProgressBar, Area)
+
+// Button, Checkbox, Combobox, LineEdit, Label, Listbox
+func applyStandardControlFont(id C.id) {
+ C.applyStandardControlFont(id)
+}
+
+var classTypes = [nctypes]*classData{
+ c_window: &classData{
+ make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
+ return C.makeWindow(appDelegate)
+ },
+ show: func(what C.id) {
+ C.windowShow(what)
+ },
+ hide: func(what C.id) {
+ C.windowHide(what)
+ },
+ settext: func(what C.id, text C.id) {
+ C.windowSetTitle(what, text)
+ },
+ text: func(what C.id, alternate bool) C.id {
+ return C.windowTitle(what)
+ },
+ },
+ c_button: &classData{
+ make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
+ button := C.makeButton()
+ C.buttonSetTargetAction(button, appDelegate)
+ applyStandardControlFont(button)
+ addControl(parentWindow, button)
+ return button
+ },
+ show: controlShow,
+ hide: controlHide,
+ settext: func(what C.id, text C.id) {
+ C.buttonSetText(what, text)
+ },
+ text: func(what C.id, alternate bool) C.id {
+ return C.buttonText(what)
+ },
+ },
+ c_checkbox: &classData{
+ make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
+ checkbox := C.makeCheckbox()
+ applyStandardControlFont(checkbox)
+ addControl(parentWindow, checkbox)
+ return checkbox
+ },
+ show: controlShow,
+ hide: controlHide,
+ settext: func(what C.id, text C.id) {
+ C.buttonSetText(what, text)
+ },
+ text: func(what C.id, alternate bool) C.id {
+ return C.buttonText(what)
+ },
+ },
+ c_combobox: &classData{
+ make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
+ combobox := C.makeCombobox(toBOOL(alternate))
+ applyStandardControlFont(combobox)
+ addControl(parentWindow, combobox)
+ return combobox
+ },
+ show: controlShow,
+ hide: controlHide,
+ text: func(what C.id, alternate bool) C.id {
+ return C.comboboxText(what, toBOOL(alternate))
+ },
+ append: func(id C.id, what string, alternate bool) {
+ C.comboboxAppend(id, toBOOL(alternate), toNSString(what))
+ },
+ insertBefore: func(id C.id, what string, before int, alternate bool) {
+ C.comboboxInsertBefore(id, toBOOL(alternate),
+ toNSString(what), C.intptr_t(before))
+ },
+ selIndex: func(id C.id) int {
+ return int(C.comboboxSelectedIndex(id))
+ },
+ delete: func(id C.id, index int) {
+ C.comboboxDelete(id, C.intptr_t(index))
+ },
+ len: func(id C.id) int {
+ return int(C.comboboxLen(id))
+ },
+ },
+ c_lineedit: &classData{
+ make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
+ lineedit := C.makeLineEdit(toBOOL(alternate))
+ applyStandardControlFont(lineedit)
+ addControl(parentWindow, lineedit)
+ return lineedit
+ },
+ show: controlShow,
+ hide: controlHide,
+ settext: func(what C.id, text C.id) {
+ C.lineeditSetText(what, text)
+ },
+ text: func(what C.id, alternate bool) C.id {
+ return C.lineeditText(what)
+ },
+ },
+ c_label: &classData{
+ make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
+ label := C.makeLabel()
+ applyStandardControlFont(label)
+ addControl(parentWindow, label)
+ return label
+ },
+ show: controlShow,
+ hide: controlHide,
+ settext: func(what C.id, text C.id) {
+ C.lineeditSetText(what, text)
+ },
+ text: func(what C.id, alternate bool) C.id {
+ return C.lineeditText(what)
+ },
+ },
+ c_listbox: &classData{
+ make: makeListbox,
+ show: controlShow,
+ hide: controlHide,
+ append: listboxAppend,
+ insertBefore: listboxInsertBefore,
+ selIndices: listboxSelectedIndices,
+ selTexts: listboxSelectedTexts,
+ delete: listboxDelete,
+ len: listboxLen,
+ },
+ c_progressbar: &classData{
+ make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
+ pbar := C.makeProgressBar()
+ addControl(parentWindow, pbar)
+ return pbar
+ },
+ show: controlShow,
+ hide: controlHide,
+ },
+ c_area: &classData{
+ make: makeArea,
+ getinside: areaInScrollView,
+ show: controlShow,
+ hide: controlHide,
+ },
+}
+
+// I need to access sysData from appDelegate, but appDelegate doesn't store any data. So, this.
+var (
+ sysdatas = make(map[C.id]*sysData)
+ sysdatalock sync.Mutex
+)
+
+func addSysData(key C.id, value *sysData) {
+ sysdatalock.Lock()
+ sysdatas[key] = value
+ sysdatalock.Unlock()
+}
+
+func getSysData(key C.id) *sysData {
+ sysdatalock.Lock()
+ defer sysdatalock.Unlock()
+
+ v, ok := sysdatas[key]
+ if !ok {
+ panic(fmt.Errorf("internal error: getSysData(%v) unknown", key))
+ }
+ return v
+}
+
+func (s *sysData) make(window *sysData) error {
+ var parentWindow C.id
+
+ ct := classTypes[s.ctype]
+ if window != nil {
+ parentWindow = window.id
+ }
+ s.id = ct.make(parentWindow, s.alternate, s)
+ if ct.getinside != nil {
+ addSysData(ct.getinside(s.id), s)
+ } else {
+ addSysData(s.id, s)
+ }
+ return nil
+}
+
+// used for Windows; nothing special needed elsewhere
+func (s *sysData) firstShow() error {
+ s.show()
+ return nil
+}
+
+func (s *sysData) show() {
+ classTypes[s.ctype].show(s.id)
+}
+
+func (s *sysData) hide() {
+ classTypes[s.ctype].hide(s.id)
+}
+
+func (s *sysData) setText(text string) {
+ classTypes[s.ctype].settext(s.id, toNSString(text))
+}
+
+func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error {
+ // winheight - y because (0,0) is the bottom-left corner of the window and not the top-left corner
+ // (winheight - y) - height because (x, y) is the bottom-left corner of the control and not the top-left
+ C.setRect(s.id,
+ C.intptr_t(x), C.intptr_t((winheight-y)-height),
+ C.intptr_t(width), C.intptr_t(height))
+ return nil
+}
+
+func (s *sysData) isChecked() bool {
+ return C.isCheckboxChecked(s.id) != C.NO
+}
+
+func (s *sysData) text() string {
+ str := classTypes[s.ctype].text(s.id, s.alternate)
+ return fromNSString(str)
+}
+
+func (s *sysData) append(what string) {
+ classTypes[s.ctype].append(s.id, what, s.alternate)
+}
+
+func (s *sysData) insertBefore(what string, before int) {
+ classTypes[s.ctype].insertBefore(s.id, what, before, s.alternate)
+}
+
+func (s *sysData) selectedIndex() int {
+ return classTypes[s.ctype].selIndex(s.id)
+}
+
+func (s *sysData) selectedIndices() []int {
+ return classTypes[s.ctype].selIndices(s.id)
+}
+
+func (s *sysData) selectedTexts() []string {
+ return classTypes[s.ctype].selTexts(s.id)
+}
+
+func (s *sysData) setWindowSize(width int, height int) error {
+ C.windowSetContentSize(s.id, C.intptr_t(width), C.intptr_t(height))
+ return nil
+}
+
+func (s *sysData) delete(index int) {
+ classTypes[s.ctype].delete(s.id, index)
+}
+
+func (s *sysData) setProgress(percent int) {
+ C.setProgress(s.id, C.intptr_t(percent))
+}
+
+func (s *sysData) len() int {
+ return classTypes[s.ctype].len(s.id)
+}
+
+func (s *sysData) setAreaSize(width int, height int) {
+ C.setAreaSize(s.id, C.intptr_t(width), C.intptr_t(height))
+}
+
+func (s *sysData) repaintAll() {
+ C.display(s.id)
+}
+
+func (s *sysData) center() {
+ C.center(s.id)
+}
+
+func (s *sysData) setChecked(checked bool) {
+ C.setCheckboxChecked(s.id, toBOOL(checked))
+}