summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/cocoa/SDL_cocoamessagebox.m
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/cocoa/SDL_cocoamessagebox.m')
-rw-r--r--contrib/SDL-3.2.8/src/video/cocoa/SDL_cocoamessagebox.m145
1 files changed, 145 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/cocoa/SDL_cocoamessagebox.m b/contrib/SDL-3.2.8/src/video/cocoa/SDL_cocoamessagebox.m
new file mode 100644
index 0000000..d54adb1
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/cocoa/SDL_cocoamessagebox.m
@@ -0,0 +1,145 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 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#ifdef SDL_VIDEO_DRIVER_COCOA
24
25#include "SDL_cocoavideo.h"
26
27@interface SDL3MessageBoxPresenter : NSObject
28{
29 @public
30 NSInteger clicked;
31 NSWindow *nswindow;
32}
33- (id)initWithParentWindow:(SDL_Window *)window;
34@end
35
36@implementation SDL3MessageBoxPresenter
37- (id)initWithParentWindow:(SDL_Window *)window
38{
39 self = [super init];
40 if (self) {
41 clicked = -1;
42
43 // Retain the NSWindow because we'll show the alert later on the main thread
44 if (window) {
45 nswindow = ((__bridge SDL_CocoaWindowData *)window->internal).nswindow;
46 } else {
47 nswindow = nil;
48 }
49 }
50
51 return self;
52}
53
54- (void)showAlert:(NSAlert *)alert
55{
56 if (nswindow) {
57 [alert beginSheetModalForWindow:nswindow
58 completionHandler:^(NSModalResponse returnCode) {
59 [NSApp stopModalWithCode:returnCode];
60 }];
61 clicked = [NSApp runModalForWindow:nswindow];
62 nswindow = nil;
63 } else {
64 clicked = [alert runModal];
65 }
66}
67@end
68
69static void Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonID, bool *result)
70{
71 NSAlert *alert;
72 const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
73 SDL3MessageBoxPresenter *presenter;
74 NSInteger clicked;
75 int i;
76 Cocoa_RegisterApp();
77
78 alert = [[NSAlert alloc] init];
79
80 if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
81 [alert setAlertStyle:NSAlertStyleCritical];
82 } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) {
83 [alert setAlertStyle:NSAlertStyleWarning];
84 } else {
85 [alert setAlertStyle:NSAlertStyleInformational];
86 }
87
88 [alert setMessageText:[NSString stringWithUTF8String:messageboxdata->title]];
89 [alert setInformativeText:[NSString stringWithUTF8String:messageboxdata->message]];
90
91 for (i = 0; i < messageboxdata->numbuttons; ++i) {
92 const SDL_MessageBoxButtonData *sdlButton;
93 NSButton *button;
94
95 if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
96 sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i];
97 } else {
98 sdlButton = &messageboxdata->buttons[i];
99 }
100
101 button = [alert addButtonWithTitle:[NSString stringWithUTF8String:sdlButton->text]];
102 if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
103 [button setKeyEquivalent:@"\r"];
104 } else if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
105 [button setKeyEquivalent:@"\033"];
106 } else {
107 [button setKeyEquivalent:@""];
108 }
109 }
110
111 presenter = [[SDL3MessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window];
112
113 [presenter showAlert:alert];
114
115 clicked = presenter->clicked;
116 if (clicked >= NSAlertFirstButtonReturn) {
117 clicked -= NSAlertFirstButtonReturn;
118 if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
119 clicked = messageboxdata->numbuttons - 1 - clicked;
120 }
121 *buttonID = buttons[clicked].buttonID;
122 *result = true;
123 } else {
124 *result = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
125 }
126}
127
128// Display a Cocoa message box
129bool Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
130{
131 @autoreleasepool {
132 __block bool result = 0;
133
134 if ([NSThread isMainThread]) {
135 Cocoa_ShowMessageBoxImpl(messageboxdata, buttonID, &result);
136 } else {
137 dispatch_sync(dispatch_get_main_queue(), ^{
138 Cocoa_ShowMessageBoxImpl(messageboxdata, buttonID, &result);
139 });
140 }
141 return result;
142 }
143}
144
145#endif // SDL_VIDEO_DRIVER_COCOA