diff --git a/redo/area_darwin.go b/redo/area_darwin.go index ad82777..4bd5902 100644 --- a/redo/area_darwin.go +++ b/redo/area_darwin.go @@ -3,6 +3,7 @@ package ui import ( + "fmt" "image" "unsafe" ) @@ -14,17 +15,21 @@ import "C" type area struct { *areabase - _id C.id - scroller *scroller + _id C.id + scroller *scroller + textfield C.id + textfielddone *event } func newArea(ab *areabase) Area { a := &area{ areabase: ab, + textfielddone: newEvent(), } a._id = C.newArea(unsafe.Pointer(a)) a.scroller = newScroller(a._id, false) // no border on Area a.SetSize(a.width, a.height) + a.textfield = C.newAreaTextField(a._id, unsafe.Pointer(a)) return a } @@ -53,6 +58,33 @@ func (a *area) RepaintAll() { C.areaRepaintAll(a._id) } +func (a *area) OpenTextFieldAt(x, y int) { + if x < 0 || x >= a.width || y < 0 || y >= a.height { + panic(fmt.Errorf("point (%d,%d) outside Area in Area.OpenTextFieldAt()", x, y)) + } + C.areaTextFieldOpen(a.textfield, C.intptr_t(x), C.intptr_t(y)) +} + +func (a *area) TextFieldText() string { + return C.GoString(C.textFieldText(a.textfield)) +} + +func (a *area) SetTextFieldText(text string) { + ctext := C.CString(text) + defer C.free(unsafe.Pointer(ctext)) + C.textFieldSetText(a.textfield, ctext) +} + +func (a *area) OnTextFieldDismissed(f func()) { + a.textfielddone.set(f) +} + +//export areaTextFieldDismissed +func areaTextFieldDismissed(data unsafe.Pointer) { + a := (*area)(unsafe.Pointer(data)) + a.textfielddone.fire() +} + //export areaView_drawRect func areaView_drawRect(self C.id, rect C.struct_xrect, data unsafe.Pointer) { a := (*area)(data) diff --git a/redo/area_darwin.m b/redo/area_darwin.m index b3d095e..280cb9e 100644 --- a/redo/area_darwin.m +++ b/redo/area_darwin.m @@ -6,6 +6,7 @@ #define toNSEvent(x) ((NSEvent *) (x)) #define toNSView(x) ((NSView *) (x)) +#define toNSTextField(x) ((NSTextField *) (x)) #define toNSInteger(x) ((NSInteger) (x)) #define fromNSInteger(x) ((intptr_t) (x)) @@ -203,3 +204,44 @@ void areaRepaintAll(id view) { [toNSView(view) display]; } + +@interface goAreaTextField : NSTextField { +@public + void *goarea; +} +@end + +@implementation goAreaTextField +/* +- (BOOL)resignFirstResponder +{ + [self setHidden:YES]; + areaTextFieldDismissed(self->goarea); + return [super resignFirstResponder]; +} +*/ +@end + +id newAreaTextField(id area, void *goarea) +{ + goAreaTextField *tf; + + tf = [[goAreaTextField alloc] initWithFrame:NSZeroRect]; + finishNewTextField((id) tf, YES); + [toNSView(area) addSubview:tf]; + [tf setHidden:YES]; + tf->goarea = goarea; + return (id) tf; +} + +void areaTextFieldOpen(id textfield, intptr_t x, intptr_t y) +{ + NSTextField *tf = toNSTextField(textfield); + + [tf sizeToFit]; + // TODO + [tf setFrameSize:NSMakeSize(150, 20)]; + [tf setFrameOrigin:NSMakePoint((CGFloat) x, (CGFloat) y)]; + [tf setHidden:NO]; + [[tf window] makeFirstResponder:tf]; +} diff --git a/redo/basicctrls_darwin.m b/redo/basicctrls_darwin.m index 6f2769c..8ca447f 100644 --- a/redo/basicctrls_darwin.m +++ b/redo/basicctrls_darwin.m @@ -106,8 +106,11 @@ void checkboxSetChecked(id c, BOOL checked) } // also good for labels -static id finishNewTextField(NSTextField *t, BOOL bordered) +// not static because area_darwin.m uses it +id finishNewTextField(id _t, BOOL bordered) { + NSTextField *t = toNSTextField(_t); + // same for text fields, password fields, and labels setStandardControlFont((id) t); // these three are the same across text fields, password fields, and labels; the only difference is the setBezeled: value, and it's only different on labels @@ -131,7 +134,7 @@ id newTextField(void) NSTextField *t; t = [[NSTextField alloc] initWithFrame:NSZeroRect]; - return finishNewTextField(t, YES); + return finishNewTextField((id) t, YES); } id newPasswordField(void) @@ -139,7 +142,7 @@ id newPasswordField(void) NSSecureTextField *t; t = [[NSSecureTextField alloc] initWithFrame:NSZeroRect]; - return finishNewTextField(toNSTextField(t), YES); + return finishNewTextField((id) t, YES); } void textfieldSetDelegate(id textfield, void *t) @@ -219,7 +222,7 @@ id newLabel(void) [l setEditable:NO]; [l setSelectable:NO]; [l setDrawsBackground:NO]; - return finishNewTextField(l, NO); + return finishNewTextField((id) l, NO); } id newGroup(id container) diff --git a/redo/objc_darwin.h b/redo/objc_darwin.h index 826334c..1d442cf 100644 --- a/redo/objc_darwin.h +++ b/redo/objc_darwin.h @@ -66,6 +66,7 @@ extern id newCheckbox(void); extern void checkboxSetDelegate(id, void *); extern BOOL checkboxChecked(id); extern void checkboxSetChecked(id, BOOL); +extern id finishNewTextField(id, BOOL); extern id newTextField(void); extern id newPasswordField(void); extern void textfieldSetDelegate(id, void *); @@ -127,6 +128,8 @@ extern uintptr_t pressedMouseButtons(void); extern uintptr_t keyCode(id); extern void areaRepaint(id, struct xrect); extern void areaRepaintAll(id); +extern id newAreaTextField(id, void *); +extern void areaTextFieldOpen(id, intptr_t, intptr_t); /* common_darwin.m */ extern void disableAutocorrect(id);