src/video/uikit/SDL_uikitwindow.m
changeset 5520 09b500e0656d
parent 5518 f84dd424d514
child 5523 6dc03727fadc
equal deleted inserted replaced
5519:c425e4e8fc75 5520:09b500e0656d
    35 #import "SDL_uikitappdelegate.h"
    35 #import "SDL_uikitappdelegate.h"
    36 
    36 
    37 #import "SDL_uikitopenglview.h"
    37 #import "SDL_uikitopenglview.h"
    38 
    38 
    39 #include <Foundation/Foundation.h>
    39 #include <Foundation/Foundation.h>
       
    40 
       
    41 @implementation SDL_uikitviewcontroller
       
    42 
       
    43 - (id)initWithSDLWindow:(SDL_Window *)_window {
       
    44     [self init];
       
    45     self->window = _window;
       
    46     return self;
       
    47 }
       
    48 
       
    49 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient {
       
    50     return YES;
       
    51 }
       
    52 
       
    53 - (void)loadView  {
       
    54     // do nothing.
       
    55 }
       
    56 
       
    57 // Send a resized event when the orientation changes.
       
    58 - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
       
    59     SDL_WindowData *data = self->window->driverdata;
       
    60     UIWindow *uiwindow = data->uiwindow;
       
    61     CGRect frame = [uiwindow frame];
       
    62     const CGSize size = frame.size;
       
    63     int w, h;
       
    64 
       
    65     switch (toInterfaceOrientation) {
       
    66         case UIInterfaceOrientationPortrait:
       
    67         case UIInterfaceOrientationPortraitUpsideDown:
       
    68             w = (size.width < size.height) ? size.width : size.height;
       
    69             h = (size.width > size.height) ? size.width : size.height;
       
    70             break;
       
    71 
       
    72         case UIInterfaceOrientationLandscapeLeft:
       
    73         case UIInterfaceOrientationLandscapeRight:
       
    74             w = (size.width > size.height) ? size.width : size.height;
       
    75             h = (size.width < size.height) ? size.width : size.height;
       
    76             break;
       
    77 
       
    78         default:
       
    79             SDL_assert(0 && "Unexpected interface orientation!");
       
    80             return;
       
    81     }
       
    82     self->window->w = w;
       
    83     self->window->h = h;
       
    84     frame.size.width = w;
       
    85     frame.size.height = h;
       
    86     SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
       
    87 }
       
    88 
       
    89 @end
       
    90 
       
    91 
    40 
    92 
    41 static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
    93 static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
    42 {
    94 {
    43     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    95     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    44     UIScreen *uiscreen = (UIScreen *) display->driverdata;
    96     UIScreen *uiscreen = (UIScreen *) display->driverdata;
    49     if (!data) {
   101     if (!data) {
    50         SDL_OutOfMemory();
   102         SDL_OutOfMemory();
    51         return -1;
   103         return -1;
    52     }
   104     }
    53     data->uiwindow = uiwindow;
   105     data->uiwindow = uiwindow;
       
   106     data->viewcontroller = nil;
    54     data->view = nil;
   107     data->view = nil;
    55 
   108 
    56     /* Fill in the SDL window with the window data */
   109     /* Fill in the SDL window with the window data */
    57     {
   110     {
    58         window->x = 0;
   111         window->x = 0;
    60         window->w = (int)uiwindow.frame.size.width;
   113         window->w = (int)uiwindow.frame.size.width;
    61         window->h = (int)uiwindow.frame.size.height;
   114         window->h = (int)uiwindow.frame.size.height;
    62     }
   115     }
    63     
   116     
    64     window->driverdata = data;
   117     window->driverdata = data;
    65     
   118 
       
   119     // !!! FIXME: should we force this? Shouldn't specifying FULLSCREEN
       
   120     // !!! FIXME:  imply BORDERLESS?
    66     window->flags |= SDL_WINDOW_FULLSCREEN;        /* window is always fullscreen */
   121     window->flags |= SDL_WINDOW_FULLSCREEN;        /* window is always fullscreen */
    67     window->flags |= SDL_WINDOW_SHOWN;            /* only one window on iPod touch, always shown */
   122     window->flags |= SDL_WINDOW_SHOWN;            /* only one window on iOS, always shown */
    68 
   123 
    69     // SDL_WINDOW_BORDERLESS controls whether status bar is hidden.
   124     // SDL_WINDOW_BORDERLESS controls whether status bar is hidden.
    70     // This is only set if the window is on the main screen. Other screens
   125     // This is only set if the window is on the main screen. Other screens
    71     //  just force the window to have the borderless flag.
   126     //  just force the window to have the borderless flag.
    72     if ([UIScreen mainScreen] != uiscreen) {
   127     if ([UIScreen mainScreen] != uiscreen) {
    73         window->flags &= ~SDL_WINDOW_RESIZABLE;  // window is NEVER resizeable
   128         window->flags &= ~SDL_WINDOW_RESIZABLE;  // window is NEVER resizeable
    74         window->flags &= ~SDL_WINDOW_INPUT_FOCUS;  // never has input focus
   129         window->flags &= ~SDL_WINDOW_INPUT_FOCUS;  // never has input focus
       
   130         window->flags |= SDL_WINDOW_BORDERLESS;  // never has a status bar.
    75     } else {
   131     } else {
    76         window->flags |= SDL_WINDOW_INPUT_FOCUS;  // always has input focus
   132         window->flags |= SDL_WINDOW_INPUT_FOCUS;  // always has input focus
    77 
   133 
    78         if (window->flags & SDL_WINDOW_BORDERLESS) {
   134         if (window->flags & SDL_WINDOW_BORDERLESS) {
    79             [UIApplication sharedApplication].statusBarHidden = YES;
   135             [UIApplication sharedApplication].statusBarHidden = YES;
    80         } else {
   136         } else {
    81             [UIApplication sharedApplication].statusBarHidden = NO;
   137             [UIApplication sharedApplication].statusBarHidden = NO;
    82         }
   138         }
    83 
   139 
    84         // Rotate the view if we have to, but only on the main screen
       
    85         //  (presumably, an external display doesn't report orientation).
       
    86         const CGSize uisize = [[uiscreen currentMode] size];
   140         const CGSize uisize = [[uiscreen currentMode] size];
    87         if ( ((window->w > window->h) && (uisize.width < uisize.height)) ||
   141         const UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
    88              ((window->w < window->h) && (uisize.width > uisize.height)) ) {
   142         const BOOL landscape = (o == UIDeviceOrientationLandscapeLeft) ||
    89             // !!! FIXME: flip orientation.
   143                                    (o == UIDeviceOrientationLandscapeRight);
       
   144         const BOOL rotate = ( ((window->w > window->h) && (!landscape)) ||
       
   145                               ((window->w < window->h) && (landscape)) );
       
   146 
       
   147         if (window->flags & SDL_WINDOW_RESIZABLE) {
       
   148             // The View Controller will handle rotating the view when the
       
   149             //  device orientation changes. We expose these as resize events.
       
   150             SDL_uikitviewcontroller *controller;
       
   151             controller = [SDL_uikitviewcontroller alloc];
       
   152             data->viewcontroller = [controller initWithSDLWindow:window];
       
   153             [data->viewcontroller setTitle:@"SDL App"];  // !!! FIXME: hook up SDL_SetWindowTitle()
       
   154             // !!! FIXME: if (rotate), force a "resize" right at the start
       
   155         } else {
       
   156             // Rotate the view if we have to, but only on the main screen
       
   157             //  (presumably, an external display doesn't report orientation).
       
   158             if (rotate) {
       
   159                 #define D2R(x) (M_PI * (x) / 180.0)   // degrees to radians.
       
   160                 [uiwindow setTransform:CGAffineTransformIdentity];
       
   161                 [uiwindow setTransform:CGAffineTransformMakeRotation(D2R(90))];
       
   162                 #undef D2R
       
   163             }
    90         }
   164         }
    91 
       
    92         if (window->flags & SDL_WINDOW_RESIZABLE) {
       
    93             // !!! FIXME: register for orientation change alerts.
       
    94         }
       
    95     }
   165     }
    96 
   166 
    97     return 0;
   167     return 0;
    98     
       
    99 }
   168 }
   100 
   169 
   101 int
   170 int
   102 UIKit_CreateWindow(_THIS, SDL_Window *window)
   171 UIKit_CreateWindow(_THIS, SDL_Window *window)
   103 {
   172 {
   105     UIScreen *uiscreen = (UIScreen *) display->driverdata;
   174     UIScreen *uiscreen = (UIScreen *) display->driverdata;
   106 
   175 
   107     // SDL currently puts this window at the start of display's linked list. We rely on this.
   176     // SDL currently puts this window at the start of display's linked list. We rely on this.
   108     SDL_assert(_this->windows == window);
   177     SDL_assert(_this->windows == window);
   109 
   178 
   110     /* We currently only handle a single window per display on iPhone */
   179     /* We currently only handle a single window per display on iOS */
   111     if (window->next != NULL) {
   180     if (window->next != NULL) {
   112         SDL_SetError("Only one window allowed per display.");
   181         SDL_SetError("Only one window allowed per display.");
   113         return -1;
   182         return -1;
   114     }
   183     }
   115 
   184 
   170 
   239 
   171 void
   240 void
   172 UIKit_DestroyWindow(_THIS, SDL_Window * window) {
   241 UIKit_DestroyWindow(_THIS, SDL_Window * window) {
   173     SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
   242     SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
   174     if (data) {
   243     if (data) {
       
   244         [data->viewcontroller release];
   175         [data->uiwindow release];
   245         [data->uiwindow release];
   176         SDL_free(data);
   246         SDL_free(data);
   177         window->driverdata = NULL;
   247         window->driverdata = NULL;
   178     }
   248     }
   179 }
   249 }