Skip to content

Commit

Permalink
iOS: show message boxes using the new UIAlertController APIs when sup…
Browse files Browse the repository at this point in the history
…ported, rather than the deprecated UIAlertView.

UIAlertController is also supported on tvOS, whereas UIAlertView is not.
  • Loading branch information
slime73 committed Sep 25, 2015
1 parent 774b077 commit ab2a350
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 48 deletions.
14 changes: 9 additions & 5 deletions src/joystick/iphoneos/SDL_sysjoystick.m
Expand Up @@ -181,7 +181,7 @@
#endif /* !SDL_EVENTS_DISABLED */
}

SDL_JoystickDeviceItem *
static SDL_JoystickDeviceItem *
SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
{
SDL_JoystickDeviceItem *prev = NULL;
Expand Down Expand Up @@ -374,12 +374,14 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
}

/* Function to determine if this joystick is attached to the system right now */
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
SDL_bool
SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{
return joystick->hwdata != NULL;
}

static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
static void
SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
{
const float maxgforce = SDL_IPHONE_MAX_GFORCE;
const SInt16 maxsint16 = 0x7FFF;
Expand Down Expand Up @@ -579,7 +581,8 @@ static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
numjoysticks = 0;
}

SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
SDL_JoystickGUID
SDL_SYS_JoystickGetDeviceGUID( int device_index )
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
SDL_JoystickGUID guid;
Expand All @@ -591,7 +594,8 @@ SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
return guid;
}

SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
SDL_JoystickGUID
SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
{
SDL_JoystickGUID guid;
if (joystick->hwdata) {
Expand Down
164 changes: 131 additions & 33 deletions src/video/uikit/SDL_uikitmessagebox.m
Expand Up @@ -24,68 +24,166 @@

#include "SDL.h"
#include "SDL_uikitvideo.h"

#include "SDL_uikitwindow.h"

/* Display a UIKit message box */

static SDL_bool s_showingMessageBox = SDL_FALSE;

SDL_bool
UIKit_ShowingMessageBox()
{
return s_showingMessageBox;
}

static void
UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex)
{
*clickedindex = messageboxdata->numbuttons;

@autoreleasepool {
/* Run the main event loop until the alert has finished */
/* Note that this needs to be done on the main thread */
s_showingMessageBox = SDL_TRUE;
while ((*clickedindex) == messageboxdata->numbuttons) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
s_showingMessageBox = SDL_FALSE;
}
}

static BOOL
UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
#ifdef __IPHONE_8_0
int i;
int __block clickedindex = messageboxdata->numbuttons;
const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
UIWindow *window = nil;
UIWindow *alertwindow = nil;

if (![UIAlertController class]) {
return NO;
}

UIAlertController *alert;
alert = [UIAlertController alertControllerWithTitle:@(messageboxdata->title)
message:@(messageboxdata->message)
preferredStyle:UIAlertControllerStyleAlert];

for (i = 0; i < messageboxdata->numbuttons; i++) {
UIAlertAction *action;
UIAlertActionStyle style = UIAlertActionStyleDefault;

if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
style = UIAlertActionStyleCancel;
}

action = [UIAlertAction actionWithTitle:@(buttons[i].text)
style:style
handler:^(UIAlertAction *action) {
clickedindex = i;
}];
[alert addAction:action];
}

if (messageboxdata->window) {
SDL_WindowData *data = (__bridge SDL_WindowData *) messageboxdata->window->driverdata;
window = data.uiwindow;
}

if (window == nil || window.rootViewController == nil) {
alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertwindow.rootViewController = [UIViewController new];
alertwindow.windowLevel = UIWindowLevelAlert;

window = alertwindow;

[alertwindow makeKeyAndVisible];
}

[window.rootViewController presentViewController:alert animated:YES completion:nil];
UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);

if (alertwindow) {
alertwindow.hidden = YES;
}

*buttonid = messageboxdata->buttons[clickedindex].buttonid;
return YES;
#else
return NO;
#endif /* __IPHONE_8_0 */
}

/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
@interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate>

@property (nonatomic, assign) int clickedIndex;
@property (nonatomic, assign) int *clickedIndex;

@end

@implementation SDLAlertViewDelegate

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
_clickedIndex = (int)buttonIndex;
if (_clickedIndex != NULL) {
*_clickedIndex = (int) buttonIndex;
}
}

@end
#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */


SDL_bool
UIKit_ShowingMessageBox()
{
return s_showingMessageBox;
}

int
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
static BOOL
UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
int i;
int clickedindex = messageboxdata->numbuttons;
const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
UIAlertView *alert = [[UIAlertView alloc] init];
SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];

@autoreleasepool {
UIAlertView *alert = [[UIAlertView alloc] init];
SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];
alert.delegate = delegate;
alert.title = @(messageboxdata->title);
alert.message = @(messageboxdata->message);

alert.delegate = delegate;
alert.title = @(messageboxdata->title);
alert.message = @(messageboxdata->message);
for (i = 0; i < messageboxdata->numbuttons; i++) {
[alert addButtonWithTitle:@(buttons[i].text)];
}

for (i = 0; i < messageboxdata->numbuttons; ++i) {
[alert addButtonWithTitle:@(buttons[i].text)];
}
delegate.clickedIndex = &clickedindex;

/* Set up for showing the alert */
delegate.clickedIndex = messageboxdata->numbuttons;
[alert show];

[alert show];
UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);

/* Run the main event loop until the alert has finished */
/* Note that this needs to be done on the main thread */
s_showingMessageBox = SDL_TRUE;
while (delegate.clickedIndex == messageboxdata->numbuttons) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
s_showingMessageBox = SDL_FALSE;
alert.delegate = nil;

*buttonid = messageboxdata->buttons[delegate.clickedIndex].buttonid;
*buttonid = messageboxdata->buttons[clickedindex].buttonid;
return YES;
#else
return NO;
#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
}

int
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
BOOL success = NO;

@autoreleasepool {
success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid);
if (!success) {
success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid);
}
}

alert.delegate = nil;
if (!success) {
return SDL_SetError("Could not show message box.");
}

return 0;
Expand Down
2 changes: 0 additions & 2 deletions src/video/uikit/SDL_uikitopengles.m
Expand Up @@ -52,8 +52,6 @@ - (void)dealloc

@end

static int UIKit_GL_Initialize(_THIS);

void *
UIKit_GL_GetProcAddress(_THIS, const char *proc)
{
Expand Down
2 changes: 0 additions & 2 deletions src/video/uikit/SDL_uikitviewcontroller.h
Expand Up @@ -47,9 +47,7 @@
- (void)loadView;
- (void)viewDidLayoutSubviews;
- (NSUInteger)supportedInterfaceOrientations;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
- (BOOL)prefersStatusBarHidden;
- (UIStatusBarStyle)preferredStatusBarStyle;

#if SDL_IPHONE_KEYBOARD
- (void)showKeyboard;
Expand Down
6 changes: 0 additions & 6 deletions src/video/uikit/SDL_uikitviewcontroller.m
Expand Up @@ -135,12 +135,6 @@ - (BOOL)prefersStatusBarHidden
return (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0;
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
/* We assume most SDL apps don't have a bright white background. */
return UIStatusBarStyleLightContent;
}

/*
---- Keyboard related functionality below this line ----
*/
Expand Down

0 comments on commit ab2a350

Please sign in to comment.