Added the beginning of the Mac OS X code.
This commit is contained in:
parent
60d0953fe9
commit
b4357db4be
|
@ -1,3 +1,5 @@
|
|||
// +build !darwin
|
||||
|
||||
// 7 july 2014
|
||||
|
||||
package ui
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build !darwin
|
||||
|
||||
// 7 july 2014
|
||||
|
||||
package ui
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* 8 july 2014 */
|
||||
|
||||
/* cgo will include this file multiple times */
|
||||
#ifndef __GO_UI_OBJC_DARWIN_H__
|
||||
#define __GO_UI_OBJC_DARWIN_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <objc/message.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
/* uitask_darwin.m */
|
||||
extern id getAppDelegate(void); /* used by the other .m files */
|
||||
extern BOOL uiinit(void);
|
||||
extern void uimsgloop(void);
|
||||
extern void issue(void *);
|
||||
|
||||
/* window_darwin.m */
|
||||
extern id newWindow(intptr_t, intptr_t);
|
||||
extern void windowSetAppDelegate(id);
|
||||
extern const char *windowTitle(id);
|
||||
extern void windowSetTitle(id, const char *);
|
||||
extern void windowShow(id);
|
||||
extern void windowHide(id);
|
||||
extern void windowClose(id);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
// 8 july 2014
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -DTODO
|
||||
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
|
||||
// #include "objc_darwin.h"
|
||||
import "C"
|
||||
|
||||
func uiinit() error {
|
||||
// TODO check error
|
||||
C.uiinit()
|
||||
return nil
|
||||
}
|
||||
|
||||
func uimsgloop() {
|
||||
C.uimsgloop()
|
||||
}
|
||||
|
||||
func issue(req *Request) {
|
||||
C.issue(unsafe.Pointer(req))
|
||||
}
|
||||
|
||||
//export doissue
|
||||
func doissue(r unsafe.Pointer) {
|
||||
req := (*Request)(unsafe.Pointer(r))
|
||||
perform(req)
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
// 8 july 2014
|
||||
|
||||
#import "objc_darwin.h"
|
||||
#import "_cgo_export.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface appDelegateClass : NSObject
|
||||
@end
|
||||
|
||||
@implementation appDelegateClass
|
||||
|
||||
- (void)issue:(id)obj
|
||||
{
|
||||
NSValue *what = (NSValue *) obj;
|
||||
|
||||
doissue([what pointerValue]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
appDelegateClass *appDelegate;
|
||||
|
||||
id getAppDelegate(void)
|
||||
{
|
||||
return appDelegate;
|
||||
}
|
||||
|
||||
BOOL uiinit(void)
|
||||
{
|
||||
appDelegate = [appDelegateClass new];
|
||||
[NSApplication sharedApplication];
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[NSApp activateIgnoringOtherApps:YES]; // TODO rsc does this; finder says NO?
|
||||
[NSApp setDelegate:appDelegate];
|
||||
return YES;
|
||||
}
|
||||
|
||||
void uimsgloop(void)
|
||||
{
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
// Ideally we would have this work like on the other platforms and issue a NSEvent to the end of the event queue
|
||||
// Unfortunately, there doesn't seem to be a way for NSEvents to hold pointer values, only (signed) NSIntegers
|
||||
// So we'll have to do the performSelectorOnMainThread: approach
|
||||
// [TODO]
|
||||
void issue(void *what)
|
||||
{
|
||||
NSAutoreleasePool *p;
|
||||
NSValue *v;
|
||||
|
||||
p = [NSAutoreleasePool new];
|
||||
v = [NSValue valueWithPointer:what];
|
||||
[appDelegate performSelectorOnMainThread:@selector(issue:)
|
||||
withObject:v
|
||||
waitUntilDone:NO];
|
||||
[p release];
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
// +build !darwin
|
||||
|
||||
// 7 july 2014
|
||||
|
||||
package ui
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
// 8 july 2014
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #include "objc_darwin.h"
|
||||
import "C"
|
||||
|
||||
type window struct {
|
||||
id C.id
|
||||
|
||||
closing *event
|
||||
}
|
||||
|
||||
func newWindow(title string, width int, height int) *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
id := C.newWindow(C.intptr_t(width), C.intptr_t(height))
|
||||
ctitle := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(ctitle))
|
||||
C.windowSetTitle(id, ctitle)
|
||||
C.windowSetAppDelegate(id)
|
||||
c <- &window{
|
||||
id: id,
|
||||
closing: newEvent(),
|
||||
}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) SetControl(control Control) *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
// TODO unparent
|
||||
// TODO reparent
|
||||
c <- struct{}{}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) Title() *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
c <- C.GoString(C.windowTitle(w.id))
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) SetTitle(title string) *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
ctitle := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(ctitle))
|
||||
C.windowSetTitle(w.id, ctitle)
|
||||
c <- struct{}{}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) Show() *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
C.windowShow(w.id)
|
||||
c <- struct{}{}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) Hide() *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
C.windowHide(w.id)
|
||||
c <- struct{}{}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) Close() *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
C.windowClose(w.id)
|
||||
c <- struct{}{}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) OnClosing(e func(c Doer) bool) *Request {
|
||||
c := make(chan interface{})
|
||||
return &Request{
|
||||
op: func() {
|
||||
w.closing.setbool(e)
|
||||
c <- struct{}{}
|
||||
},
|
||||
resp: c,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO windowClosing
|
||||
|
||||
// TODO for testing
|
||||
func newButton(string) *Request { return nil }
|
|
@ -0,0 +1,45 @@
|
|||
// 8 july 2014
|
||||
|
||||
#import "objc_darwin.h"
|
||||
#import "_cgo_export.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#define toNSWindow(x) ((NSWindow *) (x))
|
||||
|
||||
id newWindow(intptr_t width, intptr_t height)
|
||||
{
|
||||
return [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, (CGFloat) width, (CGFloat) height)
|
||||
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES];
|
||||
}
|
||||
|
||||
void windowSetAppDelegate(id win)
|
||||
{
|
||||
[toNSWindow(win) setDelegate:getAppDelegate()];
|
||||
}
|
||||
|
||||
const char *windowTitle(id win)
|
||||
{
|
||||
return [[toNSWindow(win) title] UTF8String];
|
||||
}
|
||||
|
||||
void windowSetTitle(id win, const char * title)
|
||||
{
|
||||
[toNSWindow(win) setTitle:[NSString stringWithUTF8String:title]];
|
||||
}
|
||||
|
||||
void windowShow(id win)
|
||||
{
|
||||
[toNSWindow(win) makeKeyAndOrderFront:toNSWindow(win)];
|
||||
}
|
||||
|
||||
void windowHide(id win)
|
||||
{
|
||||
[toNSWindow(win) orderOut:toNSWindow(win)];
|
||||
}
|
||||
|
||||
void windowClose(id win)
|
||||
{
|
||||
// TODO
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
// +build !darwin
|
||||
|
||||
// 7 july 2014
|
||||
|
||||
package ui
|
||||
|
|
|
@ -8,7 +8,8 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestPackage(t *testing.T) {
|
||||
// because Cocoa hates being run off the main thread, even if it's run exclusively off the main thread
|
||||
func init() {
|
||||
go func() {
|
||||
w := GetNewWindow(Do, "Hello", 320, 240)
|
||||
done := make(chan struct{})
|
||||
|
@ -21,6 +22,10 @@ func TestPackage(t *testing.T) {
|
|||
}()
|
||||
err := Go()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDummy(t *testing.T) {
|
||||
// do nothing
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue