summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--redo/controls_darwin.go92
-rw-r--r--redo/controls_darwin.m47
-rw-r--r--redo/objc_darwin.h7
-rw-r--r--redo/window_darwin.go13
4 files changed, 154 insertions, 5 deletions
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 <Cocoa/Cocoa.h>
+
+#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 }