From b172ab2e37896d36292660f6cc15987fb88ddf57 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 8 Jun 2014 12:36:55 -0400 Subject: [PATCH] Added new MsgBox() behavior on Mac OS X. Now we can finally remove MsgBox() from the TODOs! :D --- delegateuitask_darwin.m | 3 ++- dialog_darwin.go | 42 ++++++++++++++++++++++++++++------------- dialog_darwin.m | 15 ++++++++------- objc_darwin.h | 4 ++-- todo.md | 1 - 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/delegateuitask_darwin.m b/delegateuitask_darwin.m index d2e6f4f..6cf886d 100644 --- a/delegateuitask_darwin.m +++ b/delegateuitask_darwin.m @@ -108,8 +108,9 @@ extern NSRect dummyRect; return NSTerminateCancel; } -- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)chan { + dialog_send(chan, (uintptr_t) returnCode); } @end diff --git a/dialog_darwin.go b/dialog_darwin.go index ef1cd6c..3047ed0 100644 --- a/dialog_darwin.go +++ b/dialog_darwin.go @@ -3,19 +3,26 @@ package ui import ( - // ... + "unsafe" ) // #include "objc_darwin.h" import "C" -func _msgBox(parent *Window, primarytext string, secondarytext string, style uintptr) { - ret := make(chan struct{}) - defer close(ret) +//export dialog_send +func dialog_send(pchan unsafe.Pointer, res C.intptr_t) { + rchan := (*chan int)(pchan) + go func() { // send it in a new goroutine like we do with everything else + *rchan <- int(res) + }() +} + +func _msgBox(parent *Window, primarytext string, secondarytext string, style uintptr) chan int { + ret := make(chan int) uitask <- func() { var pwin C.id = nil - if parent != nil { + if parent != dialogWindow { pwin = parent.sysData.id } primary := toNSString(primarytext) @@ -25,19 +32,28 @@ func _msgBox(parent *Window, primarytext string, secondarytext string, style uin } switch style { case 0: // normal - C.msgBox(pwin, primary, secondary) + C.msgBox(pwin, primary, secondary, unsafe.Pointer(&ret)) case 1: // error - C.msgBoxError(pwin, primary, secondary) + C.msgBoxError(pwin, primary, secondary, unsafe.Pointer(&ret)) } - ret <- struct{}{} } - <-ret + return ret } -func msgBox(parent *Window, primarytext string, secondarytext string) { - _msgBox(parent, primarytext, secondarytext, 0) +func (w *Window) msgBox(primarytext string, secondarytext string) (done chan struct{}) { + done = make(chan struct{}) + go func() { + <-_msgBox(w, primarytext, secondarytext, 0) + done <- struct{}{} + }() + return done } -func msgBoxError(parent *Window, primarytext string, secondarytext string) { - _msgBox(parent, primarytext, secondarytext, 1) +func (w *Window) msgBoxError(primarytext string, secondarytext string) (done chan struct{}) { + done = make(chan struct{}) + go func() { + <-_msgBox(w, primarytext, secondarytext, 1) + done <- struct{}{} + }() + return done } diff --git a/dialog_darwin.m b/dialog_darwin.m index 6bbad61..d37956f 100644 --- a/dialog_darwin.m +++ b/dialog_darwin.m @@ -1,6 +1,7 @@ // 15 may 2014 #include "objc_darwin.h" +#include "_cgo_export.h" #import // see delegateuitask_darwin.m @@ -23,7 +24,7 @@ #define to(T, x) ((T *) (x)) #define toNSWindow(x) to(NSWindow, (x)) -static void alert(id parent, NSString *primary, NSString *secondary, NSAlertStyle style) +static void alert(id parent, NSString *primary, NSString *secondary, NSAlertStyle style, void *chan) { NSAlert *box; @@ -35,20 +36,20 @@ static void alert(id parent, NSString *primary, NSString *secondary, NSAlertStyl // TODO is there a named constant? will also need to be changed when we add different dialog types [box addButtonWithTitle:@"OK"]; if (parent == nil) - [box runModal]; + dialog_send(chan, (intptr_t) [box runModal]); else [box beginSheetModalForWindow:toNSWindow(parent) modalDelegate:[NSApp delegate] didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:NULL]; + contextInfo:chan]; } -void msgBox(id parent, id primary, id secondary) +void msgBox(id parent, id primary, id secondary, void *chan) { - alert(parent, (NSString *) primary, (NSString *) secondary, NSInformationalAlertStyle); + alert(parent, (NSString *) primary, (NSString *) secondary, NSInformationalAlertStyle, chan); } -void msgBoxError(id parent, id primary, id secondary) +void msgBoxError(id parent, id primary, id secondary, void *chan) { - alert(parent, (NSString *) primary, (NSString *) secondary, NSCriticalAlertStyle); + alert(parent, (NSString *) primary, (NSString *) secondary, NSCriticalAlertStyle, chan); } diff --git a/objc_darwin.h b/objc_darwin.h index 1a29c39..b18f0d7 100644 --- a/objc_darwin.h +++ b/objc_darwin.h @@ -63,8 +63,8 @@ extern void breakMainLoop(void); extern void cocoaMainLoop(void); /* dialog_darwin.m */ -extern void msgBox(id, id, id); -extern void msgBoxError(id, id, id); +extern void msgBox(id, id, id, void *); +extern void msgBoxError(id, id, id, void *); /* listbox_darwin.m */ extern id toListboxItem(id, id); diff --git a/todo.md b/todo.md index a83274e..e6e60bc 100644 --- a/todo.md +++ b/todo.md @@ -24,4 +24,3 @@ ALL PLATFORMS: - will require moving dialog behavior to the package overview - make sure MouseEvent's documentation has dragging described correctly (both Windows and GTK+ do) - make all widths and heights parameters in constructors in the same place (or drop the ones in Window entirely?) -- Message boxes that belong to agiven parent are still application-modal on all platforms except Mac OS X because the whole system waits... we'll need to use a channel for this, I guess :S