21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_UIKIT
28 #include "../SDL_sysvideo.h"
29 #include "../../events/SDL_events_c.h"
38 #if SDL_IPHONE_KEYBOARD
39 #include "keyinfotable.h"
44 SDL_AppleTVControllerUIHintChanged(
void *userdata,
const char *
name,
const char *oldValue,
const char *hint)
48 viewcontroller.controllerUserInteractionEnabled = hint && (*hint !=
'0');
55 SDL_HideHomeIndicatorHintChanged(
void *userdata,
const char *
name,
const char *oldValue,
const char *hint)
60 #pragma clang diagnostic push
61 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
62 if ([viewcontroller respondsToSelector:
@selector(setNeedsUpdateOfHomeIndicatorAutoHidden)]) {
63 [viewcontroller setNeedsUpdateOfHomeIndicatorAutoHidden];
64 [viewcontroller setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
66 #pragma clang diagnostic pop
72 CADisplayLink *displayLink;
73 int animationInterval;
74 void (*animationCallback)(
void*);
75 void *animationCallbackParam;
77 #if SDL_IPHONE_KEYBOARD
78 UITextField *textField;
79 BOOL hardwareKeyboard;
81 BOOL rotatingOrientation;
83 NSString *obligateForBackspace;
89 - (instancetype)initWithSDLWindow:(
SDL_Window *)_window
91 if (
self = [super initWithNibName:nil bundle:nil]) {
92 self.window = _window;
94 #if SDL_IPHONE_KEYBOARD
96 hardwareKeyboard = NO;
98 rotatingOrientation = NO;
103 SDL_AppleTVControllerUIHintChanged,
104 (__bridge
void *)
self);
109 SDL_HideHomeIndicatorHintChanged,
110 (__bridge
void *)
self);
118 #if SDL_IPHONE_KEYBOARD
119 [
self deinitKeyboard];
124 SDL_AppleTVControllerUIHintChanged,
125 (__bridge
void *)
self);
130 SDL_HideHomeIndicatorHintChanged,
131 (__bridge
void *)
self);
135 - (
void)setAnimationCallback:(
int)interval
136 callback:(
void (*)(
void*))callback
137 callbackParam:(
void*)callbackParam
139 [
self stopAnimation];
141 animationInterval = interval;
143 animationCallbackParam = callbackParam;
145 if (animationCallback) {
146 [
self startAnimation];
150 - (
void)startAnimation
152 displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)];
157 if ([displayLink respondsToSelector:
@selector(preferredFramesPerSecond)]
158 &&
data != nil &&
data.uiwindow != nil
159 && [data.uiwindow.screen respondsToSelector:@selector(maximumFramesPerSecond)]) {
160 displayLink.preferredFramesPerSecond =
data.uiwindow.screen.maximumFramesPerSecond / animationInterval;
164 #if __IPHONE_OS_VERSION_MIN_REQUIRED < 100300
165 [displayLink setFrameInterval:animationInterval];
169 [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
172 - (
void)stopAnimation
174 [displayLink invalidate];
178 - (
void)doLoop:(CADisplayLink*)sender
181 if (!UIKit_ShowingMessageBox()) {
183 #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
184 UIKit_GL_RestoreCurrentContext();
187 animationCallback(animationCallbackParam);
196 - (
void)viewDidLayoutSubviews
198 const CGSize
size =
self.view.bounds.size;
199 int w = (int)
size.width;
200 int h = (
int)
size.height;
206 - (NSUInteger)supportedInterfaceOrientations
211 #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
212 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
214 return ([
self supportedInterfaceOrientations] & (1 << orient)) != 0;
218 - (BOOL)prefersStatusBarHidden
224 - (BOOL)prefersHomeIndicatorAutoHidden
227 if (
self.homeIndicatorHidden == 1) {
233 - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
235 if (
self.homeIndicatorHidden >= 0) {
236 if (
self.homeIndicatorHidden == 2) {
237 return UIRectEdgeAll;
239 return UIRectEdgeNone;
245 return UIRectEdgeAll;
247 return UIRectEdgeNone;
255 #if SDL_IPHONE_KEYBOARD
257 @synthesize textInputRect;
258 @synthesize keyboardHeight;
259 @synthesize keyboardVisible;
265 obligateForBackspace =
@" ";
266 textField = [[UITextField alloc] initWithFrame:CGRectZero];
267 textField.delegate =
self;
269 textField.text = obligateForBackspace;
272 textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
273 textField.autocorrectionType = UITextAutocorrectionTypeNo;
274 textField.enablesReturnKeyAutomatically = NO;
275 textField.keyboardAppearance = UIKeyboardAppearanceDefault;
276 textField.keyboardType = UIKeyboardTypeDefault;
277 textField.returnKeyType = UIReturnKeyDefault;
278 textField.secureTextEntry = NO;
280 textField.hidden = YES;
281 keyboardVisible = NO;
283 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
285 [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
286 [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
288 [center addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil];
291 - (NSArray *)keyCommands
293 NSMutableArray *
commands = [[NSMutableArray alloc] init];
294 [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]];
295 [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputDownArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]];
296 [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputLeftArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]];
297 [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputRightArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]];
298 [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputEscape modifierFlags:kNilOptions action:@selector(handleCommand:)]];
299 return [NSArray arrayWithArray:commands];
302 - (
void)handleCommand:(UIKeyCommand *)keyCommand
305 NSString *
input = keyCommand.input;
307 if (
input == UIKeyInputUpArrow) {
309 }
else if (
input == UIKeyInputDownArrow) {
311 }
else if (
input == UIKeyInputLeftArrow) {
313 }
else if (
input == UIKeyInputRightArrow) {
315 }
else if (
input == UIKeyInputEscape) {
325 - (
void)setView:(UIView *)view
327 [
super setView:view];
329 [view addSubview:textField];
331 if (keyboardVisible) {
337 #if TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
338 - (
void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(
id<UIViewControllerTransitionCoordinator>)coordinator
340 [
super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
341 rotatingOrientation = YES;
342 [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {}
343 completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
344 self->rotatingOrientation = NO;
348 - (
void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
349 [
super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
350 rotatingOrientation = YES;
353 - (
void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
354 [
super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
355 rotatingOrientation = NO;
359 - (
void)deinitKeyboard
361 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
363 [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
364 [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
366 [center removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
372 keyboardVisible = YES;
373 if (textField.window) {
374 showingKeyboard = YES;
375 [textField becomeFirstResponder];
376 showingKeyboard = NO;
383 keyboardVisible = NO;
384 [textField resignFirstResponder];
387 - (
void)keyboardWillShow:(NSNotification *)notification
390 CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
394 kbrect = [
self.view convertRect:kbrect fromView:nil];
396 [
self setKeyboardHeight:(int)kbrect.size.height];
400 - (
void)keyboardWillHide:(NSNotification *)notification
402 if (!showingKeyboard && !rotatingOrientation) {
405 [
self setKeyboardHeight:0];
408 - (
void)textFieldTextDidChange:(NSNotification *)notification
410 if (changeText!=nil && textField.markedTextRange == nil)
412 NSUInteger
len = changeText.length;
417 for (
i = 0;
i <
len;
i++) {
418 unichar
c = [changeText characterAtIndex:i];
452 - (
void)updateKeyboard
454 CGAffineTransform
t =
self.view.transform;
455 CGPoint
offset = CGPointMake(0.0, 0.0);
456 CGRect
frame = UIKit_ComputeViewFrame(
window,
self.view.window.screen);
458 if (
self.keyboardHeight) {
459 int rectbottom =
self.textInputRect.y + self.textInputRect.
h;
460 int keybottom =
self.view.bounds.size.height - self.keyboardHeight;
461 if (keybottom < rectbottom) {
462 offset.y = keybottom - rectbottom;
476 self.view.frame =
frame;
479 - (
void)setKeyboardHeight:(
int)height
481 keyboardVisible =
height > 0;
483 [
self updateKeyboard];
487 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
489 NSUInteger
len =
string.length;
492 if (textField.markedTextRange == nil) {
497 if (textField.text.length < 16) {
498 textField.text = obligateForBackspace;
507 - (BOOL)textFieldShouldReturn:(UITextField*)_textField
511 if (keyboardVisible &&
523 #if SDL_IPHONE_KEYBOARD
539 UIKit_HasScreenKeyboardSupport(
_THIS)
568 return vc.keyboardVisible;
585 vc.textInputRect = *
rect;
587 if (vc.keyboardVisible) {