From 8a81650b3da7ce00725336df9e03b38e935c5a65 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 2 Jul 2014 22:53:03 -0400 Subject: Moved it all back; the preemptive multitaksing during an event handler kills us on all platforms. Going to have to restrict ALL GUI accss to happening from one t hread, so going to need to drop uitask entirely and have just a start() callback for startup code and a post() function for posting requests to windows (like channel sends but into a perpetual buffer). --- sysdata_darwin.go | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 sysdata_darwin.go (limited to 'sysdata_darwin.go') 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)) +} -- cgit v1.2.3