Atlas - SDL_uikitmessagebox.m

Home / ext / SDL2 / src / video / uikit Lines: 1 | Size: 6717 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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 33SDL_bool 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#ifdef __IPHONE_8_0 59 int i; 60 int __block clickedindex = messageboxdata->numbuttons; 61 const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons; 62 UIWindow *window = nil; 63 UIWindow *alertwindow = nil; 64 65 if (![UIAlertController class]) { 66 return NO; 67 } 68 69 UIAlertController *alert; 70 alert = [UIAlertController alertControllerWithTitle:@(messageboxdata->title) 71 message:@(messageboxdata->message) 72 preferredStyle:UIAlertControllerStyleAlert]; 73 74 for (i = 0; i < messageboxdata->numbuttons; i++) { 75 UIAlertAction *action; 76 UIAlertActionStyle style = UIAlertActionStyleDefault; 77 78 if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { 79 style = UIAlertActionStyleCancel; 80 } 81 82 action = [UIAlertAction actionWithTitle:@(buttons[i].text) 83 style:style 84 handler:^(UIAlertAction *action) { 85 clickedindex = i; 86 }]; 87 [alert addAction:action]; 88 } 89 90 if (messageboxdata->window) { 91 SDL_WindowData *data = (__bridge SDL_WindowData *) messageboxdata->window->driverdata; 92 window = data.uiwindow; 93 } 94 95 if (window == nil || window.rootViewController == nil) { 96 alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 97 alertwindow.rootViewController = [UIViewController new]; 98 alertwindow.windowLevel = UIWindowLevelAlert; 99 100 window = alertwindow; 101 102 [alertwindow makeKeyAndVisible]; 103 } 104 105 [window.rootViewController presentViewController:alert animated:YES completion:nil]; 106 UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex); 107 108 if (alertwindow) { 109 alertwindow.hidden = YES; 110 } 111 112#if !TARGET_OS_TV 113 /* Force the main SDL window to re-evaluate home indicator state */ 114 SDL_Window *focus = SDL_GetFocusWindow(); 115 if (focus) { 116 SDL_WindowData *data = (__bridge SDL_WindowData *) focus->driverdata; 117 if (data != nil) { 118 if (@available(iOS 11.0, *)) { 119 [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfHomeIndicatorAutoHidden) withObject:nil waitUntilDone:NO]; 120 [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfScreenEdgesDeferringSystemGestures) withObject:nil waitUntilDone:NO]; 121 } 122 } 123 } 124#endif /* !TARGET_OS_TV */ 125 126 *buttonid = messageboxdata->buttons[clickedindex].buttonid; 127 return YES; 128#else 129 return NO; 130#endif /* __IPHONE_8_0 */ 131} 132 133/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */ 134#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 135@interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate> 136 137@property (nonatomic, assign) int *clickedIndex; 138 139@end 140 141@implementation SDLAlertViewDelegate 142 143- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex 144{ 145 if (_clickedIndex != NULL) { 146 *_clickedIndex = (int) buttonIndex; 147 } 148} 149 150@end 151#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */ 152 153static BOOL 154UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid) 155{ 156 /* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */ 157#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 158 int i; 159 int clickedindex = messageboxdata->numbuttons; 160 const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons; 161 UIAlertView *alert = [[UIAlertView alloc] init]; 162 SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init]; 163 164 alert.delegate = delegate; 165 alert.title = @(messageboxdata->title); 166 alert.message = @(messageboxdata->message); 167 168 for (i = 0; i < messageboxdata->numbuttons; i++) { 169 [alert addButtonWithTitle:@(buttons[i].text)]; 170 } 171 172 delegate.clickedIndex = &clickedindex; 173 174 [alert show]; 175 176 UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex); 177 178 alert.delegate = nil; 179 180 *buttonid = messageboxdata->buttons[clickedindex].buttonid; 181 return YES; 182#else 183 return NO; 184#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */ 185} 186 187int 188UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) 189{ 190 BOOL success = NO; 191 192 @autoreleasepool { 193 success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid); 194 if (!success) { 195 success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid); 196 } 197 } 198 199 if (!success) { 200 return SDL_SetError("Could not show message box."); 201 } 202 203 return 0; 204} 205 206#endif /* SDL_VIDEO_DRIVER_UIKIT */ 207 208/* vi: set ts=4 sw=4 expandtab: */ 209
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.