cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_cocoamessagebox.m (4310B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 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        [alert beginSheetModalForWindow:nswindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
     61        while (clicked < 0) {
     62            SDL_PumpEvents();
     63            SDL_Delay(100);
     64        }
     65        [nswindow release];
     66    } else {
     67        clicked = [alert runModal];
     68    }
     69}
     70
     71- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
     72{
     73    clicked = returnCode;
     74}
     75
     76@end
     77
     78
     79/* Display a Cocoa message box */
     80int
     81Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
     82{ @autoreleasepool
     83{
     84    Cocoa_RegisterApp();
     85
     86    NSAlert* alert = [[[NSAlert alloc] init] autorelease];
     87
     88    if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
     89        [alert setAlertStyle:NSCriticalAlertStyle];
     90    } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) {
     91        [alert setAlertStyle:NSWarningAlertStyle];
     92    } else {
     93        [alert setAlertStyle:NSInformationalAlertStyle];
     94    }
     95
     96    [alert setMessageText:[NSString stringWithUTF8String:messageboxdata->title]];
     97    [alert setInformativeText:[NSString stringWithUTF8String:messageboxdata->message]];
     98
     99    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
    100    int i;
    101    for (i = 0; i < messageboxdata->numbuttons; ++i) {
    102        NSButton *button = [alert addButtonWithTitle:[NSString stringWithUTF8String:buttons[i].text]];
    103        if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
    104            [button setKeyEquivalent:@"\r"];
    105        } else if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
    106            [button setKeyEquivalent:@"\033"];
    107        } else {
    108            [button setKeyEquivalent:@""];
    109        }
    110    }
    111
    112    SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease];
    113
    114    [presenter performSelectorOnMainThread:@selector(showAlert:)
    115                                withObject:alert
    116                             waitUntilDone:YES];
    117
    118    int returnValue = 0;
    119    NSInteger clicked = presenter->clicked;
    120    if (clicked >= NSAlertFirstButtonReturn) {
    121        clicked -= NSAlertFirstButtonReturn;
    122        *buttonid = buttons[clicked].buttonid;
    123    } else {
    124        returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
    125    }
    126
    127    return returnValue;
    128}}
    129
    130#endif /* SDL_VIDEO_DRIVER_COCOA */
    131
    132/* vi: set ts=4 sw=4 expandtab: */