src/video/uikit/SDL_uikitview.m
branchiOS-improvements
changeset 9527 bbd9326ecacf
parent 9525 64e3f446d6d7
child 9529 4bf9830d8153
     1.1 --- a/src/video/uikit/SDL_uikitview.m	Fri Nov 21 10:03:02 2014 -0400
     1.2 +++ b/src/video/uikit/SDL_uikitview.m	Sun Nov 23 23:23:47 2014 -0400
     1.3 @@ -35,8 +35,6 @@
     1.4  #include "SDL_uikitmodes.h"
     1.5  #include "SDL_uikitwindow.h"
     1.6  
     1.7 -void _uikit_keyboard_init();
     1.8 -
     1.9  @implementation SDL_uikitview {
    1.10  
    1.11      SDL_TouchID touchId;
    1.12 @@ -54,7 +52,7 @@
    1.13  {
    1.14      if (self = [super initWithFrame:frame]) {
    1.15  #if SDL_IPHONE_KEYBOARD
    1.16 -        [self initializeKeyboard];
    1.17 +        [self initKeyboard];
    1.18  #endif
    1.19  
    1.20          self.multipleTouchEnabled = YES;
    1.21 @@ -67,6 +65,13 @@
    1.22  
    1.23  }
    1.24  
    1.25 +- (void)dealloc
    1.26 +{
    1.27 +#if SDL_IPHONE_KEYBOARD
    1.28 +    [self deinitKeyboard];
    1.29 +#endif
    1.30 +}
    1.31 +
    1.32  - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
    1.33  {
    1.34      CGPoint point = [touch locationInView:self];
    1.35 @@ -152,7 +157,7 @@
    1.36  @synthesize keyboardVisible;
    1.37  
    1.38  /* Set ourselves up as a UITextFieldDelegate */
    1.39 -- (void)initializeKeyboard
    1.40 +- (void)initKeyboard
    1.41  {
    1.42      textField = [[UITextField alloc] initWithFrame:CGRectZero];
    1.43      textField.delegate = self;
    1.44 @@ -172,8 +177,17 @@
    1.45      keyboardVisible = NO;
    1.46      /* add the UITextField (hidden) to our view */
    1.47      [self addSubview:textField];
    1.48 -    
    1.49 -    _uikit_keyboard_init();
    1.50 +
    1.51 +    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    1.52 +    [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    1.53 +    [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    1.54 +}
    1.55 +
    1.56 +- (void)deinitKeyboard
    1.57 +{
    1.58 +    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    1.59 +    [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    1.60 +    [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    1.61  }
    1.62  
    1.63  /* reveal onscreen virtual keyboard */
    1.64 @@ -190,6 +204,71 @@
    1.65      [textField resignFirstResponder];
    1.66  }
    1.67  
    1.68 +- (void)keyboardWillShow:(NSNotification *)notification
    1.69 +{
    1.70 +    CGRect kbrect = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    1.71 +    int height;
    1.72 +
    1.73 +    /* The keyboard rect is in the coordinate space of the screen, but we want
    1.74 +     * its height in the view's coordinate space.
    1.75 +     */
    1.76 +#ifdef __IPHONE_8_0
    1.77 +    if ([self respondsToSelector:@selector(convertRect:fromCoordinateSpace:)]) {
    1.78 +        UIScreen *screen = self.window.screen;
    1.79 +        kbrect = [self convertRect:kbrect fromCoordinateSpace:screen.coordinateSpace];
    1.80 +        height = kbrect.size.height;
    1.81 +    } else
    1.82 +#endif
    1.83 +    {
    1.84 +        /* In iOS 7 and below, the screen's coordinate space is never rotated. */
    1.85 +        if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
    1.86 +            height = kbrect.size.width;
    1.87 +        } else {
    1.88 +            height = kbrect.size.height;
    1.89 +        }
    1.90 +    }
    1.91 +
    1.92 +    [self setKeyboardHeight:height];
    1.93 +}
    1.94 +
    1.95 + - (void)keyboardWillHide:(NSNotification *)notification
    1.96 +{
    1.97 +    [self setKeyboardHeight:0];
    1.98 +}
    1.99 +
   1.100 +- (void)updateKeyboard
   1.101 +{
   1.102 +    SDL_Rect textrect = self.textInputRect;
   1.103 +    CGAffineTransform t = self.transform;
   1.104 +    CGPoint offset = CGPointMake(0.0, 0.0);
   1.105 +
   1.106 +    if (self.keyboardHeight) {
   1.107 +        int rectbottom = textrect.y + textrect.h;
   1.108 +        int kbottom = self.bounds.size.height - self.keyboardHeight;
   1.109 +        if (kbottom < rectbottom) {
   1.110 +            offset.y = kbottom - rectbottom;
   1.111 +        }
   1.112 +    }
   1.113 +
   1.114 +    /* Put the offset into the this view transform's coordinate space. */
   1.115 +    t.tx = 0.0;
   1.116 +    t.ty = 0.0;
   1.117 +    offset = CGPointApplyAffineTransform(offset, t);
   1.118 +
   1.119 +    t.tx = offset.x;
   1.120 +    t.ty = offset.y;
   1.121 +
   1.122 +    /* Move the view by applying the updated transform. */
   1.123 +    self.transform = t;
   1.124 +}
   1.125 +
   1.126 +- (void)setKeyboardHeight:(int)height
   1.127 +{
   1.128 +    keyboardVisible = height > 0;
   1.129 +    keyboardHeight = height;
   1.130 +    [self updateKeyboard];
   1.131 +}
   1.132 +
   1.133  /* UITextFieldDelegate method.  Invoked when user types something. */
   1.134  - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
   1.135  {
   1.136 @@ -255,7 +334,8 @@
   1.137  /* iPhone keyboard addition functions */
   1.138  #if SDL_IPHONE_KEYBOARD
   1.139  
   1.140 -static SDL_uikitview * getWindowView(SDL_Window * window)
   1.141 +static SDL_uikitview *
   1.142 +GetWindowView(SDL_Window * window)
   1.143  {
   1.144      if (window == NULL) {
   1.145          SDL_SetError("Window does not exist");
   1.146 @@ -272,117 +352,46 @@
   1.147      return view;
   1.148  }
   1.149  
   1.150 -SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
   1.151 +SDL_bool
   1.152 +UIKit_HasScreenKeyboardSupport(_THIS)
   1.153  {
   1.154      return SDL_TRUE;
   1.155  }
   1.156  
   1.157 -void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
   1.158 +void
   1.159 +UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
   1.160  {
   1.161      @autoreleasepool {
   1.162 -        SDL_uikitview *view = getWindowView(window);
   1.163 +        SDL_uikitview *view = GetWindowView(window);
   1.164          if (view != nil) {
   1.165              [view showKeyboard];
   1.166          }
   1.167      }
   1.168  }
   1.169  
   1.170 -void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
   1.171 +void
   1.172 +UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
   1.173  {
   1.174      @autoreleasepool {
   1.175 -        SDL_uikitview *view = getWindowView(window);
   1.176 +        SDL_uikitview *view = GetWindowView(window);
   1.177          if (view != nil) {
   1.178              [view hideKeyboard];
   1.179          }
   1.180      }
   1.181  }
   1.182  
   1.183 -SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
   1.184 +SDL_bool
   1.185 +UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
   1.186  {
   1.187      @autoreleasepool {
   1.188 -        SDL_uikitview *view = getWindowView(window);
   1.189 -        if (view == nil) {
   1.190 -            return 0;
   1.191 +        SDL_uikitview *view = GetWindowView(window);
   1.192 +        if (view != nil) {
   1.193 +            return view.isKeyboardVisible;
   1.194          }
   1.195 -
   1.196 -        return view.isKeyboardVisible;
   1.197 +        return 0;
   1.198      }
   1.199  }
   1.200  
   1.201 -
   1.202 -void _uikit_keyboard_update() {
   1.203 -    SDL_Window *window = SDL_GetFocusWindow();
   1.204 -    if (!window) { return; }
   1.205 -    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
   1.206 -    if (!data) { return; }
   1.207 -    SDL_uikitview *view = data.view;
   1.208 -    if (!view) { return; }
   1.209 -
   1.210 -    SDL_Rect r = view.textInputRect;
   1.211 -    int height = view.keyboardHeight;
   1.212 -    int offsetx = 0;
   1.213 -    int offsety = 0;
   1.214 -    if (height) {
   1.215 -        int sw,sh;
   1.216 -        SDL_GetWindowSize(window,&sw,&sh);
   1.217 -        int bottom = (r.y + r.h);
   1.218 -        int kbottom = sh - height;
   1.219 -        if (kbottom < bottom) {
   1.220 -            offsety = kbottom-bottom;
   1.221 -        }
   1.222 -    }
   1.223 -    UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
   1.224 -    if (ui_orient == UIInterfaceOrientationLandscapeLeft) {
   1.225 -        int tmp = offsetx; offsetx = offsety; offsety = tmp;
   1.226 -    }
   1.227 -    if (ui_orient == UIInterfaceOrientationLandscapeRight) {
   1.228 -        offsety = -offsety;
   1.229 -        int tmp = offsetx; offsetx = offsety; offsety = tmp;
   1.230 -    }
   1.231 -    if (ui_orient == UIInterfaceOrientationPortraitUpsideDown) {
   1.232 -        offsety = -offsety;
   1.233 -    }
   1.234 -
   1.235 -    view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
   1.236 -}
   1.237 -
   1.238 -void _uikit_keyboard_set_height(int height) {
   1.239 -    SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
   1.240 -    if (view == nil) {
   1.241 -        return;
   1.242 -    }
   1.243 -
   1.244 -    view.keyboardVisible = height > 0;
   1.245 -    view.keyboardHeight = height;
   1.246 -    _uikit_keyboard_update();
   1.247 -}
   1.248 -
   1.249 -void _uikit_keyboard_init() {
   1.250 -    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
   1.251 -    NSOperationQueue *queue = [NSOperationQueue mainQueue];
   1.252 -    [center addObserverForName:UIKeyboardWillShowNotification
   1.253 -                        object:nil
   1.254 -                         queue:queue
   1.255 -                    usingBlock:^(NSNotification *notification) {
   1.256 -                        int height = 0;
   1.257 -                        CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
   1.258 -                        height = keyboardSize.height;
   1.259 -                        UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
   1.260 -                        if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
   1.261 -                            height = keyboardSize.width;
   1.262 -                        }
   1.263 -                        _uikit_keyboard_set_height(height);
   1.264 -                    }
   1.265 -     ];
   1.266 -    [center addObserverForName:UIKeyboardDidHideNotification
   1.267 -                        object:nil
   1.268 -                         queue:queue
   1.269 -                    usingBlock:^(NSNotification *notification) {
   1.270 -                        _uikit_keyboard_set_height(0);
   1.271 -                    }
   1.272 -     ];
   1.273 -}
   1.274 -
   1.275  void
   1.276  UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
   1.277  {
   1.278 @@ -392,12 +401,14 @@
   1.279      }
   1.280  
   1.281      @autoreleasepool {
   1.282 -        SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
   1.283 -        if (view == nil) {
   1.284 -            return;
   1.285 +        SDL_uikitview *view = GetWindowView(SDL_GetFocusWindow());
   1.286 +        if (view != nil) {
   1.287 +            view.textInputRect = *rect;
   1.288 +
   1.289 +            if (view.keyboardVisible) {
   1.290 +                [view updateKeyboard];
   1.291 +            }
   1.292          }
   1.293 -
   1.294 -        view.textInputRect = *rect;
   1.295      }
   1.296  }
   1.297