From 7ea493873cb2be2eac1e6bb08c66a119e489b38e Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 4 Apr 2014 21:32:10 -0400 Subject: [PATCH] Changed the Area class on Mac OS X to use the new class creation code. This gets rid of ALL the class creation code from delegate_darwin.go. --- area_darwin.go | 103 ++++++++++++++++----------------------------- delegate_darwin.go | 24 ++--------- objc_darwin.go | 13 ++++-- 3 files changed, 49 insertions(+), 91 deletions(-) diff --git a/area_darwin.go b/area_darwin.go index 45675b9..5353607 100644 --- a/area_darwin.go +++ b/area_darwin.go @@ -28,62 +28,56 @@ const ( var ( _goArea C.id + _NSView = objc_getClass("NSView") _drawRect = sel_getUid("drawRect:") - _isFlipped = sel_getUid("isFlipped") - _acceptsFirstResponder = sel_getUid("acceptsFirstResponder") ) -// uintptr due to a bug; see https://code.google.com/p/go/issues/detail?id=7665 -type eventMethod struct { - sel string - m uintptr -} -var eventMethods = []eventMethod{ - eventMethod{"mouseMoved:", uintptr(C.areaView_mouseMoved)}, - eventMethod{"mouseDown:", uintptr(C.areaView_mouseDown_mouseDragged)}, - eventMethod{"mouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged)}, - eventMethod{"mouseUp:", uintptr(C.areaView_mouseUp)}, - eventMethod{"rightMouseDown:", uintptr(C.areaView_mouseDown_mouseDragged)}, - eventMethod{"rightMouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged)}, - eventMethod{"rightMouseUp:", uintptr(C.areaView_mouseUp)}, - eventMethod{"otherMouseDown:", uintptr(C.areaView_mouseDown_mouseDragged)}, - eventMethod{"otherMouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged)}, - eventMethod{"otherMouseUp:", uintptr(C.areaView_mouseUp)}, - eventMethod{"keyDown:", uintptr(C.areaView_keyDown)}, - eventMethod{"keyUp:", uintptr(C.areaView_keyUp)}, - eventMethod{"flagsChanged:", uintptr(C.areaView_flagsChanged)}, +var goAreaSels = []selector{ + selector{"isFlipped", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool, + "ensuring that an Area's coordinate system has (0,0) at the top-left corner"}, + selector{"acceptsFirstResponder", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool, + "registering that Areas are to receive events"}, + selector{"mouseMoved:", uintptr(C.areaView_mouseMoved), sel_void_id, + "handling mouse movements in Area"}, + selector{"mouseDown:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id, + "handling mouse button 1 presses in Area"}, + selector{"mouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id, + "handling mouse button 1 dragging in Area"}, + selector{"mouseUp:", uintptr(C.areaView_mouseUp), sel_void_id, + "handling mouse button 1 releases in Area"}, + selector{"rightMouseDown:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id, + "handling mouse button 3 presses in Area"}, + selector{"rightMouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id, + "handling mouse button 3 dragging in Area"}, + selector{"rightMouseUp:", uintptr(C.areaView_mouseUp), sel_void_id, + "handling mouse button 3 releases in Area"}, + selector{"otherMouseDown:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id, + "handling mouse button 2 (and 4 and higher) presses in Area"}, + selector{"otherMouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id, + "handling mouse button 2 (and 4 and higher) dragging in Area"}, + selector{"otherMouseUp:", uintptr(C.areaView_mouseUp), sel_void_id, + "handling mouse button 2 (and 4 and higher) releases in Area"}, + selector{"keyDown:", uintptr(C.areaView_keyDown), sel_void_id, + "handling key presses in Area"}, + selector{"keyUp:", uintptr(C.areaView_keyUp), sel_void_id, + "handling key releases in Area"}, + selector{"flagsChanged:", uintptr(C.areaView_flagsChanged), sel_void_id, + "handling Modifiers presses and releases in Area"}, } func mkAreaClass() error { - areaclass, err := makeAreaClass(__goArea) + id, class, err := makeClass(__goArea, _NSView, goAreaSels, + "the implementation of Area on Mac OS X") if err != nil { - return fmt.Errorf("error creating Area backend class: %v", err) + return err } // addAreaViewDrawMethod() is in bleh_darwin.m - ok := C.addAreaViewDrawMethod(areaclass) + ok := C.addAreaViewDrawMethod(class) if ok != C.BOOL(C.YES) { return fmt.Errorf("error overriding Area drawRect: method; reason unknown") } - // TODO rename this function (it overrides anyway) - err = addDelegateMethod(areaclass, _isFlipped, - C.areaView_isFlipped_acceptsFirstResponder, area_boolret) - if err != nil { - return fmt.Errorf("error overriding Area isFlipped method: %v", err) - } - err = addDelegateMethod(areaclass, _acceptsFirstResponder, - C.areaView_isFlipped_acceptsFirstResponder, area_boolret) - if err != nil { - return fmt.Errorf("error overriding Area acceptsFirstResponder method: %v", err) - } - for _, m := range eventMethods { - err = addDelegateMethod(areaclass, sel_getUid(m.sel), - unsafe.Pointer(m.m), delegate_void) - if err != nil { - return fmt.Errorf("error overriding Area %s method: %v", m.sel, err) - } - } - _goArea = objc_getClass(__goArea) + _goArea = id return nil } @@ -298,26 +292,3 @@ func makeArea(parentWindow C.id, alternate bool) C.id { addControl(parentWindow, area) return area } - -// TODO combine the below with the delegate stuff - -var ( - _NSView = objc_getClass("NSView") - _NSView_Class = C.Class(unsafe.Pointer(_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 ( - area_boolret = []C.char{'c', '@', ':', 0} // BOOL (*)(id, SEL) -) diff --git a/delegate_darwin.go b/delegate_darwin.go index 460e930..87cf4d8 100644 --- a/delegate_darwin.go +++ b/delegate_darwin.go @@ -3,8 +3,7 @@ package ui import ( - "fmt" - "unsafe" + // ... ) /* @@ -49,12 +48,12 @@ var appDelegateSels = []selector{ } func mkAppDelegate() error { - err := makeClass(_goAppDelegate, _NSObject, appDelegateSels, + id, _, err := makeClass(_goAppDelegate, _NSObject, appDelegateSels, "application delegate (handles events)") if err != nil { return err } - appDelegate = C.objc_msgSend_noargs(objc_getClass(_goAppDelegate), _new) + appDelegate = C.objc_msgSend_noargs(id, _new) return nil } @@ -95,20 +94,3 @@ func appDelegate_buttonClicked(self C.id, sel C.SEL, button C.id) { sysData := getSysData(button) sysData.signal() } - -// this actually constructs the delegate class - -var ( - delegate_void = []C.char{'v', '@', ':', '@', 0} // void (*)(id, SEL, id) - delegate_bool = []C.char{'c', '@', ':', '@', 0} // BOOL (*)(id, SEL, id) -) - -// according to errors spit out by cgo, C function pointers are unsafe.Pointer -func addDelegateMethod(class C.Class, sel C.SEL, imp unsafe.Pointer, ty []C.char) error { - 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 to class %v (reason unknown)", sel, imp, class) - } - return nil -} diff --git a/objc_darwin.go b/objc_darwin.go index 90afd74..b72dcdd 100644 --- a/objc_darwin.go +++ b/objc_darwin.go @@ -62,19 +62,22 @@ type selector struct { desc string // for error reporting } +// sel_[returntype] or sel_[returntype]_[arguments] (after the required self/sel arguments) type itype uint const ( sel_void_id itype = iota sel_bool_id + sel_bool nitypes ) var itypes = [nitypes][]C.char{ sel_void_id: []C.char{'v', '@', ':', '@', 0}, sel_bool_id: []C.char{'c', '@', ':', '@', 0}, + sel_bool: []C.char{'c', '@', ':', 0}, } -func makeClass(name string, super C.id, sels []selector, desc string) (err error) { +func makeClass(name string, super C.id, sels []selector, desc string) (id C.id, class C.Class, err error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) @@ -82,15 +85,17 @@ func makeClass(name string, super C.id, sels []selector, desc string) (err error // thanks to Psy| in irc.freenode.net/##objc c := C.objc_allocateClassPair(C.Class(unsafe.Pointer(super)), cname, 0) if c == C.NilClass { - return fmt.Errorf("unable to create Objective-C class %s for %s; reason unknown", name, desc) + err = fmt.Errorf("unable to create Objective-C class %s for %s; reason unknown", name, desc) + return } C.objc_registerClassPair(c) for _, v := range sels { ok := C.class_addMethod(c, sel_getUid(v.name), C.IMP(unsafe.Pointer(v.imp)), &itypes[v.itype][0]) if ok == C.BOOL(C.NO) { - return fmt.Errorf("unable to add selector %s to class %s (needed for %s; reason unknown)", v.name, name, v.desc) + err = fmt.Errorf("unable to add selector %s to class %s (needed for %s; reason unknown)", v.name, name, v.desc) + return } } - return nil + return objc_getClass(name), c, nil }