Implemented the dialog stuff on OS X.

This commit is contained in:
Pietro Gagliardi 2015-11-28 12:09:14 -05:00
parent 3943c2c65e
commit bf6fabef21
1 changed files with 62 additions and 12 deletions

View File

@ -1,6 +1,12 @@
// 26 june 2015
#import "uipriv_darwin.h"
// TODO while a dialog is running no other window receives events
#define windowWindow(w) ((NSWindow *) uiControlHandle(uiControl(w)))
// source of code modal logic: http://stackoverflow.com/questions/604768/wait-for-nsalert-beginsheetmodalforwindow
// note: whether extensions are actually shown depends on a user setting in Finder; we can't control it here
static void setupSavePanel(NSSavePanel *s)
{
@ -11,17 +17,20 @@ static void setupSavePanel(NSSavePanel *s)
[s setTreatsFilePackagesAsDirectories:YES];
}
static char *runSavePanel(NSSavePanel *s)
static char *runSavePanel(NSWindow *parent, NSSavePanel *s)
{
char *filename;
if ([s runModal] != NSFileHandlingPanelOKButton)
[s beginSheetModalForWindow:parent completionHandler:^(NSInteger result) {
[realNSApp() stopModalWithCode:result];
}];
if ([realNSApp() runModalForWindow:s] != NSFileHandlingPanelOKButton)
return NULL;
filename = uiDarwinNSStringToText([[s URL] path]);
return filename;
}
char *uiOpenFile(void)
char *uiOpenFile(uiWindow *parent)
{
NSOpenPanel *o;
@ -32,22 +41,61 @@ char *uiOpenFile(void)
[o setAllowsMultipleSelection:NO];
setupSavePanel(o);
// panel is autoreleased
return runSavePanel(o);
return runSavePanel(windowWindow(parent), o);
}
char *uiSaveFile(void)
char *uiSaveFile(uiWindow *parent)
{
NSSavePanel *s;
s = [NSSavePanel savePanel];
setupSavePanel(s);
// panel is autoreleased
return runSavePanel(s);
return runSavePanel(windowWindow(parent), s);
}
static void msgbox(const char *title, const char *description, NSAlertStyle style)
// I would use a completion handler for NSAlert as well, but alas NSAlert's are 10.9 and higher only
@interface libuiCodeModalAlertPanel : NSObject {
NSAlert *panel;
NSWindow *parent;
}
- (id)initWithPanel:(NSAlert *)p parent:(NSWindow *)w;
- (NSInteger)run;
- (void)panelEnded:(NSAlert *)panel result:(NSInteger)result data:(void *)data;
@end
@implementation libuiCodeModalAlertPanel
- (id)initWithPanel:(NSAlert *)p parent:(NSWindow *)w
{
self = [super init];
if (self) {
self->panel = p;
self->parent = w;
}
return self;
}
- (NSInteger)run
{
[self->panel beginSheetModalForWindow:self->parent
modalDelegate:self
didEndSelector:@selector(panelEnded:result:data:)
contextInfo:NULL];
return [realNSApp() runModalForWindow:[self->panel window]];
}
- (void)panelEnded:(NSAlert *)panel result:(NSInteger)result data:(void *)data
{
[realNSApp() stopModalWithCode:result];
}
@end
static void msgbox(NSWindow *parent, const char *title, const char *description, NSAlertStyle style)
{
NSAlert *a;
libuiCodeModalAlertPanel *cm;
a = [NSAlert new];
[a setAlertStyle:style];
@ -56,16 +104,18 @@ static void msgbox(const char *title, const char *description, NSAlertStyle styl
[a setMessageText:toNSString(title)];
[a setInformativeText:toNSString(description)];
[a addButtonWithTitle:@"OK"];
[a runModal];
cm = [[libuiCodeModalAlertPanel alloc] initWithPanel:a parent:parent];
[cm run];
[cm release];
[a release];
}
void uiMsgBox(const char *title, const char *description)
void uiMsgBox(uiWindow *parent, const char *title, const char *description)
{
msgbox(title, description, NSInformationalAlertStyle);
msgbox(windowWindow(parent), title, description, NSInformationalAlertStyle);
}
void uiMsgBoxError(const char *title, const char *description)
void uiMsgBoxError(uiWindow *parent, const char *title, const char *description)
{
msgbox(title, description, NSCriticalAlertStyle);
msgbox(windowWindow(parent), title, description, NSCriticalAlertStyle);
}