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: |
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]; |