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.
This commit is contained in:
parent
dd20d56f25
commit
7ea493873c
103
area_darwin.go
103
area_darwin.go
|
@ -28,62 +28,56 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_goArea C.id
|
_goArea C.id
|
||||||
|
_NSView = objc_getClass("NSView")
|
||||||
|
|
||||||
_drawRect = sel_getUid("drawRect:")
|
_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
|
var goAreaSels = []selector{
|
||||||
type eventMethod struct {
|
selector{"isFlipped", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool,
|
||||||
sel string
|
"ensuring that an Area's coordinate system has (0,0) at the top-left corner"},
|
||||||
m uintptr
|
selector{"acceptsFirstResponder", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool,
|
||||||
}
|
"registering that Areas are to receive events"},
|
||||||
var eventMethods = []eventMethod{
|
selector{"mouseMoved:", uintptr(C.areaView_mouseMoved), sel_void_id,
|
||||||
eventMethod{"mouseMoved:", uintptr(C.areaView_mouseMoved)},
|
"handling mouse movements in Area"},
|
||||||
eventMethod{"mouseDown:", uintptr(C.areaView_mouseDown_mouseDragged)},
|
selector{"mouseDown:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id,
|
||||||
eventMethod{"mouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged)},
|
"handling mouse button 1 presses in Area"},
|
||||||
eventMethod{"mouseUp:", uintptr(C.areaView_mouseUp)},
|
selector{"mouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id,
|
||||||
eventMethod{"rightMouseDown:", uintptr(C.areaView_mouseDown_mouseDragged)},
|
"handling mouse button 1 dragging in Area"},
|
||||||
eventMethod{"rightMouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged)},
|
selector{"mouseUp:", uintptr(C.areaView_mouseUp), sel_void_id,
|
||||||
eventMethod{"rightMouseUp:", uintptr(C.areaView_mouseUp)},
|
"handling mouse button 1 releases in Area"},
|
||||||
eventMethod{"otherMouseDown:", uintptr(C.areaView_mouseDown_mouseDragged)},
|
selector{"rightMouseDown:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id,
|
||||||
eventMethod{"otherMouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged)},
|
"handling mouse button 3 presses in Area"},
|
||||||
eventMethod{"otherMouseUp:", uintptr(C.areaView_mouseUp)},
|
selector{"rightMouseDragged:", uintptr(C.areaView_mouseDown_mouseDragged), sel_void_id,
|
||||||
eventMethod{"keyDown:", uintptr(C.areaView_keyDown)},
|
"handling mouse button 3 dragging in Area"},
|
||||||
eventMethod{"keyUp:", uintptr(C.areaView_keyUp)},
|
selector{"rightMouseUp:", uintptr(C.areaView_mouseUp), sel_void_id,
|
||||||
eventMethod{"flagsChanged:", uintptr(C.areaView_flagsChanged)},
|
"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 {
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating Area backend class: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
// addAreaViewDrawMethod() is in bleh_darwin.m
|
// addAreaViewDrawMethod() is in bleh_darwin.m
|
||||||
ok := C.addAreaViewDrawMethod(areaclass)
|
ok := C.addAreaViewDrawMethod(class)
|
||||||
if ok != C.BOOL(C.YES) {
|
if ok != C.BOOL(C.YES) {
|
||||||
return fmt.Errorf("error overriding Area drawRect: method; reason unknown")
|
return fmt.Errorf("error overriding Area drawRect: method; reason unknown")
|
||||||
}
|
}
|
||||||
// TODO rename this function (it overrides anyway)
|
_goArea = id
|
||||||
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)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,26 +292,3 @@ func makeArea(parentWindow C.id, alternate bool) C.id {
|
||||||
addControl(parentWindow, area)
|
addControl(parentWindow, area)
|
||||||
return 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)
|
|
||||||
)
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
// ...
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,12 +48,12 @@ var appDelegateSels = []selector{
|
||||||
}
|
}
|
||||||
|
|
||||||
func mkAppDelegate() error {
|
func mkAppDelegate() error {
|
||||||
err := makeClass(_goAppDelegate, _NSObject, appDelegateSels,
|
id, _, err := makeClass(_goAppDelegate, _NSObject, appDelegateSels,
|
||||||
"application delegate (handles events)")
|
"application delegate (handles events)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
appDelegate = C.objc_msgSend_noargs(objc_getClass(_goAppDelegate), _new)
|
appDelegate = C.objc_msgSend_noargs(id, _new)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,20 +94,3 @@ func appDelegate_buttonClicked(self C.id, sel C.SEL, button C.id) {
|
||||||
sysData := getSysData(button)
|
sysData := getSysData(button)
|
||||||
sysData.signal()
|
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -62,19 +62,22 @@ type selector struct {
|
||||||
desc string // for error reporting
|
desc string // for error reporting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sel_[returntype] or sel_[returntype]_[arguments] (after the required self/sel arguments)
|
||||||
type itype uint
|
type itype uint
|
||||||
const (
|
const (
|
||||||
sel_void_id itype = iota
|
sel_void_id itype = iota
|
||||||
sel_bool_id
|
sel_bool_id
|
||||||
|
sel_bool
|
||||||
nitypes
|
nitypes
|
||||||
)
|
)
|
||||||
|
|
||||||
var itypes = [nitypes][]C.char{
|
var itypes = [nitypes][]C.char{
|
||||||
sel_void_id: []C.char{'v', '@', ':', '@', 0},
|
sel_void_id: []C.char{'v', '@', ':', '@', 0},
|
||||||
sel_bool_id: []C.char{'c', '@', ':', '@', 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)
|
cname := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(cname))
|
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
|
// thanks to Psy| in irc.freenode.net/##objc
|
||||||
c := C.objc_allocateClassPair(C.Class(unsafe.Pointer(super)), cname, 0)
|
c := C.objc_allocateClassPair(C.Class(unsafe.Pointer(super)), cname, 0)
|
||||||
if c == C.NilClass {
|
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)
|
C.objc_registerClassPair(c)
|
||||||
for _, v := range sels {
|
for _, v := range sels {
|
||||||
ok := C.class_addMethod(c, sel_getUid(v.name),
|
ok := C.class_addMethod(c, sel_getUid(v.name),
|
||||||
C.IMP(unsafe.Pointer(v.imp)), &itypes[v.itype][0])
|
C.IMP(unsafe.Pointer(v.imp)), &itypes[v.itype][0])
|
||||||
if ok == C.BOOL(C.NO) {
|
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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue