src/video/uikit/SDL_uikitwindow.m
changeset 5529 8c0d15077360
parent 5527 9a03d2300486
child 5535 96594ac5fd1a
equal deleted inserted replaced
5528:15c9c03a80cc 5529:8c0d15077360
    39 #include <Foundation/Foundation.h>
    39 #include <Foundation/Foundation.h>
    40 
    40 
    41 @implementation SDL_uikitviewcontroller
    41 @implementation SDL_uikitviewcontroller
    42 
    42 
    43 - (id)initWithSDLWindow:(SDL_Window *)_window {
    43 - (id)initWithSDLWindow:(SDL_Window *)_window {
    44     [self init];
    44     if ((self = [self init]) == nil) {
       
    45         return nil;
       
    46     }
    45     self->window = _window;
    47     self->window = _window;
    46     return self;
    48     return self;
    47 }
    49 }
    48 
    50 
    49 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient {
    51 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient {
    50     return YES;
    52     if (self->window->flags & SDL_WINDOW_RESIZABLE) {
       
    53         return YES;  // any orientation is okay.
       
    54     }
       
    55 
       
    56     // If not resizable, allow device to orient to other matching sizes
       
    57     //  (that is, let the user turn the device upside down...same screen
       
    58     //   dimensions, but it lets the user place the device where it's most
       
    59     //   comfortable in relation to its physical buttons, headphone jack, etc).
       
    60     switch (orient) {
       
    61         case UIInterfaceOrientationLandscapeLeft:
       
    62         case UIInterfaceOrientationLandscapeRight:
       
    63             return (self->window->w >= self->window->h);
       
    64 
       
    65         case UIInterfaceOrientationPortrait:
       
    66         case UIInterfaceOrientationPortraitUpsideDown:
       
    67             return (self->window->h >= self->window->w);
       
    68 
       
    69         default: break;
       
    70     }
       
    71 
       
    72     return NO;  // Nothing else is acceptable.
    51 }
    73 }
    52 
    74 
    53 - (void)loadView  {
    75 - (void)loadView  {
    54     // do nothing.
    76     // do nothing.
    55 }
    77 }
    56 
    78 
    57 // Send a resized event when the orientation changes.
    79 // Send a resized event when the orientation changes.
    58 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    80 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
       
    81     if ((self->window->flags & SDL_WINDOW_RESIZABLE) == 0) {
       
    82         return;   // don't care, we're just flipping over in this case.
       
    83     }
       
    84 
    59     const UIInterfaceOrientation toInterfaceOrientation = [self interfaceOrientation];
    85     const UIInterfaceOrientation toInterfaceOrientation = [self interfaceOrientation];
    60     SDL_WindowData *data = self->window->driverdata;
    86     SDL_WindowData *data = self->window->driverdata;
    61     UIWindow *uiwindow = data->uiwindow;
    87     UIWindow *uiwindow = data->uiwindow;
    62     CGRect frame = [uiwindow frame];
    88     UIScreen *uiscreen = [uiwindow screen];
       
    89     const int noborder = self->window->flags & SDL_WINDOW_BORDERLESS;
       
    90     CGRect frame = noborder ? [uiscreen bounds] : [uiscreen applicationFrame];
    63     const CGSize size = frame.size;
    91     const CGSize size = frame.size;
    64     int w, h;
    92     int w, h;
    65 
    93 
    66     switch (toInterfaceOrientation) {
    94     switch (toInterfaceOrientation) {
    67         case UIInterfaceOrientationPortrait:
    95         case UIInterfaceOrientationPortrait:
    81             return;
   109             return;
    82     }
   110     }
    83 
   111 
    84     frame.size.width = w;
   112     frame.size.width = w;
    85     frame.size.height = h;
   113     frame.size.height = h;
       
   114     frame.origin.x = 0;
       
   115     frame.origin.y = 0;
       
   116 
    86     [uiwindow setFrame:frame];
   117     [uiwindow setFrame:frame];
    87     [data->view updateFrame];
   118     [data->view updateFrame];
    88     SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
   119     SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
    89 }
   120 }
    90 
   121 
   137             [UIApplication sharedApplication].statusBarHidden = YES;
   168             [UIApplication sharedApplication].statusBarHidden = YES;
   138         } else {
   169         } else {
   139             [UIApplication sharedApplication].statusBarHidden = NO;
   170             [UIApplication sharedApplication].statusBarHidden = NO;
   140         }
   171         }
   141 
   172 
   142         const CGSize uisize = [[uiscreen currentMode] size];
       
   143         const UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
   173         const UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
   144         const BOOL landscape = (o == UIDeviceOrientationLandscapeLeft) ||
   174         const BOOL landscape = (o == UIDeviceOrientationLandscapeLeft) ||
   145                                    (o == UIDeviceOrientationLandscapeRight);
   175                                    (o == UIDeviceOrientationLandscapeRight);
   146         const BOOL rotate = ( ((window->w > window->h) && (!landscape)) ||
   176         const BOOL rotate = ( ((window->w > window->h) && (!landscape)) ||
   147                               ((window->w < window->h) && (landscape)) );
   177                               ((window->w < window->h) && (landscape)) );
   148 
   178 
   149         if (window->flags & SDL_WINDOW_RESIZABLE) {
   179         // The View Controller will handle rotating the view when the
   150             // The View Controller will handle rotating the view when the
   180         //  device orientation changes. This will trigger resize events, if
   151             //  device orientation changes. We expose these as resize events.
   181         //  appropriate.
   152             SDL_uikitviewcontroller *controller;
   182         SDL_uikitviewcontroller *controller;
   153             controller = [SDL_uikitviewcontroller alloc];
   183         controller = [SDL_uikitviewcontroller alloc];
   154             data->viewcontroller = [controller initWithSDLWindow:window];
   184         data->viewcontroller = [controller initWithSDLWindow:window];
   155             [data->viewcontroller setTitle:@"SDL App"];  // !!! FIXME: hook up SDL_SetWindowTitle()
   185         [data->viewcontroller setTitle:@"SDL App"];  // !!! FIXME: hook up SDL_SetWindowTitle()
   156             // !!! FIXME: if (rotate), force a "resize" right at the start
   186         // !!! FIXME: if (rotate), force a "resize" right at the start
   157         } else {
       
   158             // Rotate the view if we have to, but only on the main screen
       
   159             //  (presumably, an external display doesn't report orientation).
       
   160             if (rotate) {
       
   161                 #define D2R(x) (M_PI * (x) / 180.0)   // degrees to radians.
       
   162                 [uiwindow setTransform:CGAffineTransformIdentity];
       
   163                 [uiwindow setTransform:CGAffineTransformMakeRotation(D2R(90))];
       
   164                 #undef D2R
       
   165             }
       
   166         }
       
   167     }
   187     }
   168 
   188 
   169     return 0;
   189     return 0;
   170 }
   190 }
   171 
   191 
   172 int
   192 int
   173 UIKit_CreateWindow(_THIS, SDL_Window *window)
   193 UIKit_CreateWindow(_THIS, SDL_Window *window)
   174 {
   194 {
   175     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
   195     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
   176     UIScreen *uiscreen = (UIScreen *) display->driverdata;
   196     UIScreen *uiscreen = (UIScreen *) display->driverdata;
       
   197     const BOOL external = ([UIScreen mainScreen] != uiscreen);
   177 
   198 
   178     // SDL currently puts this window at the start of display's linked list. We rely on this.
   199     // SDL currently puts this window at the start of display's linked list. We rely on this.
   179     SDL_assert(_this->windows == window);
   200     SDL_assert(_this->windows == window);
   180 
   201 
   181     /* We currently only handle a single window per display on iOS */
   202     /* We currently only handle a single window per display on iOS */
   185     }
   206     }
   186 
   207 
   187     // Non-mainscreen windows must be force to borderless, as there's no
   208     // Non-mainscreen windows must be force to borderless, as there's no
   188     //  status bar there, and we want to get the right dimensions later in
   209     //  status bar there, and we want to get the right dimensions later in
   189     //  this function.
   210     //  this function.
   190     if ([UIScreen mainScreen] != uiscreen) {
   211     if (external) {
   191         window->flags |= SDL_WINDOW_BORDERLESS;
   212         window->flags |= SDL_WINDOW_BORDERLESS;
   192     }
   213     }
   193 
   214 
   194     // If monitor has a resolution of 0x0 (hasn't been explicitly set by the
   215     // If monitor has a resolution of 0x0 (hasn't been explicitly set by the
   195     //  user, so it's in standby), try to force the display to a resolution
   216     //  user, so it's in standby), try to force the display to a resolution
   223     UIWindow *uiwindow = [UIWindow alloc];
   244     UIWindow *uiwindow = [UIWindow alloc];
   224     if (window->flags & SDL_WINDOW_BORDERLESS)
   245     if (window->flags & SDL_WINDOW_BORDERLESS)
   225         uiwindow = [uiwindow initWithFrame:[uiscreen bounds]];
   246         uiwindow = [uiwindow initWithFrame:[uiscreen bounds]];
   226     else
   247     else
   227         uiwindow = [uiwindow initWithFrame:[uiscreen applicationFrame]];
   248         uiwindow = [uiwindow initWithFrame:[uiscreen applicationFrame]];
   228 
   249     
   229     if (SDL_UIKit_supports_multiple_displays) {
   250     // put the window on an external display if appropriate. This implicitly
       
   251     //  does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
       
   252     //  main display, where we land by default, as that would eat the
       
   253     //  status bar real estate.
       
   254     if (external) {
   230         [uiwindow setScreen:uiscreen];
   255         [uiwindow setScreen:uiscreen];
   231     }
   256     }
   232 
   257 
   233     if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
   258     if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
   234         [uiwindow release];
   259         [uiwindow release];