summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--redo/imagelist_darwin.go38
-rw-r--r--redo/imagelist_darwin.m32
-rw-r--r--redo/imagelist_unix.go2
-rw-r--r--redo/objc_darwin.h9
-rw-r--r--redo/table_darwin.go25
-rw-r--r--redo/table_darwin.m26
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]);