diff options
| -rw-r--r-- | area_darwin.go | 65 | ||||
| -rw-r--r-- | bleh_darwin.m | 33 | ||||
| -rw-r--r-- | delegate_darwin.go | 10 | ||||
| -rw-r--r-- | objc_darwin.h | 3 |
4 files changed, 106 insertions, 5 deletions
diff --git a/area_darwin.go b/area_darwin.go new file mode 100644 index 0000000..4f27554 --- /dev/null +++ b/area_darwin.go @@ -0,0 +1,65 @@ +// 29 march 2014 + +package ui + +import ( + "fmt" + "unsafe" +) + +// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit +// #include <stdlib.h> +//// #include <HIToolbox/Events.h> +// #include "objc_darwin.h" +// extern void areaView_drawRect(id, struct xrect); +import "C" + +const ( + _goArea = "goArea" +) + +var ( + _drawRect = sel_getUid("drawRect:") +) + +func mkAreaClass() error { + areaclass, err := makeAreaClass(_goArea) + if err != nil { + return fmt.Errorf("error creating Area backend class: %v", err) + } +// // TODO rename this function (it overrides anyway) + // addAreaViewDrawMethod() is in bleh_darwin.m + ok := C.addAreaViewDrawMethod(areaclass) + if ok != C.BOOL(C.YES) { + return fmt.Errorf("error overriding Area drawRect: method; reason unknown") + } + return nil +} + +//export areaView_drawRect +func areaView_drawRect(self C.id, rect C.struct_xrect) { + // TODO +} + +// TODO combine the below with the delegate stuff + +var ( + _NSView = objc_getClass("NSView") + _NSView_Class = C.object_getClass(_NSView) +) + +func makeAreaClass(name string) (C.Class, error) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + c := C.objc_allocateClassPair(_NSView_Class, cname, 0) + if c == C.NilClass { + return C.NilClass, fmt.Errorf("unable to create Objective-C class %s for Area; reason unknown", name) + } + C.objc_registerClassPair(c) + return c, nil +} + +var ( + // delegate_rect in bleh_darwin.m +) diff --git a/bleh_darwin.m b/bleh_darwin.m index 08b02bb..ac6182a 100644 --- a/bleh_darwin.m +++ b/bleh_darwin.m @@ -184,3 +184,36 @@ id makeDummyEvent() (NSInteger) 0, /* data1: */ (NSInteger) 0); /* data2: */ } + +/* +[NSView drawRect:] needs to be overridden in our Area subclass. This takes a NSRect, which I'm not sure how to encode, so we're going to have to use @encode() and hope for the best for portability. +*/ + +extern void areaView_drawRect(id, struct xrect); + +static void _areaView_drawRect(id self, SEL sel, NSRect r) +{ + struct xrect t; + + t.x = (int64_t) r.origin.x; + t.y = (int64_t) r.origin.y; + t.width = (int64_t) r.size.width; + t.height = (int64_t) r.size.height; + areaView_drawRect(self, t); +} + +/* the only objective-c feature you'll see here */ +/* TODO correct? "v@:" @encode(NSRect) complained about missing ; */ +static char *avdrType = @encode(void(id, SEL, NSRect)); + +static SEL drawRect; +static BOOL drawRect_init = NO; + +BOOL addAreaViewDrawMethod(Class what) +{ + if (drawRect_init == NO) { + drawRect = sel_getUid("drawRect:"); + drawRect_init = YES; + } + return class_addMethod(what, drawRect, (IMP) _areaView_drawRect, avdrType); +} diff --git a/delegate_darwin.go b/delegate_darwin.go index a1c835d..c60689d 100644 --- a/delegate_darwin.go +++ b/delegate_darwin.go @@ -85,13 +85,13 @@ var ( //export appDelegate_windowDidResize func appDelegate_windowDidResize(self C.id, sel C.SEL, notification C.id) { win := C.objc_msgSend_noargs(notification, _object) - sysData := getSysData(win) + s := getSysData(win) wincv := C.objc_msgSend_noargs(win, _contentView) // we want the content view's size, not the window's; selector defined in sysdata_darwin.go r := C.objc_msgSend_stret_rect_noargs(wincv, _frame) - if sysData.resize != nil { + if s.resize != nil { // winheight is used here because (0,0) is the bottom-left corner, not the top-left corner s.resizes = s.resizes[0:0] // set len to 0 without changing cap - s.resize(0, 0, width, height, &s.resizes) + s.resize(0, 0, int(r.width), int(r.height), &s.resizes) for _, s := range s.resizes { err := s.sysData.setRect(s.x, s.y, s.width, s.height, int(r.height)) if err != nil { @@ -120,7 +120,7 @@ func makeDelegateClass(name string) (C.Class, error) { c := C.objc_allocateClassPair(_NSObject_Class, cname, 0) if c == C.NilClass { - return C.NilClass, fmt.Errorf("unable to create Objective-C class %s; reason unknown", name) + return C.NilClass, fmt.Errorf("unable to create Objective-C class %s for NSApplication delegate; reason unknown", name) } C.objc_registerClassPair(c) return c, nil @@ -136,7 +136,7 @@ func addDelegateMethod(class C.Class, sel C.SEL, imp unsafe.Pointer, ty []C.char ok := C.class_addMethod(class, sel, C.IMP(imp), &ty[0]) if ok == C.BOOL(C.NO) { // TODO get function name - return fmt.Errorf("unable to add selector %v/imp %v (reason unknown)", sel, imp) + return fmt.Errorf("unable to add selector %v/imp %v to class %v (reason unknown)", sel, imp, class) } return nil } diff --git a/objc_darwin.h b/objc_darwin.h index f73bc2b..e94c128 100644 --- a/objc_darwin.h +++ b/objc_darwin.h @@ -104,4 +104,7 @@ extern uintptr_t *NSIndexSetEntries(id, uintptr_t); /* for uitask_darwin.go */ extern id makeDummyEvent(); +/* for area_darwin.go */ +extern BOOL addAreaViewDrawMethod(Class); + #endif |
