summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--area_darwin.go65
-rw-r--r--bleh_darwin.m33
-rw-r--r--delegate_darwin.go10
-rw-r--r--objc_darwin.h3
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