Make Cocoa_ShowMessageBox work in background threads.
This commit is contained in:
parent
be8f97cb6a
commit
c7fb60a46b
2 changed files with 115 additions and 34 deletions
|
@ -32,6 +32,29 @@
|
|||
#include "SDL_messagebox.h"
|
||||
#include "SDL_cocoavideo.h"
|
||||
|
||||
@interface SDLMessageBoxPresenter : NSObject {
|
||||
@public
|
||||
NSInteger clicked;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation SDLMessageBoxPresenter
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
clicked = -1;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)showAlert:(NSAlert*)alert
|
||||
{
|
||||
clicked = [alert runModal];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
/* Display a Cocoa message box */
|
||||
int
|
||||
|
@ -41,7 +64,7 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSAlert* alert = [[NSAlert alloc] init];
|
||||
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
|
||||
|
||||
if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
|
||||
[alert setAlertStyle:NSCriticalAlertStyle];
|
||||
|
@ -67,14 +90,27 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
}
|
||||
}
|
||||
|
||||
NSInteger clicked = [alert runModal];
|
||||
clicked -= NSAlertFirstButtonReturn;
|
||||
*buttonid = buttons[clicked].buttonid;
|
||||
[alert release];
|
||||
SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] init] autorelease];
|
||||
|
||||
[presenter performSelectorOnMainThread:@selector(showAlert:)
|
||||
withObject:alert
|
||||
waitUntilDone:YES];
|
||||
|
||||
int returnValue = 0;
|
||||
NSInteger clicked = presenter->clicked;
|
||||
if (clicked >= NSAlertFirstButtonReturn)
|
||||
{
|
||||
clicked -= NSAlertFirstButtonReturn;
|
||||
*buttonid = buttons[clicked].buttonid;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = SDL_SetError("Did not get a valid `clicked button' id: %d", clicked);
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return 0;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
|
|
@ -29,13 +29,67 @@ quit(int rc)
|
|||
exit(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
button_messagebox(void *eventNumber)
|
||||
{
|
||||
const SDL_MessageBoxButtonData buttons[] = {
|
||||
{
|
||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
|
||||
0,
|
||||
"OK"
|
||||
},{
|
||||
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
||||
1,
|
||||
"Cancel"
|
||||
},
|
||||
};
|
||||
|
||||
SDL_MessageBoxData data = {
|
||||
SDL_MESSAGEBOX_INFORMATION,
|
||||
NULL, // no parent window
|
||||
"Custom MessageBox",
|
||||
"This is a custom messagebox",
|
||||
2,
|
||||
buttons,
|
||||
NULL // Default color scheme
|
||||
};
|
||||
|
||||
int button = -1;
|
||||
int success = 0;
|
||||
if (eventNumber) {
|
||||
data.message = "This is a custom messagebox from a background thread.";
|
||||
}
|
||||
|
||||
success =SDL_ShowMessageBox(&data, &button);
|
||||
if (success == -1) {
|
||||
printf("Error Presenting MessageBox: %s\n", SDL_GetError());
|
||||
if (eventNumber) {
|
||||
SDL_UserEvent event;
|
||||
event.type = (intptr_t)eventNumber;
|
||||
SDL_PushEvent((SDL_Event*)&event);
|
||||
return 1;
|
||||
} else {
|
||||
quit(2);
|
||||
}
|
||||
}
|
||||
printf("Pressed button: %d, %s\n", button, button == 1 ? "Cancel" : "OK");
|
||||
|
||||
if (eventNumber) {
|
||||
SDL_UserEvent event;
|
||||
event.type = (intptr_t)eventNumber;
|
||||
SDL_PushEvent((SDL_Event*)&event);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int success;
|
||||
|
||||
/* Load the SDL library */
|
||||
if (SDL_Init(0) < 0) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
return (1);
|
||||
}
|
||||
|
@ -78,36 +132,27 @@ main(int argc, char *argv[])
|
|||
quit(1);
|
||||
}
|
||||
|
||||
button_messagebox(NULL);
|
||||
|
||||
/* Technically this isn't a supported operation for the API, but it doesn't
|
||||
* hurt for it to work.
|
||||
*/
|
||||
{
|
||||
const SDL_MessageBoxButtonData buttons[] = {
|
||||
{
|
||||
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
|
||||
0,
|
||||
"OK"
|
||||
},{
|
||||
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
|
||||
1,
|
||||
"Cancel"
|
||||
},
|
||||
};
|
||||
int status = 0;
|
||||
SDL_Event event;
|
||||
intptr_t eventNumber = SDL_RegisterEvents(1);
|
||||
SDL_Thread* thread = SDL_CreateThread(&button_messagebox, "MessageBox", (void*)eventNumber);
|
||||
|
||||
SDL_MessageBoxData data = {
|
||||
SDL_MESSAGEBOX_INFORMATION,
|
||||
NULL, // no parent window
|
||||
"Custom MessageBox",
|
||||
"This is a custom messagebox",
|
||||
2,
|
||||
buttons,
|
||||
NULL // Default color scheme
|
||||
};
|
||||
|
||||
int button = -1;
|
||||
success = SDL_ShowMessageBox(&data, &button);
|
||||
if (success == -1) {
|
||||
printf("Error Presenting MessageBox: %s\n", SDL_GetError());
|
||||
quit(2);
|
||||
while (SDL_WaitEvent(&event))
|
||||
{
|
||||
if (event.type == eventNumber) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("Pressed button: %d, %s\n", button, button == 1 ? "Cancel" : "OK");
|
||||
|
||||
SDL_WaitThread(thread, &status);
|
||||
|
||||
printf("Message box thread return %i\n", status);
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue