summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--redo/objc_darwin.h3
-rw-r--r--redo/table_darwin.go37
-rw-r--r--redo/table_darwin.m40
3 files changed, 66 insertions, 14 deletions
diff --git a/redo/objc_darwin.h b/redo/objc_darwin.h
index eef1501..f07180d 100644
--- a/redo/objc_darwin.h
+++ b/redo/objc_darwin.h
@@ -86,9 +86,10 @@ extern struct xsize tabPreferredSize(id);
enum {
colTypeText,
colTypeImage,
+ colTypeCheckbox,
};
extern id newTable(void);
-extern void tableAppendColumn(id, intptr_t, char *, int);
+extern void tableAppendColumn(id, intptr_t, char *, int, BOOL);
extern void tableUpdate(id);
extern void tableMakeDataSource(id, void *);
extern struct xsize tablePreferredSize(id);
diff --git a/redo/table_darwin.go b/redo/table_darwin.go
index 662b2ee..1f889c0 100644
--- a/redo/table_darwin.go
+++ b/redo/table_darwin.go
@@ -31,11 +31,15 @@ func finishNewTable(b *tablebase, ty reflect.Type) Table {
for i := 0; i < ty.NumField(); i++ {
cname := C.CString(ty.Field(i).Name)
coltype := C.colTypeText
- switch ty.Field(i).Type {
- case reflect.TypeOf(ImageIndex(0)):
+ editable := false
+ switch {
+ case ty.Field(i).Type == reflect.TypeOf(ImageIndex(0)):
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))
+ 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
@@ -59,16 +63,25 @@ func (t *table) LoadImageList(i ImageList) {
}
//export goTableDataSource_getValue
-func goTableDataSource_getValue(data unsafe.Pointer, row C.intptr_t, col C.intptr_t, isObject *C.BOOL) unsafe.Pointer {
+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 d := datum.Interface().(type) {
- case ImageIndex:
- *isObject = C.YES
+ switch {
+ case datum.Type() == reflect.TypeOf(ImageIndex(0)):
+ *outtype = C.colTypeImage
+ d := datum.Interface().(ImageIndex)
return unsafe.Pointer(t.images[d])
+ 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))
@@ -84,6 +97,16 @@ func goTableDataSource_getRowCount(data unsafe.Pointer) C.intptr_t {
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))
+}
+
func (t *table) id() C.id {
return t._id
}
diff --git a/redo/table_darwin.m b/redo/table_darwin.m
index ab66682..e3c2192 100644
--- a/redo/table_darwin.m
+++ b/redo/table_darwin.m
@@ -36,18 +36,33 @@
NSString *s;
intptr_t colnum;
char *str;
- BOOL isObject = FALSE;
+ int type = colTypeText;
colnum = ((goTableColumn *) col)->gocolnum;
- ret = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum, &isObject);
- if (isObject)
+ ret = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum, &type);
+ switch (type) {
+ case colTypeImage:
return (id) ret;
+ case colTypeCheckbox:
+ if (ret == NULL)
+ return nil;
+ return (id) [NSNumber numberWithInt:1];
+ }
str = (char *) ret;
s = [NSString stringWithUTF8String:str];
free(str); // allocated with C.CString() on the Go side
return (id) s;
}
+- (void)tableView:(NSTableView *)view setObjectValue:(id)value forTableColumn:(NSTableColumn *)col row:(NSInteger)row
+{
+ intptr_t colnum;
+
+ colnum = ((goTableColumn *) col)->gocolnum;
+ // TODO verify type of value
+ goTableDataSource_toggled(self->gotable, (intptr_t) row, colnum, [value boolValue]);
+}
+
@end
id newTable(void)
@@ -63,10 +78,12 @@ id newTable(void)
return (id) t;
}
-void tableAppendColumn(id t, intptr_t colnum, char *name, int type)
+void tableAppendColumn(id t, intptr_t colnum, char *name, int type, BOOL editable)
{
goTableColumn *c;
NSImageCell *ic;
+ NSButtonCell *bc;
+ NSLineBreakMode lbm = NSLineBreakByTruncatingTail; // default for most types
c = [[goTableColumn alloc] initWithIdentifier:nil];
c->gocolnum = colnum;
@@ -80,9 +97,20 @@ void tableAppendColumn(id t, intptr_t colnum, char *name, int type)
[ic setImageAlignment:NSImageAlignCenter];
[c setDataCell:ic];
break;
+ case colTypeCheckbox:
+ bc = [[NSButtonCell alloc] init];
+ [bc setBezelStyle:NSRegularSquareBezelStyle]; // not explicitly stated as such in Interface Builder; extracted with a test program
+ [bc setButtonType:NSSwitchButton];
+ [bc setBordered:NO];
+ [bc setTransparent:NO];
+ [bc setAllowsMixedState:NO];
+ [bc setTitle:@""]; // no label
+ lbm = NSLineBreakByWordWrapping; // Interface Builder sets this mode for this type
+ [c setDataCell:bc];
+ break;
}
// otherwise just use the current cell
- [c setEditable:NO];
+ [c setEditable:editable];
[[c headerCell] setStringValue:[NSString stringWithUTF8String:name]];
setSmallControlFont((id) [c headerCell]);
setStandardControlFont((id) [c dataCell]);
@@ -95,7 +123,7 @@ void tableAppendColumn(id t, intptr_t colnum, char *name, int type)
[[c headerCell] setTruncatesLastVisibleLine:NO];
[[c dataCell] setScrollable:NO];
[[c dataCell] setWraps:NO];
- [[c dataCell] setLineBreakMode:NSLineBreakByTruncatingTail];
+ [[c dataCell] setLineBreakMode:lbm];
[[c dataCell] setUsesSingleLineMode:NO];
[[c dataCell] setTruncatesLastVisibleLine:NO];
[toNSTableView(t) addTableColumn:c];