Added orientation rotation for iOS.
This commit is contained in:
parent
15b112e3a6
commit
ab0fcbfbd2
7 changed files with 114 additions and 19 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
/* 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 @@
|
||||||
}
|
}
|
||||||
/* 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 @@
|
||||||
#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> {
|
||||||
|
@ -49,6 +59,8 @@
|
||||||
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
|
||||||
{
|
{
|
||||||
UIWindow *uiwindow;
|
UIWindow *uiwindow;
|
||||||
SDL_uikitopenglview *view;
|
SDL_uikitopenglview *view;
|
||||||
|
SDL_uikitviewcontroller *viewcontroller;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
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 */
|
||||||
|
@ -63,8 +116,10 @@ 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
|
||||||
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
|
||||||
[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)
|
||||||
// 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
|
||||||
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[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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[])
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue