sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_cocoamessagebox.m (5150B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
      4 
      5   This software is provided 'as-is', without any express or implied
      6   warranty.  In no event will the authors be held liable for any damages
      7   arising from the use of this software.
      8 
      9   Permission is granted to anyone to use this software for any purpose,
     10   including commercial applications, and to alter it and redistribute it
     11   freely, subject to the following restrictions:
     12 
     13   1. The origin of this software must not be misrepresented; you must not
     14      claim that you wrote the original software. If you use this software
     15      in a product, an acknowledgment in the product documentation would be
     16      appreciated but is not required.
     17   2. Altered source versions must be plainly marked as such, and must not be
     18      misrepresented as being the original software.
     19   3. This notice may not be removed or altered from any source distribution.
     20 */
     21 #include "../../SDL_internal.h"
     22 
     23 #if SDL_VIDEO_DRIVER_COCOA
     24 
     25 #include "SDL_events.h"
     26 #include "SDL_timer.h"
     27 #include "SDL_messagebox.h"
     28 #include "SDL_cocoavideo.h"
     29 
     30 @interface SDLMessageBoxPresenter : NSObject {
     31 @public
     32     NSInteger clicked;
     33     NSWindow *nswindow;
     34 }
     35 - (id) initWithParentWindow:(SDL_Window *)window;
     36 - (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
     37 @end
     38 
     39 @implementation SDLMessageBoxPresenter
     40 - (id) initWithParentWindow:(SDL_Window *)window
     41 {
     42     self = [super init];
     43     if (self) {
     44         clicked = -1;
     45 
     46         /* Retain the NSWindow because we'll show the alert later on the main thread */
     47         if (window) {
     48             nswindow = [((SDL_WindowData *) window->driverdata)->nswindow retain];
     49         } else {
     50             nswindow = NULL;
     51         }
     52     }
     53 
     54     return self;
     55 }
     56 
     57 - (void)showAlert:(NSAlert*)alert
     58 {
     59     if (nswindow) {
     60 #ifdef MAC_OS_X_VERSION_10_9
     61         if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
     62             [alert beginSheetModalForWindow:nswindow completionHandler:^(NSModalResponse returnCode) {
     63                 clicked = returnCode;
     64             }];
     65         } else
     66 #endif
     67         {
     68 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
     69             [alert beginSheetModalForWindow:nswindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
     70 #endif
     71         }
     72 
     73         while (clicked < 0) {
     74             SDL_PumpEvents();
     75             SDL_Delay(100);
     76         }
     77 
     78         [nswindow release];
     79     } else {
     80         clicked = [alert runModal];
     81     }
     82 }
     83 
     84 - (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
     85 {
     86     clicked = returnCode;
     87 }
     88 
     89 @end
     90 
     91 
     92 /* Display a Cocoa message box */
     93 int
     94 Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
     95 { @autoreleasepool
     96 {
     97     Cocoa_RegisterApp();
     98 
     99     NSAlert* alert = [[[NSAlert alloc] init] autorelease];
    100 
    101     if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
    102         [alert setAlertStyle:NSAlertStyleCritical];
    103     } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) {
    104         [alert setAlertStyle:NSAlertStyleWarning];
    105     } else {
    106         [alert setAlertStyle:NSAlertStyleInformational];
    107     }
    108 
    109     [alert setMessageText:[NSString stringWithUTF8String:messageboxdata->title]];
    110     [alert setInformativeText:[NSString stringWithUTF8String:messageboxdata->message]];
    111 
    112     const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
    113     int i;
    114     for (i = 0; i < messageboxdata->numbuttons; ++i) {
    115         const SDL_MessageBoxButtonData *sdlButton;
    116         NSButton *button;
    117 
    118         if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
    119             sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i];
    120         } else {
    121             sdlButton = &messageboxdata->buttons[i];
    122         }
    123 
    124         button = [alert addButtonWithTitle:[NSString stringWithUTF8String:sdlButton->text]];
    125         if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
    126             [button setKeyEquivalent:@"\r"];
    127         } else if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
    128             [button setKeyEquivalent:@"\033"];
    129         } else {
    130             [button setKeyEquivalent:@""];
    131         }
    132     }
    133 
    134     SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease];
    135 
    136     [presenter performSelectorOnMainThread:@selector(showAlert:)
    137                                 withObject:alert
    138                              waitUntilDone:YES];
    139 
    140     int returnValue = 0;
    141     NSInteger clicked = presenter->clicked;
    142     if (clicked >= NSAlertFirstButtonReturn) {
    143         clicked -= NSAlertFirstButtonReturn;
    144         if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
    145             clicked = messageboxdata->numbuttons - 1 - clicked;
    146         }
    147         *buttonid = buttons[clicked].buttonid;
    148     } else {
    149         returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
    150     }
    151 
    152     return returnValue;
    153 }}
    154 
    155 #endif /* SDL_VIDEO_DRIVER_COCOA */
    156 
    157 /* vi: set ts=4 sw=4 expandtab: */