2014-02-27 19:48:32 -06:00
// 27 february 2014
package main
import (
"fmt"
"unsafe"
2014-02-28 14:08:07 -06:00
"time"
2014-02-27 19:48:32 -06:00
)
2014-02-27 20:53:44 -06:00
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
2014-02-27 19:48:32 -06:00
// #include <stdlib.h>
2014-02-28 17:30:06 -06:00
// #include "objc_darwin.h"
2014-02-27 22:07:45 -06:00
// Class NilClass = Nil; /* for newtypes.go */
2014-02-28 14:08:07 -06:00
// id Nilid = nil;
2014-02-27 19:48:32 -06:00
import "C"
2014-02-27 19:56:08 -06:00
func objc_getClass ( class string ) C . id {
cclass := C . CString ( class )
defer C . free ( unsafe . Pointer ( cclass ) )
return C . objc_getClass ( cclass )
}
func sel_getUid ( sel string ) C . SEL {
csel := C . CString ( sel )
defer C . free ( unsafe . Pointer ( csel ) )
return C . sel_getUid ( csel )
}
2014-02-28 10:06:20 -06:00
var NSApp C . id
2014-02-28 14:08:07 -06:00
var defNC C . id
var delegate C . id
2014-02-28 16:20:22 -06:00
var notesel C . SEL
2014-02-28 10:06:20 -06:00
func init ( ) {
// need an NSApplication first - see https://github.com/TooTallNate/NodObjC/issues/21
NSApplication := objc_getClass ( "NSApplication" )
sharedApplication := sel_getUid ( "sharedApplication" )
NSApp = C . objc_msgSend_noargs ( NSApplication , sharedApplication )
2014-02-28 14:08:07 -06:00
defNC = C . objc_msgSend_noargs (
objc_getClass ( "NSNotificationCenter" ) ,
sel_getUid ( "defaultCenter" ) )
2014-02-28 10:55:35 -06:00
selW := sel_getUid ( "windowShouldClose:" )
selB := sel_getUid ( "buttonClicked:" )
2014-02-28 14:08:07 -06:00
selN := sel_getUid ( "gotNotification:" )
mk ( "hello" , selW , selB , selN )
delegate = C . objc_msgSend_noargs (
objc_getClass ( "hello" ) ,
alloc )
2014-02-28 16:20:22 -06:00
notesel = selN
2014-02-27 22:07:45 -06:00
}
2014-02-27 20:53:44 -06:00
const (
NSBorderlessWindowMask = 0
NSTitledWindowMask = 1 << 0
NSClosableWindowMask = 1 << 1
NSMiniaturizableWindowMask = 1 << 2
NSResizableWindowMask = 1 << 3
NSTexturedBackgroundWindowMask = 1 << 8
)
const (
// NSBackingStoreRetained = 0 // "You should not use this mode."
// NSBackingStoreNonretained = 1 // "You should not use this mode."
NSBackingStoreBuffered = 2
)
2014-02-28 11:09:15 -06:00
const (
NSRoundedBezelStyle = 1
)
2014-02-27 20:53:44 -06:00
var alloc = sel_getUid ( "alloc" )
2014-02-28 14:08:07 -06:00
func notify ( source string ) {
csource := C . CString ( source )
defer C . free ( unsafe . Pointer ( csource ) )
2014-02-28 16:32:55 -06:00
// we need to make an NSAutoreleasePool, otherwise we get leak warnings on stderr
pool := C . objc_msgSend_noargs (
objc_getClass ( "NSAutoreleasePool" ) ,
sel_getUid ( "new" ) )
2014-02-28 17:30:06 -06:00
src := C . objc_msgSend_str (
2014-02-28 14:08:07 -06:00
objc_getClass ( "NSString" ) ,
sel_getUid ( "stringWithUTF8String:" ) ,
csource )
2014-02-28 16:20:22 -06:00
C . objc_msgSend_sel_id_bool (
delegate ,
sel_getUid ( "performSelectorOnMainThread:withObject:waitUntilDone:" ) ,
notesel ,
2014-02-28 14:08:07 -06:00
src ,
2014-02-28 18:34:18 -06:00
C . BOOL ( C . YES ) ) // wait so we can properly drain the autorelease pool; on other platforms we wind up waiting anyway (since the main thread can only handle one thing at a time) so
2014-02-28 16:32:55 -06:00
C . objc_msgSend_noargs ( pool ,
sel_getUid ( "release" ) )
2014-02-28 14:08:07 -06:00
}
2014-02-28 10:06:20 -06:00
func main ( ) {
2014-02-27 20:53:44 -06:00
NSWindow := objc_getClass ( "NSWindow" )
NSWindowinit :=
sel_getUid ( "initWithContentRect:styleMask:backing:defer:" )
2014-02-28 10:06:20 -06:00
setDelegate := sel_getUid ( "setDelegate:" )
2014-02-27 20:53:44 -06:00
makeKeyAndOrderFront := sel_getUid ( "makeKeyAndOrderFront:" )
2014-02-28 18:34:18 -06:00
style := uintptr ( NSTitledWindowMask | NSClosableWindowMask )
backing := uintptr ( NSBackingStoreBuffered )
2014-02-27 20:53:44 -06:00
deferx := C . BOOL ( C . YES )
window := C . objc_msgSend_noargs ( NSWindow , alloc )
2014-02-28 18:34:18 -06:00
window = objc_msgSend_rect_uint_uint_bool ( window , NSWindowinit ,
100 , 100 , 320 , 240 ,
style , backing , deferx )
2014-02-27 20:53:44 -06:00
C . objc_msgSend_id ( window , makeKeyAndOrderFront , window )
2014-02-28 10:06:20 -06:00
C . objc_msgSend_id ( window , setDelegate ,
delegate )
2014-02-28 10:55:35 -06:00
windowView := C . objc_msgSend_noargs ( window ,
sel_getUid ( "contentView" ) )
NSButton := objc_getClass ( "NSButton" )
button := C . objc_msgSend_noargs ( NSButton , alloc )
2014-02-28 18:34:18 -06:00
button = objc_msgSend_rect ( button ,
2014-02-28 10:55:35 -06:00
sel_getUid ( "initWithFrame:" ) ,
2014-02-28 18:34:18 -06:00
20 , 20 , 200 , 200 )
2014-02-28 10:55:35 -06:00
C . objc_msgSend_id ( button ,
sel_getUid ( "setTarget:" ) ,
delegate )
C . objc_msgSend_sel ( button ,
sel_getUid ( "setAction:" ) ,
sel_getUid ( "buttonClicked:" ) )
2014-02-28 18:34:18 -06:00
objc_msgSend_uint ( button ,
2014-02-28 11:09:15 -06:00
sel_getUid ( "setBezelStyle:" ) ,
2014-02-28 18:34:18 -06:00
NSRoundedBezelStyle )
2014-02-28 10:55:35 -06:00
C . objc_msgSend_id ( windowView ,
sel_getUid ( "addSubview:" ) ,
button )
2014-02-28 14:08:07 -06:00
go func ( ) {
for {
<- time . After ( 5 * time . Second )
fmt . Println ( "five seconds passed; sending notification..." )
notify ( "timer" )
}
} ( )
2014-02-28 10:06:20 -06:00
C . objc_msgSend_noargs ( NSApp ,
sel_getUid ( "run" ) )
2014-02-27 20:53:44 -06:00
}
func helloworld ( ) {
2014-02-27 19:48:32 -06:00
_hello := C . CString ( "hello, world\n" )
defer C . free ( unsafe . Pointer ( _hello ) )
2014-02-27 19:56:08 -06:00
NSString := objc_getClass ( "NSString" )
2014-02-27 19:48:32 -06:00
stringWithUTF8String :=
2014-02-27 19:56:08 -06:00
sel_getUid ( "stringWithUTF8String:" )
2014-02-28 17:30:06 -06:00
str := C . objc_msgSend_str ( NSString ,
2014-02-27 19:48:32 -06:00
stringWithUTF8String ,
_hello )
2014-02-27 19:56:08 -06:00
UTF8String := sel_getUid ( "UTF8String" )
2014-02-27 19:48:32 -06:00
res := C . objc_msgSend_noargs ( str ,
UTF8String )
cres := ( * C . char ) ( unsafe . Pointer ( res ) )
fmt . Printf ( "%s" , C . GoString ( cres ) )
}