Added bool Table columns on Mac OS X.

This commit is contained in:
Pietro Gagliardi 2014-08-17 10:13:28 -04:00
parent 5854cf2e5d
commit 4a5218df5b
3 changed files with 66 additions and 14 deletions

View File

@ -86,9 +86,10 @@ extern struct xsize tabPreferredSize(id);
enum { enum {
colTypeText, colTypeText,
colTypeImage, colTypeImage,
colTypeCheckbox,
}; };
extern id newTable(void); 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 tableUpdate(id);
extern void tableMakeDataSource(id, void *); extern void tableMakeDataSource(id, void *);
extern struct xsize tablePreferredSize(id); extern struct xsize tablePreferredSize(id);

View File

@ -31,11 +31,15 @@ func finishNewTable(b *tablebase, ty reflect.Type) Table {
for i := 0; i < ty.NumField(); i++ { for i := 0; i < ty.NumField(); i++ {
cname := C.CString(ty.Field(i).Name) cname := C.CString(ty.Field(i).Name)
coltype := C.colTypeText coltype := C.colTypeText
switch ty.Field(i).Type { editable := false
case reflect.TypeOf(ImageIndex(0)): switch {
case ty.Field(i).Type == reflect.TypeOf(ImageIndex(0)):
coltype = C.colTypeImage 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 C.free(unsafe.Pointer(cname)) // free now (not deferred) to conserve memory
} }
return t return t
@ -59,16 +63,25 @@ func (t *table) LoadImageList(i ImageList) {
} }
//export goTableDataSource_getValue //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 := (*table)(data)
t.RLock() t.RLock()
defer t.RUnlock() defer t.RUnlock()
d := reflect.Indirect(reflect.ValueOf(t.data)) d := reflect.Indirect(reflect.ValueOf(t.data))
datum := d.Index(int(row)).Field(int(col)) datum := d.Index(int(row)).Field(int(col))
switch d := datum.Interface().(type) { switch {
case ImageIndex: case datum.Type() == reflect.TypeOf(ImageIndex(0)):
*isObject = C.YES *outtype = C.colTypeImage
d := datum.Interface().(ImageIndex)
return unsafe.Pointer(t.images[d]) 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: default:
s := fmt.Sprintf("%v", datum) s := fmt.Sprintf("%v", datum)
return unsafe.Pointer(C.CString(s)) 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()) 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 { func (t *table) id() C.id {
return t._id return t._id
} }

View File

@ -36,18 +36,33 @@
NSString *s; NSString *s;
intptr_t colnum; intptr_t colnum;
char *str; char *str;
BOOL isObject = FALSE; int type = colTypeText;
colnum = ((goTableColumn *) col)->gocolnum; colnum = ((goTableColumn *) col)->gocolnum;
ret = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum, &isObject); ret = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum, &type);
if (isObject) switch (type) {
case colTypeImage:
return (id) ret; return (id) ret;
case colTypeCheckbox:
if (ret == NULL)
return nil;
return (id) [NSNumber numberWithInt:1];
}
str = (char *) ret; str = (char *) ret;
s = [NSString stringWithUTF8String:str]; s = [NSString stringWithUTF8String:str];
free(str); // allocated with C.CString() on the Go side free(str); // allocated with C.CString() on the Go side
return (id) s; 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 @end
id newTable(void) id newTable(void)
@ -63,10 +78,12 @@ id newTable(void)
return (id) t; 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; goTableColumn *c;
NSImageCell *ic; NSImageCell *ic;
NSButtonCell *bc;
NSLineBreakMode lbm = NSLineBreakByTruncatingTail; // default for most types
c = [[goTableColumn alloc] initWithIdentifier:nil]; c = [[goTableColumn alloc] initWithIdentifier:nil];
c->gocolnum = colnum; c->gocolnum = colnum;
@ -80,9 +97,20 @@ void tableAppendColumn(id t, intptr_t colnum, char *name, int type)
[ic setImageAlignment:NSImageAlignCenter]; [ic setImageAlignment:NSImageAlignCenter];
[c setDataCell:ic]; [c setDataCell:ic];
break; 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 // otherwise just use the current cell
[c setEditable:NO]; [c setEditable:editable];
[[c headerCell] setStringValue:[NSString stringWithUTF8String:name]]; [[c headerCell] setStringValue:[NSString stringWithUTF8String:name]];
setSmallControlFont((id) [c headerCell]); setSmallControlFont((id) [c headerCell]);
setStandardControlFont((id) [c dataCell]); setStandardControlFont((id) [c dataCell]);
@ -95,7 +123,7 @@ void tableAppendColumn(id t, intptr_t colnum, char *name, int type)
[[c headerCell] setTruncatesLastVisibleLine:NO]; [[c headerCell] setTruncatesLastVisibleLine:NO];
[[c dataCell] setScrollable:NO]; [[c dataCell] setScrollable:NO];
[[c dataCell] setWraps:NO]; [[c dataCell] setWraps:NO];
[[c dataCell] setLineBreakMode:NSLineBreakByTruncatingTail]; [[c dataCell] setLineBreakMode:lbm];
[[c dataCell] setUsesSingleLineMode:NO]; [[c dataCell] setUsesSingleLineMode:NO];
[[c dataCell] setTruncatesLastVisibleLine:NO]; [[c dataCell] setTruncatesLastVisibleLine:NO];
[toNSTableView(t) addTableColumn:c]; [toNSTableView(t) addTableColumn:c];