Implemented ImageList and Table ImageIndex on Mac OS X.
This commit is contained in:
parent
37069eadcb
commit
5903dffe3c
|
@ -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)
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
|
// +build !windows,!darwin
|
||||||
|
|
||||||
// 16 august 2014
|
// 16 august 2014
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,12 @@ extern void tabAppend(id, char *, id);
|
||||||
extern struct xsize tabPreferredSize(id);
|
extern struct xsize tabPreferredSize(id);
|
||||||
|
|
||||||
/* table_darwin.m */
|
/* table_darwin.m */
|
||||||
|
enum {
|
||||||
|
colTypeText,
|
||||||
|
colTypeImage,
|
||||||
|
};
|
||||||
extern id newTable(void);
|
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 tableUpdate(id);
|
||||||
extern void tableMakeDataSource(id, void *);
|
extern void tableMakeDataSource(id, void *);
|
||||||
extern struct xsize tablePreferredSize(id);
|
extern struct xsize tablePreferredSize(id);
|
||||||
|
@ -118,4 +122,7 @@ extern void areaRepaintAll(id);
|
||||||
/* common_darwin.m */
|
/* common_darwin.m */
|
||||||
extern void disableAutocorrect(id);
|
extern void disableAutocorrect(id);
|
||||||
|
|
||||||
|
/* imagerep_darwin.m */
|
||||||
|
extern id toImageListImage(void *, intptr_t, intptr_t, intptr_t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,8 @@ type table struct {
|
||||||
|
|
||||||
_id C.id
|
_id C.id
|
||||||
scroller *scroller
|
scroller *scroller
|
||||||
|
|
||||||
|
images []C.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func finishNewTable(b *tablebase, ty reflect.Type) Table {
|
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))
|
C.tableMakeDataSource(t._id, unsafe.Pointer(t))
|
||||||
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)
|
||||||
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
|
C.free(unsafe.Pointer(cname)) // free now (not deferred) to conserve memory
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
|
@ -47,15 +54,25 @@ func (t *table) Unlock() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *table) LoadImageList(i ImageList) {
|
||||||
|
i.apply(&t.images)
|
||||||
|
}
|
||||||
|
|
||||||
//export goTableDataSource_getValue
|
//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 := (*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))
|
||||||
s := fmt.Sprintf("%v", datum)
|
switch d := datum.Interface().(type) {
|
||||||
return C.CString(s)
|
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
|
//export goTableDataSource_getRowCount
|
||||||
|
|
|
@ -32,15 +32,20 @@
|
||||||
|
|
||||||
- (id)tableView:(NSTableView *)view objectValueForTableColumn:(NSTableColumn *)col row:(NSInteger)row
|
- (id)tableView:(NSTableView *)view objectValueForTableColumn:(NSTableColumn *)col row:(NSInteger)row
|
||||||
{
|
{
|
||||||
char *str;
|
void *ret;
|
||||||
NSString *s;
|
NSString *s;
|
||||||
intptr_t colnum;
|
intptr_t colnum;
|
||||||
|
char *str;
|
||||||
|
BOOL isObject = FALSE;
|
||||||
|
|
||||||
colnum = ((goTableColumn *) col)->gocolnum;
|
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];
|
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 s;
|
return (id) s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -58,12 +63,25 @@ id newTable(void)
|
||||||
return (id) t;
|
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;
|
goTableColumn *c;
|
||||||
|
NSImageCell *ic;
|
||||||
|
|
||||||
c = [[goTableColumn alloc] initWithIdentifier:nil];
|
c = [[goTableColumn alloc] initWithIdentifier:nil];
|
||||||
c->gocolnum = colnum;
|
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 setEditable:NO];
|
||||||
[[c headerCell] setStringValue:[NSString stringWithUTF8String:name]];
|
[[c headerCell] setStringValue:[NSString stringWithUTF8String:name]];
|
||||||
setSmallControlFont((id) [c headerCell]);
|
setSmallControlFont((id) [c headerCell]);
|
||||||
|
|
Loading…
Reference in New Issue