// 27 february 2014 package ui import ( // ... ) /* This creates a class goAppDelegate that will be used as the delegate for /everything/. Specifically, it: - runs uitask requests (uitask:) - handles window close events (windowShouldClose:) - handles window resize events (windowDidResize:) - handles button click events (buttonClicked:) - handles the application-global Quit event (such as from the Dock) (applicationShouldTerminate) */ // #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit // #include // #include "objc_darwin.h" // extern void appDelegate_uitask(id, SEL, id); /* from uitask_darwin.go */ // extern BOOL appDelegate_windowShouldClose(id, SEL, id); // extern void appDelegate_windowDidResize(id, SEL, id); // extern void appDelegate_buttonClicked(id, SEL, id); import "C" var ( appDelegate C.id ) const ( _goAppDelegate = "goAppDelegate" ) var ( _uitask = sel_getUid("uitask:") // used by uitask_darwin.go _buttonClicked = sel_getUid("buttonClicked:") // used by sysdata_darwin.go ) var appDelegateSels = []selector{ selector{"uitask:", uintptr(C.appDelegate_uitask), sel_void_id, "performing/dispatching UI events"}, selector{"windowShouldClose:", uintptr(C.appDelegate_windowShouldClose), sel_bool_id, "handling window close button events"}, selector{"windowDidResize:", uintptr(C.appDelegate_windowDidResize), sel_void_id, "handling window resize events"}, selector{"buttonClicked:", uintptr(C.appDelegate_buttonClicked), sel_bool_id, "handling button clicks"}, selector{"applicationShouldTerminate:", uintptr(C._appDelegate_applicationShouldTerminate), sel_terminatereply_id, "handling Quit menu items (such as from the Dock)/the AppQuit channel"}, } func mkAppDelegate() error { id, err := makeClass(_goAppDelegate, _NSObject, appDelegateSels, "application delegate (handles events)") if err != nil { return err } appDelegate = C.objc_msgSend_noargs(id, _new) return nil } //export appDelegate_windowShouldClose func appDelegate_windowShouldClose(self C.id, sel C.SEL, win C.id) C.BOOL { sysData := getSysData(win) sysData.signal() return C.BOOL(C.NO) // don't close } var ( _object = sel_getUid("object") _display = sel_getUid("display") ) //export appDelegate_windowDidResize func appDelegate_windowDidResize(self C.id, sel C.SEL, notification C.id) { win := C.objc_msgSend_noargs(notification, _object) 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) // winheight is used here because (0,0) is the bottom-left corner, not the top-left corner s.doResize(0, 0, int(r.width), int(r.height), int(r.height)) C.objc_msgSend_noargs(win, _display) // redraw everything; TODO only if resize() was called? } //export appDelegate_buttonClicked func appDelegate_buttonClicked(self C.id, sel C.SEL, button C.id) { sysData := getSysData(button) sysData.signal() } //export appDelegate_applicationShouldTerminate func appDelegate_applicationShouldTerminate() { // asynchronous so as to return control to the event loop go func() { AppQuit <- struct{}{} }() // xxx in bleh_darwin.m tells Cocoa not to quit }