diff options
| author | Pietro Gagliardi <[email protected]> | 2015-12-11 20:37:59 -0500 |
|---|---|---|
| committer | Pietro Gagliardi <[email protected]> | 2015-12-11 20:37:59 -0500 |
| commit | f8e3f12ab02b528f2a05a4f713d7af7ea8e44b42 (patch) | |
| tree | 82dedf4d37f0f6d31e88ebb2ca1ce6499dead261 /prev/table_darwin.go | |
| parent | e34c561ed5bedeb180437ec165882b98d70d38c1 (diff) | |
LET'S GET THIS FINAL REWRITE EVER STARTED
Diffstat (limited to 'prev/table_darwin.go')
| -rw-r--r-- | prev/table_darwin.go | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/prev/table_darwin.go b/prev/table_darwin.go new file mode 100644 index 0000000..1bfbe74 --- /dev/null +++ b/prev/table_darwin.go @@ -0,0 +1,138 @@ +// 29 july 2014 + +package ui + +import ( + "fmt" + "reflect" + "unsafe" + "image" +) + +// #include "objc_darwin.h" +import "C" + +type table struct { + *tablebase + + *scroller + + selected *event +} + +func finishNewTable(b *tablebase, ty reflect.Type) Table { + id := C.newTable() + t := &table{ + scroller: newScroller(id, true), // border on Table + tablebase: b, + selected: newEvent(), + } + t.fpreferredSize = t.xpreferredSize + // also sets the delegate + C.tableMakeDataSource(t.id, unsafe.Pointer(t)) + for i := 0; i < ty.NumField(); i++ { + colname := ty.Field(i).Tag.Get("uicolumn") + if colname == "" { + colname = ty.Field(i).Name + } + cname := C.CString(colname) + coltype := C.colTypeText + editable := false + switch { + case ty.Field(i).Type == reflect.TypeOf((*image.RGBA)(nil)): + coltype = C.colTypeImage + case ty.Field(i).Type.Kind() == reflect.Bool: + coltype = C.colTypeCheckbox + editable = true + } + C.tableAppendColumn(t.id, C.intptr_t(i), cname, C.int(coltype), toBOOL(editable)) + C.free(unsafe.Pointer(cname)) // free now (not deferred) to conserve memory + } + return t +} + +func (t *table) Unlock() { + t.unlock() + // there's a possibility that user actions can happen at this point, before the view is updated + // alas, this is something we have to deal with, because Unlock() can be called from any thread + go func() { + Do(func() { + t.RLock() + defer t.RUnlock() + C.tableUpdate(t.id) + }) + }() +} + +func (t *table) Selected() int { + t.RLock() + defer t.RUnlock() + return int(C.tableSelected(t.id)) +} + +func (t *table) Select(index int) { + t.RLock() + defer t.RUnlock() + C.tableSelect(t.id, C.intptr_t(index)) +} + +func (t *table) OnSelected(f func()) { + t.selected.set(f) +} + +//export goTableDataSource_getValue +func goTableDataSource_getValue(data unsafe.Pointer, row C.intptr_t, col C.intptr_t, outtype *C.int) unsafe.Pointer { + t := (*table)(data) + t.RLock() + defer t.RUnlock() + d := reflect.Indirect(reflect.ValueOf(t.data)) + datum := d.Index(int(row)).Field(int(col)) + switch { + case datum.Type() == reflect.TypeOf((*image.RGBA)(nil)): + *outtype = C.colTypeImage + d := datum.Interface().(*image.RGBA) + img := C.toTableImage(unsafe.Pointer(pixelData(d)), C.intptr_t(d.Rect.Dx()), C.intptr_t(d.Rect.Dy()), C.intptr_t(d.Stride)) + return unsafe.Pointer(img) + case datum.Kind() == reflect.Bool: + *outtype = C.colTypeCheckbox + if datum.Bool() == true { + // return a non-nil pointer + // outtype isn't Go-side so it'll work + return unsafe.Pointer(outtype) + } + return nil + default: + s := fmt.Sprintf("%v", datum) + return unsafe.Pointer(C.CString(s)) + } +} + +//export goTableDataSource_getRowCount +func goTableDataSource_getRowCount(data unsafe.Pointer) C.intptr_t { + t := (*table)(data) + t.RLock() + defer t.RUnlock() + d := reflect.Indirect(reflect.ValueOf(t.data)) + return C.intptr_t(d.Len()) +} + +//export goTableDataSource_toggled +func goTableDataSource_toggled(data unsafe.Pointer, row C.intptr_t, col C.intptr_t, checked C.BOOL) { + t := (*table)(data) + t.Lock() + defer t.Unlock() + d := reflect.Indirect(reflect.ValueOf(t.data)) + datum := d.Index(int(row)).Field(int(col)) + datum.SetBool(fromBOOL(checked)) +} + +//export tableSelectionChanged +func tableSelectionChanged(data unsafe.Pointer) { + t := (*table)(data) + t.selected.fire() +} + +func (t *table) xpreferredSize(d *sizing) (width, height int) { + s := C.tablePreferredSize(t.id) + return int(s.width), int(s.height) +} |
