Make sure mode width/height and status bar orientation match

This commit is contained in:
Sam Lantinga 2012-09-29 18:52:00 -07:00
parent 767bcb961b
commit 9a82a89800
3 changed files with 91 additions and 47 deletions

View file

@ -39,6 +39,8 @@ typedef struct
extern BOOL SDL_UIKit_supports_multiple_displays;
extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
extern int UIKit_InitModes(_THIS);
extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);

View file

@ -93,13 +93,13 @@ UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
static int
UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
UIScreenMode * uiscreenmode, BOOL addRotated)
UIScreenMode * uiscreenmode, SDL_bool addRotation)
{
if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
return -1;
}
if (addRotated) {
if (addRotation) {
// Add the rotated version
if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
return -1;
@ -114,6 +114,13 @@ UIKit_AddDisplay(UIScreen *uiscreen)
{
CGSize size = [uiscreen bounds].size;
// Make sure the width/height are oriented correctly
if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
CGFloat height = size.width;
size.width = size.height;
size.height = height;
}
// When dealing with UIKit all coordinates are specified in terms of
// what Apple refers to as points. On earlier devices without the
// so called "Retina" display, there is a one to one mapping between
@ -168,6 +175,16 @@ UIKit_AddDisplay(UIScreen *uiscreen)
return 0;
}
SDL_bool
UIKit_IsDisplayLandscape(UIScreen *uiscreen)
{
if (uiscreen == [UIScreen mainScreen]) {
return UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
} else {
CGSize size = [uiscreen bounds].size;
return (size.width > size.height);
}
}
int
UIKit_InitModes(_THIS)
@ -203,6 +220,9 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
if (SDL_UIKit_supports_multiple_displays) {
// availableModes showed up in 3.2 (the iPad and later). We should only
// land here for at least that version of the OS.
@ -210,10 +230,16 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
CGSize size = [uimode size];
int w = (int)size.width;
int h = (int)size.height;
BOOL addRotated = (data->uiscreen == [UIScreen mainScreen]);
// Make sure the width/height are oriented correctly
if (isLandscape != (w > h)) {
int tmp = w;
w = h;
h = tmp;
}
// Add the native screen resolution.
UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotated);
UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotation);
if (data->scale != 1.0f) {
// Add the native screen resolution divided by its scale.
@ -222,14 +248,22 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
UIKit_AddDisplayMode(display,
(int)(size.width / data->scale),
(int)(size.height / data->scale),
1.0f, uimode, addRotated);
1.0f, uimode, addRotation);
}
}
} else {
const CGRect rect = [data->uiscreen bounds];
UIKit_AddDisplayMode(display,
(int)rect.size.width, (int)rect.size.height,
1.0f, nil, YES);
const CGSize size = [data->uiscreen bounds].size;
int w = (int)size.width;
int h = (int)size.height;
// Make sure the width/height are oriented correctly
if (isLandscape != (w > h)) {
int tmp = w;
w = h;
h = tmp;
}
UIKit_AddDisplayMode(display, w, h, 1.0f, nil, addRotation);
}
}
@ -237,6 +271,7 @@ int
UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
if (!SDL_UIKit_supports_multiple_displays) {
// Not on at least iPhoneOS 3.2 (versions prior to iPad).
SDL_assert(mode->driverdata == NULL);
@ -244,15 +279,18 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
[data->uiscreen setCurrentMode:modedata->uiscreenmode];
if (data->uiscreen == [UIScreen mainScreen]) {
if (mode->w > mode->h) {
if (!UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
}
} else if (mode->w < mode->h) {
if (!UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
if (UIKit_IsDisplayLandscape(data->uiscreen)) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
}
}
}
}
return 0;
}

View file

@ -77,31 +77,15 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
int width = (int)(bounds.size.width * displaymodedata->scale);
int height = (int)(bounds.size.height * displaymodedata->scale);
if ([UIScreen mainScreen] == displaydata->uiscreen) {
/* We can pick either width or height here and we'll rotate the
screen to match, so we pick the closest to what we wanted.
*/
if (window->w >= window->h) {
if (width > height) {
// Make sure the width/height are oriented correctly
if (UIKit_IsDisplayLandscape(displaydata->uiscreen) != (width > height)) {
int temp = width;
width = height;
height = temp;
}
window->w = width;
window->h = height;
} else {
window->w = height;
window->h = width;
}
} else {
if (width > height) {
window->w = height;
window->h = width;
} else {
window->w = width;
window->h = height;
}
}
} else {
window->w = width;
window->h = height;
}
}
window->driverdata = data;
@ -112,13 +96,13 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
// SDL_WINDOW_BORDERLESS controls whether status bar is hidden.
// This is only set if the window is on the main screen. Other screens
// just force the window to have the borderless flag.
if ([UIScreen mainScreen] == displaydata->uiscreen) {
if (displaydata->uiscreen == [UIScreen mainScreen]) {
window->flags |= SDL_WINDOW_INPUT_FOCUS; // always has input focus
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
[UIApplication sharedApplication].statusBarHidden = YES;
if ([UIApplication sharedApplication].statusBarHidden) {
window->flags |= SDL_WINDOW_BORDERLESS;
} else {
[UIApplication sharedApplication].statusBarHidden = NO;
window->flags &= ~SDL_WINDOW_BORDERLESS;
}
} else {
window->flags &= ~SDL_WINDOW_RESIZABLE; // window is NEVER resizeable
@ -183,6 +167,26 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
}
}
if (data->uiscreen == [UIScreen mainScreen]) {
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
[UIApplication sharedApplication].statusBarHidden = YES;
} else {
[UIApplication sharedApplication].statusBarHidden = NO;
}
}
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
if (window->w > window->h) {
if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
}
} else if (window->w < window->h) {
if (UIKit_IsDisplayLandscape(data->uiscreen)) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
}
}
}
/* ignore the size user requested, and make a fullscreen window */
// !!! FIXME: can we have a smaller view?
UIWindow *uiwindow = [UIWindow alloc];