src/video/uikit/SDL_uikitview.m
branchiOS-improvements
changeset 9527 bbd9326ecacf
parent 9525 64e3f446d6d7
child 9529 4bf9830d8153
equal deleted inserted replaced
9526:b1e51123fbea 9527:bbd9326ecacf
    33 #endif
    33 #endif
    34 #include "SDL_uikitappdelegate.h"
    34 #include "SDL_uikitappdelegate.h"
    35 #include "SDL_uikitmodes.h"
    35 #include "SDL_uikitmodes.h"
    36 #include "SDL_uikitwindow.h"
    36 #include "SDL_uikitwindow.h"
    37 
    37 
    38 void _uikit_keyboard_init();
       
    39 
       
    40 @implementation SDL_uikitview {
    38 @implementation SDL_uikitview {
    41 
    39 
    42     SDL_TouchID touchId;
    40     SDL_TouchID touchId;
    43     UITouch *leftFingerDown;
    41     UITouch *leftFingerDown;
    44 
    42 
    52 
    50 
    53 - (id)initWithFrame:(CGRect)frame
    51 - (id)initWithFrame:(CGRect)frame
    54 {
    52 {
    55     if (self = [super initWithFrame:frame]) {
    53     if (self = [super initWithFrame:frame]) {
    56 #if SDL_IPHONE_KEYBOARD
    54 #if SDL_IPHONE_KEYBOARD
    57         [self initializeKeyboard];
    55         [self initKeyboard];
    58 #endif
    56 #endif
    59 
    57 
    60         self.multipleTouchEnabled = YES;
    58         self.multipleTouchEnabled = YES;
    61 
    59 
    62         touchId = 1;
    60         touchId = 1;
    63         SDL_AddTouch(touchId, "");
    61         SDL_AddTouch(touchId, "");
    64     }
    62     }
    65 
    63 
    66     return self;
    64     return self;
    67 
    65 
       
    66 }
       
    67 
       
    68 - (void)dealloc
       
    69 {
       
    70 #if SDL_IPHONE_KEYBOARD
       
    71     [self deinitKeyboard];
       
    72 #endif
    68 }
    73 }
    69 
    74 
    70 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
    75 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
    71 {
    76 {
    72     CGPoint point = [touch locationInView:self];
    77     CGPoint point = [touch locationInView:self];
   150 @synthesize textInputRect;
   155 @synthesize textInputRect;
   151 @synthesize keyboardHeight;
   156 @synthesize keyboardHeight;
   152 @synthesize keyboardVisible;
   157 @synthesize keyboardVisible;
   153 
   158 
   154 /* Set ourselves up as a UITextFieldDelegate */
   159 /* Set ourselves up as a UITextFieldDelegate */
   155 - (void)initializeKeyboard
   160 - (void)initKeyboard
   156 {
   161 {
   157     textField = [[UITextField alloc] initWithFrame:CGRectZero];
   162     textField = [[UITextField alloc] initWithFrame:CGRectZero];
   158     textField.delegate = self;
   163     textField.delegate = self;
   159     /* placeholder so there is something to delete! */
   164     /* placeholder so there is something to delete! */
   160     textField.text = @" ";
   165     textField.text = @" ";
   170 
   175 
   171     textField.hidden = YES;
   176     textField.hidden = YES;
   172     keyboardVisible = NO;
   177     keyboardVisible = NO;
   173     /* add the UITextField (hidden) to our view */
   178     /* add the UITextField (hidden) to our view */
   174     [self addSubview:textField];
   179     [self addSubview:textField];
   175     
   180 
   176     _uikit_keyboard_init();
   181     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
       
   182     [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
       
   183     [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
       
   184 }
       
   185 
       
   186 - (void)deinitKeyboard
       
   187 {
       
   188     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
       
   189     [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
       
   190     [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
   177 }
   191 }
   178 
   192 
   179 /* reveal onscreen virtual keyboard */
   193 /* reveal onscreen virtual keyboard */
   180 - (void)showKeyboard
   194 - (void)showKeyboard
   181 {
   195 {
   186 /* hide onscreen virtual keyboard */
   200 /* hide onscreen virtual keyboard */
   187 - (void)hideKeyboard
   201 - (void)hideKeyboard
   188 {
   202 {
   189     keyboardVisible = NO;
   203     keyboardVisible = NO;
   190     [textField resignFirstResponder];
   204     [textField resignFirstResponder];
       
   205 }
       
   206 
       
   207 - (void)keyboardWillShow:(NSNotification *)notification
       
   208 {
       
   209     CGRect kbrect = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue];
       
   210     int height;
       
   211 
       
   212     /* The keyboard rect is in the coordinate space of the screen, but we want
       
   213      * its height in the view's coordinate space.
       
   214      */
       
   215 #ifdef __IPHONE_8_0
       
   216     if ([self respondsToSelector:@selector(convertRect:fromCoordinateSpace:)]) {
       
   217         UIScreen *screen = self.window.screen;
       
   218         kbrect = [self convertRect:kbrect fromCoordinateSpace:screen.coordinateSpace];
       
   219         height = kbrect.size.height;
       
   220     } else
       
   221 #endif
       
   222     {
       
   223         /* In iOS 7 and below, the screen's coordinate space is never rotated. */
       
   224         if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
       
   225             height = kbrect.size.width;
       
   226         } else {
       
   227             height = kbrect.size.height;
       
   228         }
       
   229     }
       
   230 
       
   231     [self setKeyboardHeight:height];
       
   232 }
       
   233 
       
   234  - (void)keyboardWillHide:(NSNotification *)notification
       
   235 {
       
   236     [self setKeyboardHeight:0];
       
   237 }
       
   238 
       
   239 - (void)updateKeyboard
       
   240 {
       
   241     SDL_Rect textrect = self.textInputRect;
       
   242     CGAffineTransform t = self.transform;
       
   243     CGPoint offset = CGPointMake(0.0, 0.0);
       
   244 
       
   245     if (self.keyboardHeight) {
       
   246         int rectbottom = textrect.y + textrect.h;
       
   247         int kbottom = self.bounds.size.height - self.keyboardHeight;
       
   248         if (kbottom < rectbottom) {
       
   249             offset.y = kbottom - rectbottom;
       
   250         }
       
   251     }
       
   252 
       
   253     /* Put the offset into the this view transform's coordinate space. */
       
   254     t.tx = 0.0;
       
   255     t.ty = 0.0;
       
   256     offset = CGPointApplyAffineTransform(offset, t);
       
   257 
       
   258     t.tx = offset.x;
       
   259     t.ty = offset.y;
       
   260 
       
   261     /* Move the view by applying the updated transform. */
       
   262     self.transform = t;
       
   263 }
       
   264 
       
   265 - (void)setKeyboardHeight:(int)height
       
   266 {
       
   267     keyboardVisible = height > 0;
       
   268     keyboardHeight = height;
       
   269     [self updateKeyboard];
   191 }
   270 }
   192 
   271 
   193 /* UITextFieldDelegate method.  Invoked when user types something. */
   272 /* UITextFieldDelegate method.  Invoked when user types something. */
   194 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
   273 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
   195 {
   274 {
   253 @end
   332 @end
   254 
   333 
   255 /* iPhone keyboard addition functions */
   334 /* iPhone keyboard addition functions */
   256 #if SDL_IPHONE_KEYBOARD
   335 #if SDL_IPHONE_KEYBOARD
   257 
   336 
   258 static SDL_uikitview * getWindowView(SDL_Window * window)
   337 static SDL_uikitview *
       
   338 GetWindowView(SDL_Window * window)
   259 {
   339 {
   260     if (window == NULL) {
   340     if (window == NULL) {
   261         SDL_SetError("Window does not exist");
   341         SDL_SetError("Window does not exist");
   262         return nil;
   342         return nil;
   263     }
   343     }
   270     }
   350     }
   271 
   351 
   272     return view;
   352     return view;
   273 }
   353 }
   274 
   354 
   275 SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
   355 SDL_bool
       
   356 UIKit_HasScreenKeyboardSupport(_THIS)
   276 {
   357 {
   277     return SDL_TRUE;
   358     return SDL_TRUE;
   278 }
   359 }
   279 
   360 
   280 void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
   361 void
       
   362 UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
   281 {
   363 {
   282     @autoreleasepool {
   364     @autoreleasepool {
   283         SDL_uikitview *view = getWindowView(window);
   365         SDL_uikitview *view = GetWindowView(window);
   284         if (view != nil) {
   366         if (view != nil) {
   285             [view showKeyboard];
   367             [view showKeyboard];
   286         }
   368         }
   287     }
   369     }
   288 }
   370 }
   289 
   371 
   290 void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
   372 void
       
   373 UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
   291 {
   374 {
   292     @autoreleasepool {
   375     @autoreleasepool {
   293         SDL_uikitview *view = getWindowView(window);
   376         SDL_uikitview *view = GetWindowView(window);
   294         if (view != nil) {
   377         if (view != nil) {
   295             [view hideKeyboard];
   378             [view hideKeyboard];
   296         }
   379         }
   297     }
   380     }
   298 }
   381 }
   299 
   382 
   300 SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
   383 SDL_bool
       
   384 UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
   301 {
   385 {
   302     @autoreleasepool {
   386     @autoreleasepool {
   303         SDL_uikitview *view = getWindowView(window);
   387         SDL_uikitview *view = GetWindowView(window);
   304         if (view == nil) {
   388         if (view != nil) {
   305             return 0;
   389             return view.isKeyboardVisible;
   306         }
   390         }
   307 
   391         return 0;
   308         return view.isKeyboardVisible;
   392     }
   309     }
       
   310 }
       
   311 
       
   312 
       
   313 void _uikit_keyboard_update() {
       
   314     SDL_Window *window = SDL_GetFocusWindow();
       
   315     if (!window) { return; }
       
   316     SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
       
   317     if (!data) { return; }
       
   318     SDL_uikitview *view = data.view;
       
   319     if (!view) { return; }
       
   320 
       
   321     SDL_Rect r = view.textInputRect;
       
   322     int height = view.keyboardHeight;
       
   323     int offsetx = 0;
       
   324     int offsety = 0;
       
   325     if (height) {
       
   326         int sw,sh;
       
   327         SDL_GetWindowSize(window,&sw,&sh);
       
   328         int bottom = (r.y + r.h);
       
   329         int kbottom = sh - height;
       
   330         if (kbottom < bottom) {
       
   331             offsety = kbottom-bottom;
       
   332         }
       
   333     }
       
   334     UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
       
   335     if (ui_orient == UIInterfaceOrientationLandscapeLeft) {
       
   336         int tmp = offsetx; offsetx = offsety; offsety = tmp;
       
   337     }
       
   338     if (ui_orient == UIInterfaceOrientationLandscapeRight) {
       
   339         offsety = -offsety;
       
   340         int tmp = offsetx; offsetx = offsety; offsety = tmp;
       
   341     }
       
   342     if (ui_orient == UIInterfaceOrientationPortraitUpsideDown) {
       
   343         offsety = -offsety;
       
   344     }
       
   345 
       
   346     view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
       
   347 }
       
   348 
       
   349 void _uikit_keyboard_set_height(int height) {
       
   350     SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
       
   351     if (view == nil) {
       
   352         return;
       
   353     }
       
   354 
       
   355     view.keyboardVisible = height > 0;
       
   356     view.keyboardHeight = height;
       
   357     _uikit_keyboard_update();
       
   358 }
       
   359 
       
   360 void _uikit_keyboard_init() {
       
   361     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
       
   362     NSOperationQueue *queue = [NSOperationQueue mainQueue];
       
   363     [center addObserverForName:UIKeyboardWillShowNotification
       
   364                         object:nil
       
   365                          queue:queue
       
   366                     usingBlock:^(NSNotification *notification) {
       
   367                         int height = 0;
       
   368                         CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
       
   369                         height = keyboardSize.height;
       
   370                         UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
       
   371                         if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
       
   372                             height = keyboardSize.width;
       
   373                         }
       
   374                         _uikit_keyboard_set_height(height);
       
   375                     }
       
   376      ];
       
   377     [center addObserverForName:UIKeyboardDidHideNotification
       
   378                         object:nil
       
   379                          queue:queue
       
   380                     usingBlock:^(NSNotification *notification) {
       
   381                         _uikit_keyboard_set_height(0);
       
   382                     }
       
   383      ];
       
   384 }
   393 }
   385 
   394 
   386 void
   395 void
   387 UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
   396 UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
   388 {
   397 {
   390         SDL_InvalidParamError("rect");
   399         SDL_InvalidParamError("rect");
   391         return;
   400         return;
   392     }
   401     }
   393 
   402 
   394     @autoreleasepool {
   403     @autoreleasepool {
   395         SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
   404         SDL_uikitview *view = GetWindowView(SDL_GetFocusWindow());
   396         if (view == nil) {
   405         if (view != nil) {
   397             return;
   406             view.textInputRect = *rect;
   398         }
   407 
   399 
   408             if (view.keyboardVisible) {
   400         view.textInputRect = *rect;
   409                 [view updateKeyboard];
       
   410             }
       
   411         }
   401     }
   412     }
   402 }
   413 }
   403 
   414 
   404 
   415 
   405 #endif /* SDL_IPHONE_KEYBOARD */
   416 #endif /* SDL_IPHONE_KEYBOARD */