Fixed Chinese IME support (thanks 树子。!)
authorSam Lantinga <slouken@libsdl.org>
Mon, 10 Sep 2018 23:01:33 -0700
changeset 1218402509665751f
parent 12183 364f514f94d8
child 12185 b6aa21d1a522
Fixed Chinese IME support (thanks 树子。!)
src/video/uikit/SDL_uikitviewcontroller.m
     1.1 --- a/src/video/uikit/SDL_uikitviewcontroller.m	Mon Sep 10 23:00:09 2018 -0700
     1.2 +++ b/src/video/uikit/SDL_uikitviewcontroller.m	Mon Sep 10 23:01:33 2018 -0700
     1.3 @@ -74,6 +74,8 @@
     1.4  #if SDL_IPHONE_KEYBOARD
     1.5      UITextField *textField;
     1.6      BOOL rotatingOrientation;
     1.7 +    NSString *changeText;
     1.8 +    NSString *obligateForBackspace;
     1.9  #endif
    1.10  }
    1.11  
    1.12 @@ -250,10 +252,12 @@
    1.13  /* Set ourselves up as a UITextFieldDelegate */
    1.14  - (void)initKeyboard
    1.15  {
    1.16 +    changeText = nil;
    1.17 +    obligateForBackspace = @"                                                                "; /* 64 space */
    1.18      textField = [[UITextField alloc] initWithFrame:CGRectZero];
    1.19      textField.delegate = self;
    1.20      /* placeholder so there is something to delete! */
    1.21 -    textField.text = @" ";
    1.22 +    textField.text = obligateForBackspace;
    1.23  
    1.24      /* set UITextInputTrait properties, mostly to defaults */
    1.25      textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
    1.26 @@ -267,11 +271,12 @@
    1.27      textField.hidden = YES;
    1.28      keyboardVisible = NO;
    1.29  
    1.30 +    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    1.31  #if !TARGET_OS_TV
    1.32 -    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    1.33      [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    1.34      [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    1.35  #endif
    1.36 +    [center addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil];
    1.37  }
    1.38  
    1.39  - (void)setView:(UIView *)view
    1.40 @@ -310,11 +315,12 @@
    1.41  
    1.42  - (void)deinitKeyboard
    1.43  {
    1.44 +    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    1.45  #if !TARGET_OS_TV
    1.46 -    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    1.47      [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    1.48      [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    1.49  #endif
    1.50 +    [center removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
    1.51  }
    1.52  
    1.53  /* reveal onscreen virtual keyboard */
    1.54 @@ -354,6 +360,50 @@
    1.55      [self setKeyboardHeight:0];
    1.56  }
    1.57  
    1.58 +- (void)textFieldTextDidChange:(NSNotification *)notification
    1.59 +{
    1.60 +    if (changeText!=nil && textField.markedTextRange == nil)
    1.61 +    {
    1.62 +        NSUInteger len = changeText.length;
    1.63 +        if (len > 0) {
    1.64 +            /* Go through all the characters in the string we've been sent and
    1.65 +             * convert them to key presses */
    1.66 +            int i;
    1.67 +            for (i = 0; i < len; i++) {
    1.68 +                unichar c = [changeText characterAtIndex:i];
    1.69 +                SDL_Scancode code;
    1.70 +                Uint16 mod;
    1.71 +
    1.72 +                if (c < 127) {
    1.73 +                    /* Figure out the SDL_Scancode and SDL_keymod for this unichar */
    1.74 +                    code = unicharToUIKeyInfoTable[c].code;
    1.75 +                    mod  = unicharToUIKeyInfoTable[c].mod;
    1.76 +                } else {
    1.77 +                    /* We only deal with ASCII right now */
    1.78 +                    code = SDL_SCANCODE_UNKNOWN;
    1.79 +                    mod = 0;
    1.80 +                }
    1.81 +
    1.82 +                if (mod & KMOD_SHIFT) {
    1.83 +                    /* If character uses shift, press shift down */
    1.84 +                    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
    1.85 +                }
    1.86 +
    1.87 +                /* send a keydown and keyup even for the character */
    1.88 +                SDL_SendKeyboardKey(SDL_PRESSED, code);
    1.89 +                SDL_SendKeyboardKey(SDL_RELEASED, code);
    1.90 +
    1.91 +                if (mod & KMOD_SHIFT) {
    1.92 +                    /* If character uses shift, press shift back up */
    1.93 +                    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
    1.94 +                }
    1.95 +            }
    1.96 +            SDL_SendKeyboardText([changeText UTF8String]);
    1.97 +        }
    1.98 +        changeText = nil;
    1.99 +    }
   1.100 +}
   1.101 +
   1.102  - (void)updateKeyboard
   1.103  {
   1.104      CGAffineTransform t = self.view.transform;
   1.105 @@ -392,49 +442,20 @@
   1.106  - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
   1.107  {
   1.108      NSUInteger len = string.length;
   1.109 -
   1.110      if (len == 0) {
   1.111 -        /* it wants to replace text with nothing, ie a delete */
   1.112 -        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
   1.113 -        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
   1.114 +        changeText = nil;
   1.115 +        if (textField.markedTextRange == nil) {
   1.116 +            /* it wants to replace text with nothing, ie a delete */
   1.117 +            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
   1.118 +            SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
   1.119 +        }
   1.120 +        if (textField.text.length < 16) {
   1.121 +            textField.text = obligateForBackspace;
   1.122 +        }
   1.123      } else {
   1.124 -        /* go through all the characters in the string we've been sent and
   1.125 -         * convert them to key presses */
   1.126 -        int i;
   1.127 -        for (i = 0; i < len; i++) {
   1.128 -            unichar c = [string characterAtIndex:i];
   1.129 -            Uint16 mod = 0;
   1.130 -            SDL_Scancode code;
   1.131 -
   1.132 -            if (c < 127) {
   1.133 -                /* figure out the SDL_Scancode and SDL_keymod for this unichar */
   1.134 -                code = unicharToUIKeyInfoTable[c].code;
   1.135 -                mod  = unicharToUIKeyInfoTable[c].mod;
   1.136 -            } else {
   1.137 -                /* we only deal with ASCII right now */
   1.138 -                code = SDL_SCANCODE_UNKNOWN;
   1.139 -                mod = 0;
   1.140 -            }
   1.141 -
   1.142 -            if (mod & KMOD_SHIFT) {
   1.143 -                /* If character uses shift, press shift down */
   1.144 -                SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
   1.145 -            }
   1.146 -
   1.147 -            /* send a keydown and keyup even for the character */
   1.148 -            SDL_SendKeyboardKey(SDL_PRESSED, code);
   1.149 -            SDL_SendKeyboardKey(SDL_RELEASED, code);
   1.150 -
   1.151 -            if (mod & KMOD_SHIFT) {
   1.152 -                /* If character uses shift, press shift back up */
   1.153 -                SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
   1.154 -            }
   1.155 -        }
   1.156 -
   1.157 -        SDL_SendKeyboardText([string UTF8String]);
   1.158 +        changeText = string;
   1.159      }
   1.160 -
   1.161 -    return NO; /* don't allow the edit! (keep placeholder text there) */
   1.162 +    return YES;
   1.163  }
   1.164  
   1.165  /* Terminates the editing session */
   1.166 @@ -498,7 +519,7 @@
   1.167      @autoreleasepool {
   1.168          SDL_uikitviewcontroller *vc = GetWindowViewController(window);
   1.169          if (vc != nil) {
   1.170 -            return vc.isKeyboardVisible;
   1.171 +            return vc.keyboardVisible;
   1.172          }
   1.173          return SDL_FALSE;
   1.174      }