SDL 2.0
SDL_uikitmessagebox.m
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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_UIKIT
24
25#include "SDL.h"
26#include "SDL_uikitvideo.h"
27#include "SDL_uikitwindow.h"
28
29/* Display a UIKit message box */
30
31static SDL_bool s_showingMessageBox = SDL_FALSE;
32
34UIKit_ShowingMessageBox(void)
35{
36 return s_showingMessageBox;
37}
38
39static void
40UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex)
41{
42 *clickedindex = messageboxdata->numbuttons;
43
44 @autoreleasepool {
45 /* Run the main event loop until the alert has finished */
46 /* Note that this needs to be done on the main thread */
47 s_showingMessageBox = SDL_TRUE;
48 while ((*clickedindex) == messageboxdata->numbuttons) {
49 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
50 }
51 s_showingMessageBox = SDL_FALSE;
52 }
53}
54
55static BOOL
56UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonid)
57{
58 int i;
59 int __block clickedindex = messageboxdata->numbuttons;
60 const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
61 UIWindow *window = nil;
62 UIWindow *alertwindow = nil;
63
64 if (![UIAlertController class]) {
65 return NO;
66 }
67
68 UIAlertController *alert;
69 alert = [UIAlertController alertControllerWithTitle:@(messageboxdata->title)
70 message:@(messageboxdata->message)
71 preferredStyle:UIAlertControllerStyleAlert];
72
73 for (i = 0; i < messageboxdata->numbuttons; i++) {
74 UIAlertAction *action;
75 UIAlertActionStyle style = UIAlertActionStyleDefault;
76
78 style = UIAlertActionStyleCancel;
79 }
80
81 action = [UIAlertAction actionWithTitle:@(buttons[i].text)
82 style:style
83 handler:^(UIAlertAction *action) {
84 clickedindex = i;
85 }];
86 [alert addAction:action];
87 }
88
89 if (messageboxdata->window) {
90 SDL_WindowData *data = (__bridge SDL_WindowData *) messageboxdata->window->driverdata;
91 window = data.uiwindow;
92 }
93
94 if (window == nil || window.rootViewController == nil) {
95 alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
96 alertwindow.rootViewController = [UIViewController new];
97 alertwindow.windowLevel = UIWindowLevelAlert;
98
99 window = alertwindow;
100
101 [alertwindow makeKeyAndVisible];
102 }
103
104 [window.rootViewController presentViewController:alert animated:YES completion:nil];
105 UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
106
107 if (alertwindow) {
108 alertwindow.hidden = YES;
109 }
110
112
113 *buttonid = messageboxdata->buttons[clickedindex].buttonid;
114 return YES;
115}
116
117/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
118#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
119@interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate>
120
121@property (nonatomic, assign) int *clickedIndex;
122
123@end
124
125@implementation SDLAlertViewDelegate
126
127- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
128{
129 if (_clickedIndex != NULL) {
130 *_clickedIndex = (int) buttonIndex;
131 }
132}
133
134@end
135#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
136
137static BOOL
138UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid)
139{
140 /* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
141#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
142 int i;
143 int clickedindex = messageboxdata->numbuttons;
144 const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
145 UIAlertView *alert = [[UIAlertView alloc] init];
146 SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];
147
148 alert.delegate = delegate;
149 alert.title = @(messageboxdata->title);
150 alert.message = @(messageboxdata->message);
151
152 for (i = 0; i < messageboxdata->numbuttons; i++) {
153 [alert addButtonWithTitle:@(buttons[i].text)];
154 }
155
156 delegate.clickedIndex = &clickedindex;
157
158 [alert show];
159
160 UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
161
162 alert.delegate = nil;
163
164 *buttonid = messageboxdata->buttons[clickedindex].buttonid;
165 return YES;
166#else
167 return NO;
168#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
169}
170
171int
172UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
173{
174 BOOL success = NO;
175
176 @autoreleasepool {
177 success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid);
178 if (!success) {
179 success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid);
180 }
181 }
182
183 if (!success) {
184 return SDL_SetError("Could not show message box.");
185 }
186
187 return 0;
188}
189
190#endif /* SDL_VIDEO_DRIVER_UIKIT */
191
192/* vi: set ts=4 sw=4 expandtab: */
#define SDL_SetError
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
@ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT
GLbitfield flags
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
void UIKit_ForceUpdateHomeIndicator(void)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:167
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
Individual button data.
MessageBox structure containing title, text, window, etc.
const SDL_MessageBoxButtonData * buttons
SDL_Window * window
const char * title
const char * message