diff options
| author | Pietro Gagliardi <[email protected]> | 2014-08-16 21:49:43 -0400 |
|---|---|---|
| committer | Pietro Gagliardi <[email protected]> | 2014-08-16 21:49:43 -0400 |
| commit | 5903dffe3c3f4572491c6575d431f066faa03caf (patch) | |
| tree | ecd8f87191bf297461eb2b0baac17135f8b6feac | |
| parent | 37069eadcbd8960ac46031b3455f78463a6bdf3f (diff) | |
Implemented ImageList and Table ImageIndex on Mac OS X.
| -rw-r--r-- | redo/imagelist_darwin.go | 38 | ||||
| -rw-r--r-- | redo/imagelist_darwin.m | 32 | ||||
| -rw-r--r-- | redo/imagelist_unix.go | 2 | ||||
| -rw-r--r-- | redo/objc_darwin.h | 9 | ||||
| -rw-r--r-- | redo/table_darwin.go | 25 | ||||
| -rw-r--r-- | redo/table_darwin.m | 26 |
6 files changed, 122 insertions, 10 deletions
diff --git a/redo/imagelist_darwin.go b/redo/imagelist_darwin.go new file mode 100644 index 0000000..53fafa5 --- /dev/null +++ b/redo/imagelist_darwin.go @@ -0,0 +1,38 @@ +// 16 august 2014 + +package ui + +import ( + "image" + "unsafe" +) + +// #include "objc_darwin.h" +import "C" + +type imagelist struct { + list []C.id +} + +func newImageList() ImageList { + return new(imagelist) +} + +func (i *imagelist) Append(img *image.RGBA) { + id := C.toImageListImage( + unsafe.Pointer(pixelData(img)), C.intptr_t(img.Rect.Dx()), C.intptr_t(img.Rect.Dy()), C.intptr_t(img.Stride)) + i.list = append(i.list, id) +} + +func (i *imagelist) Len() ImageIndex { + return ImageIndex(len(i.list)) +} + +type imageListApply interface { + apply(*[]C.id) +} + +func (i *imagelist) apply(out *[]C.id) { + *out = make([]C.id, len(i.list)) + copy(*out, i.list) +} diff --git a/redo/imagelist_darwin.m b/redo/imagelist_darwin.m new file mode 100644 index 0000000..00ad75a --- /dev/null +++ b/redo/imagelist_darwin.m @@ -0,0 +1,32 @@ +// 16 august 2014 + +#import "objc_darwin.h" +#import <Cocoa/Cocoa.h> + +#define toNSInteger(x) ((NSInteger) (x)) + +// TODO top two pixels of 16x16 images are green? + +id toImageListImage(void *pixels, intptr_t width, intptr_t height, intptr_t stride) +{ + unsigned char *planes[1]; // NSBitmapImageRep wants an array of planes; we have one plane + NSBitmapImageRep *bitmap; + NSImage *image; + + planes[0] = (unsigned char *) pixels; + bitmap = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:planes + pixelsWide:toNSInteger(width) + pixelsHigh:toNSInteger(height) + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:0 + bytesPerRow:toNSInteger(stride) + bitsPerPixel:32]; + image = [[NSImage alloc] initWithSize:NSMakeSize((CGFloat) width, (CGFloat) height)]; + [image addRepresentation:bitmap]; + return (id) image; +} diff --git a/redo/imagelist_unix.go b/redo/imagelist_unix.go index 7c45bd4..34947af 100644 --- a/redo/imagelist_unix.go +++ b/redo/imagelist_unix.go @@ -1,4 +1,4 @@ - +// +build !windows,!darwin // 16 august 2014 diff --git a/redo/objc_darwin.h b/redo/objc_darwin.h index 16a1a56..eef1501 100644 --- a/redo/objc_darwin.h +++ b/redo/objc_darwin.h @@ -83,8 +83,12 @@ extern void tabAppend(id, char *, id); extern struct xsize tabPreferredSize(id); /* table_darwin.m */ +enum { + colTypeText, + colTypeImage, +}; extern id newTable(void); -extern void tableAppendColumn(id, intptr_t, char *); +extern void tableAppendColumn(id, intptr_t, char *, int); extern void tableUpdate(id); extern void tableMakeDataSource(id, void *); extern struct xsize tablePreferredSize(id); @@ -118,4 +122,7 @@ extern void areaRepaintAll(id); /* common_darwin.m */ extern void disableAutocorrect(id); +/* imagerep_darwin.m */ +extern id toImageListImage(void *, intptr_t, intptr_t, intptr_t); + #endif diff --git a/redo/table_darwin.go b/redo/table_darwin.go index 95344c1..662b2ee 100644 --- a/redo/table_darwin.go +++ b/redo/table_darwin.go @@ -16,6 +16,8 @@ type table struct { _id C.id scroller *scroller + + images []C.id } func finishNewTable(b *tablebase, ty reflect.Type) Table { @@ -28,7 +30,12 @@ func finishNewTable(b *tablebase, ty reflect.Type) Table { C.tableMakeDataSource(t._id, unsafe.Pointer(t)) for i := 0; i < ty.NumField(); i++ { cname := C.CString(ty.Field(i).Name) - C.tableAppendColumn(t._id, C.intptr_t(i), cname) + coltype := C.colTypeText + switch ty.Field(i).Type { + case reflect.TypeOf(ImageIndex(0)): + coltype = C.colTypeImage + } + C.tableAppendColumn(t._id, C.intptr_t(i), cname, C.int(coltype)) C.free(unsafe.Pointer(cname)) // free now (not deferred) to conserve memory } return t @@ -47,15 +54,25 @@ func (t *table) Unlock() { }() } +func (t *table) LoadImageList(i ImageList) { + i.apply(&t.images) +} + //export goTableDataSource_getValue -func goTableDataSource_getValue(data unsafe.Pointer, row C.intptr_t, col C.intptr_t) *C.char { +func goTableDataSource_getValue(data unsafe.Pointer, row C.intptr_t, col C.intptr_t, isObject *C.BOOL) 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)) - s := fmt.Sprintf("%v", datum) - return C.CString(s) + switch d := datum.Interface().(type) { + case ImageIndex: + *isObject = C.YES + return unsafe.Pointer(t.images[d]) + default: + s := fmt.Sprintf("%v", datum) + return unsafe.Pointer(C.CString(s)) + } } //export goTableDataSource_getRowCount diff --git a/redo/table_darwin.m b/redo/table_darwin.m index 70d9260..ab66682 100644 --- a/redo/table_darwin.m +++ b/redo/table_darwin.m @@ -32,15 +32,20 @@ - (id)tableView:(NSTableView *)view objectValueForTableColumn:(NSTableColumn *)col row:(NSInteger)row { - char *str; + void *ret; NSString *s; intptr_t colnum; + char *str; + BOOL isObject = FALSE; colnum = ((goTableColumn *) col)->gocolnum; - str = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum); + ret = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum, &isObject); + if (isObject) + return (id) ret; + str = (char *) ret; s = [NSString stringWithUTF8String:str]; free(str); // allocated with C.CString() on the Go side - return s; + return (id) s; } @end @@ -58,12 +63,25 @@ id newTable(void) return (id) t; } -void tableAppendColumn(id t, intptr_t colnum, char *name) +void tableAppendColumn(id t, intptr_t colnum, char *name, int type) { goTableColumn *c; + NSImageCell *ic; c = [[goTableColumn alloc] initWithIdentifier:nil]; c->gocolnum = colnum; + switch (type) { + case colTypeImage: + ic = [[NSImageCell alloc] initImageCell:nil]; + // this is the behavior we want, which differs from the Interface Builder default of proportionally down + [ic setImageScaling:NSImageScaleProportionallyUpOrDown]; + // these two, however, ARE Interface Builder defaults + [ic setImageFrameStyle:NSImageFrameNone]; + [ic setImageAlignment:NSImageAlignCenter]; + [c setDataCell:ic]; + break; + } + // otherwise just use the current cell [c setEditable:NO]; [[c headerCell] setStringValue:[NSString stringWithUTF8String:name]]; setSmallControlFont((id) [c headerCell]); |
