From 1953f2d748a097e7a0e6ecfd2a2db2acf5fbca10 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 16 Jul 2014 13:25:09 -0400 Subject: [PATCH] Added Button and control adding to the Mac OS X backend. --- redo/controls_darwin.go | 92 +++++++++++++++++++++++++++++++++++++++++ redo/controls_darwin.m | 47 +++++++++++++++++++++ redo/objc_darwin.h | 7 ++++ redo/window_darwin.go | 13 +++--- 4 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 redo/controls_darwin.go create mode 100644 redo/controls_darwin.m diff --git a/redo/controls_darwin.go b/redo/controls_darwin.go new file mode 100644 index 0000000..91dcb65 --- /dev/null +++ b/redo/controls_darwin.go @@ -0,0 +1,92 @@ +// 16 july 2014 + +package ui + +import ( + "unsafe" +) + +// #include "objc_darwin.h" +import "C" + +// TODO move to common_darwin.go +func toBOOL(b bool) C.BOOL { + if b == true { + return C.YES + } + return C.NO +} + +type widgetbase struct { + id C.id + parentw *window + floating bool +} + +func newWidget(id C.id) *widgetbase { + return &widgetbase{ + id: id, + } +} + +// these few methods are embedded by all the various Controls since they all will do the same thing + +func (w *widgetbase) unparent() { + if w.parentw != nil { + C.unparent(w.id) + w.floating = true + w.parentw = nil + } +} + +func (w *widgetbase) parent(win *window) { + C.parent(w.id, win.id, toBOOL(w.floating)) + w.floating = false + w.parentw = win +} + +type button struct { + *widgetbase +} + +func newButton(text string) *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + c <- &button{ + widgetbase: newWidget(C.newButton(ctext)), + } + }, + resp: c, + } +} + +func (b *button) OnClicked(e func(c Doer)) *Request { + // TODO + return nil +} + +func (b *button) Text() *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + c <- C.GoString(C.buttonText(b.id)) + }, + resp: c, + } +} + +func (b *button) SetText(text string) *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + C.buttonSetText(b.id, ctext) + c <- struct{}{} + }, + resp: c, + } +} diff --git a/redo/controls_darwin.m b/redo/controls_darwin.m new file mode 100644 index 0000000..a21ac0f --- /dev/null +++ b/redo/controls_darwin.m @@ -0,0 +1,47 @@ +// 16 july 2014 + +#import "objc_darwin.h" +#import "_cgo_export.h" +#import + +#define toNSView(x) ((NSView *) (x)) +#define toNSWindow(x) ((NSWindow *) (x)) +#define toNSButton(x) ((NSButton *) (x)) + +void unparent(id control) +{ + [toNSView(control) retain]; // save from being freed when released by the removal selector below + // TODO removeFromSuperviewWithoutNeedingDisplay? + [toNSView(control) removeFromSuperview]; +} + +void parent(id control, id parentid, BOOL floating) +{ + [[toNSWindow(parentid) contentView] addSubview:toNSView(control)]; + if (floating) // previously unparented + [toNSView(control) release]; +} + +id newButton(char *text) +{ + NSButton *b; + + // TODO cache the initial rect? + b = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + // TODO verify all of these against Interface Builder + [b setButtonType:NSMomentaryLightButton]; + [b setTitle:[NSString stringWithUTF8String:text]]; + [b setBordered:YES]; + [b setBezelStyle:NSRoundedBezelStyle]; + return b; +} + +const char *buttonText(id button) +{ + return [[toNSButton(button) title] UTF8String]; +} + +void buttonSetText(id button, char *text) +{ + [toNSButton(button) setTitle:[NSString stringWithUTF8String:text]]; +} diff --git a/redo/objc_darwin.h b/redo/objc_darwin.h index 3de8a29..4c5365e 100644 --- a/redo/objc_darwin.h +++ b/redo/objc_darwin.h @@ -26,4 +26,11 @@ extern void windowShow(id); extern void windowHide(id); extern void windowClose(id); +/* controls_darwin.m */ +extern void unparent(id); +extern void parent(id, id, BOOL); +extern id newButton(char *); +extern const char *buttonText(id); +extern void buttonSetText(id, char *); + #endif diff --git a/redo/window_darwin.go b/redo/window_darwin.go index be9ceec..d9a72a4 100644 --- a/redo/window_darwin.go +++ b/redo/window_darwin.go @@ -13,6 +13,8 @@ import "C" type window struct { id C.id + child Control + closing *event } @@ -39,8 +41,12 @@ func (w *window) SetControl(control Control) *Request { c := make(chan interface{}) return &Request{ op: func() { - // TODO unparent - // TODO reparent + if w.child != nil { // unparent existing control + w.child.unparent() + } + control.unparent() + control.parent(w) + w.child = control c <- struct{}{} }, resp: c, @@ -131,6 +137,3 @@ func windowResized(xw unsafe.Pointer, width C.uintptr_t, height C.uintptr_t) { _=w//TODO fmt.Printf("new size %d x %d\n", width, height) } - -// TODO for testing -func newButton(string) *Request { return nil }