Commit ab0fcbfb authored by Ryan C. Gordon's avatar Ryan C. Gordon

Added orientation rotation for iOS.

parent 15b112e3
...@@ -117,13 +117,15 @@ SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window) ...@@ -117,13 +117,15 @@ SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window)
majorVersion: _this->gl_config.major_version]; majorVersion: _this->gl_config.major_version];
data->view = view; data->view = view;
view->viewcontroller = data->viewcontroller;
if (view->viewcontroller != nil) {
[view->viewcontroller setView:view];
[view->viewcontroller retain];
}
/* add the view to our window */ /* add the view to our window */
[uiwindow addSubview: view ]; [uiwindow addSubview: view ];
/* Don't worry, the window retained the view */
[view release];
if ( UIKit_GL_MakeCurrent(_this, window, view) < 0 ) { if ( UIKit_GL_MakeCurrent(_this, window, view) < 0 ) {
UIKit_GL_DeleteContext(_this, view); UIKit_GL_DeleteContext(_this, view);
return NULL; return NULL;
...@@ -140,8 +142,12 @@ void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context) ...@@ -140,8 +142,12 @@ void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
{ {
/* the delegate has retained the view, this will release him */ /* the delegate has retained the view, this will release him */
SDL_uikitopenglview *view = (SDL_uikitopenglview *)context; SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
/* this will also delete it */ if (view->viewcontroller) {
[view->viewcontroller setView:nil];
[view->viewcontroller release];
}
[view removeFromSuperview]; [view removeFromSuperview];
[view release];
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -121,9 +121,12 @@ ...@@ -121,9 +121,12 @@
} }
/* end create buffers */ /* end create buffers */
// !!! FIXME: use the screen this is on!
/* Use the main screen scale (for retina display support) */ /* Use the main screen scale (for retina display support) */
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
self.contentScaleFactor = [UIScreen mainScreen].scale; self.contentScaleFactor = [UIScreen mainScreen].scale;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
} }
return self; return self;
} }
......
...@@ -30,6 +30,16 @@ ...@@ -30,6 +30,16 @@
#define MAX_SIMULTANEOUS_TOUCHES 5 #define MAX_SIMULTANEOUS_TOUCHES 5
#endif #endif
@interface SDL_uikitviewcontroller : UIViewController {
@private
SDL_Window *window;
}
- (id)initWithSDLWindow:(SDL_Window *)_window;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
- (void)loadView;
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
@end
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#if SDL_IPHONE_KEYBOARD #if SDL_IPHONE_KEYBOARD
@interface SDL_uikitview : UIView<UITextFieldDelegate> { @interface SDL_uikitview : UIView<UITextFieldDelegate> {
...@@ -48,7 +58,9 @@ ...@@ -48,7 +58,9 @@
UITextField *textField; UITextField *textField;
BOOL keyboardVisible; BOOL keyboardVisible;
#endif #endif
@public
SDL_uikitviewcontroller *viewcontroller;
} }
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
......
...@@ -40,6 +40,7 @@ struct SDL_WindowData ...@@ -40,6 +40,7 @@ struct SDL_WindowData
{ {
UIWindow *uiwindow; UIWindow *uiwindow;
SDL_uikitopenglview *view; SDL_uikitopenglview *view;
SDL_uikitviewcontroller *viewcontroller;
}; };
......
...@@ -38,6 +38,58 @@ ...@@ -38,6 +38,58 @@
#include <Foundation/Foundation.h> #include <Foundation/Foundation.h>
@implementation SDL_uikitviewcontroller
- (id)initWithSDLWindow:(SDL_Window *)_window {
[self init];
self->window = _window;
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient {
return YES;
}
- (void)loadView {
// do nothing.
}
// Send a resized event when the orientation changes.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
SDL_WindowData *data = self->window->driverdata;
UIWindow *uiwindow = data->uiwindow;
CGRect frame = [uiwindow frame];
const CGSize size = frame.size;
int w, h;
switch (toInterfaceOrientation) {
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
w = (size.width < size.height) ? size.width : size.height;
h = (size.width > size.height) ? size.width : size.height;
break;
case UIInterfaceOrientationLandscapeLeft:
case UIInterfaceOrientationLandscapeRight:
w = (size.width > size.height) ? size.width : size.height;
h = (size.width < size.height) ? size.width : size.height;
break;
default:
SDL_assert(0 && "Unexpected interface orientation!");
return;
}
self->window->w = w;
self->window->h = h;
frame.size.width = w;
frame.size.height = h;
SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
}
@end
static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
{ {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
...@@ -51,6 +103,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo ...@@ -51,6 +103,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
return -1; return -1;
} }
data->uiwindow = uiwindow; data->uiwindow = uiwindow;
data->viewcontroller = nil;
data->view = nil; data->view = nil;
/* Fill in the SDL window with the window data */ /* Fill in the SDL window with the window data */
...@@ -62,9 +115,11 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo ...@@ -62,9 +115,11 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
} }
window->driverdata = data; window->driverdata = data;
// !!! FIXME: should we force this? Shouldn't specifying FULLSCREEN
// !!! FIXME: imply BORDERLESS?
window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */ window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */
window->flags |= SDL_WINDOW_SHOWN; /* only one window on iPod touch, always shown */ window->flags |= SDL_WINDOW_SHOWN; /* only one window on iOS, always shown */
// SDL_WINDOW_BORDERLESS controls whether status bar is hidden. // SDL_WINDOW_BORDERLESS controls whether status bar is hidden.
// This is only set if the window is on the main screen. Other screens // This is only set if the window is on the main screen. Other screens
...@@ -72,6 +127,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo ...@@ -72,6 +127,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
if ([UIScreen mainScreen] != uiscreen) { if ([UIScreen mainScreen] != uiscreen) {
window->flags &= ~SDL_WINDOW_RESIZABLE; // window is NEVER resizeable window->flags &= ~SDL_WINDOW_RESIZABLE; // window is NEVER resizeable
window->flags &= ~SDL_WINDOW_INPUT_FOCUS; // never has input focus window->flags &= ~SDL_WINDOW_INPUT_FOCUS; // never has input focus
window->flags |= SDL_WINDOW_BORDERLESS; // never has a status bar.
} else { } else {
window->flags |= SDL_WINDOW_INPUT_FOCUS; // always has input focus window->flags |= SDL_WINDOW_INPUT_FOCUS; // always has input focus
...@@ -81,21 +137,34 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo ...@@ -81,21 +137,34 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
[UIApplication sharedApplication].statusBarHidden = NO; [UIApplication sharedApplication].statusBarHidden = NO;
} }
// Rotate the view if we have to, but only on the main screen
// (presumably, an external display doesn't report orientation).
const CGSize uisize = [[uiscreen currentMode] size]; const CGSize uisize = [[uiscreen currentMode] size];
if ( ((window->w > window->h) && (uisize.width < uisize.height)) || const UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
((window->w < window->h) && (uisize.width > uisize.height)) ) { const BOOL landscape = (o == UIDeviceOrientationLandscapeLeft) ||
// !!! FIXME: flip orientation. (o == UIDeviceOrientationLandscapeRight);
} const BOOL rotate = ( ((window->w > window->h) && (!landscape)) ||
((window->w < window->h) && (landscape)) );
if (window->flags & SDL_WINDOW_RESIZABLE) { if (window->flags & SDL_WINDOW_RESIZABLE) {
// !!! FIXME: register for orientation change alerts. // The View Controller will handle rotating the view when the
// device orientation changes. We expose these as resize events.
SDL_uikitviewcontroller *controller;
controller = [SDL_uikitviewcontroller alloc];
data->viewcontroller = [controller initWithSDLWindow:window];
[data->viewcontroller setTitle:@"SDL App"]; // !!! FIXME: hook up SDL_SetWindowTitle()
// !!! FIXME: if (rotate), force a "resize" right at the start
} else {
// Rotate the view if we have to, but only on the main screen
// (presumably, an external display doesn't report orientation).
if (rotate) {
#define D2R(x) (M_PI * (x) / 180.0) // degrees to radians.
[uiwindow setTransform:CGAffineTransformIdentity];
[uiwindow setTransform:CGAffineTransformMakeRotation(D2R(90))];
#undef D2R
}
} }
} }
return 0; return 0;
} }
int int
...@@ -107,7 +176,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) ...@@ -107,7 +176,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
// SDL currently puts this window at the start of display's linked list. We rely on this. // SDL currently puts this window at the start of display's linked list. We rely on this.
SDL_assert(_this->windows == window); SDL_assert(_this->windows == window);
/* We currently only handle a single window per display on iPhone */ /* We currently only handle a single window per display on iOS */
if (window->next != NULL) { if (window->next != NULL) {
SDL_SetError("Only one window allowed per display."); SDL_SetError("Only one window allowed per display.");
return -1; return -1;
...@@ -172,6 +241,7 @@ void ...@@ -172,6 +241,7 @@ void
UIKit_DestroyWindow(_THIS, SDL_Window * window) { UIKit_DestroyWindow(_THIS, SDL_Window * window) {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
if (data) { if (data) {
[data->viewcontroller release];
[data->uiwindow release]; [data->uiwindow release];
SDL_free(data); SDL_free(data);
window->driverdata = NULL; window->driverdata = NULL;
......
...@@ -140,7 +140,7 @@ main(int argc, char *argv[]) ...@@ -140,7 +140,7 @@ main(int argc, char *argv[])
} }
/* Set OpenGL parameters */ /* Set OpenGL parameters */
state->window_flags |= SDL_WINDOW_OPENGL; state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
state->gl_red_size = 5; state->gl_red_size = 5;
state->gl_green_size = 5; state->gl_green_size = 5;
state->gl_blue_size = 5; state->gl_blue_size = 5;
......
...@@ -219,6 +219,9 @@ main(int argc, char *argv[]) ...@@ -219,6 +219,9 @@ main(int argc, char *argv[])
if (!state) { if (!state) {
return 1; return 1;
} }
state->window_flags |= SDL_WINDOW_RESIZABLE;
for (i = 1; i < argc;) { for (i = 1; i < argc;) {
int consumed; int consumed;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment