Mercurial > sdl-ios-xcode
diff src/video/cocoa/SDL_cocoakeyboard.m @ 3280:00cace2d9080
Merged a cleaned up version of Jiang's code changes from Google Summer of Code 2009
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 19 Sep 2009 13:29:40 +0000 |
parents | 2dcfb4e07a57 |
children | d390778b59c1 |
line wrap: on
line diff
--- a/src/video/cocoa/SDL_cocoakeyboard.m Sat Sep 19 12:48:52 2009 +0000 +++ b/src/video/cocoa/SDL_cocoakeyboard.m Sat Sep 19 13:29:40 2009 +0000 @@ -28,6 +28,8 @@ #include <Carbon/Carbon.h> +//#define DEBUG_IME NSLog +#define DEBUG_IME #ifndef NX_DEVICERCTLKEYMASK #define NX_DEVICELCTLKEYMASK 0x00000001 @@ -54,14 +56,142 @@ #define NX_DEVICERCTLKEYMASK 0x00002000 #endif -@interface SDLTranslatorResponder : NSTextView +@interface SDLTranslatorResponder : NSView <NSTextInput> { + NSString *_markedText; + NSRange _markedRange; + NSRange _selectedRange; + SDL_Rect _inputRect; + int _keyboard; } - (void) doCommandBySelector:(SEL)myselector; +- (void) setInputRect:(SDL_Rect *) rect; +- (void) setKeyboard:(int) keyboard; @end @implementation SDLTranslatorResponder -- (void) doCommandBySelector:(SEL) myselector {} + +- (void) setKeyboard:(int) keyboard +{ + _keyboard = keyboard; +} + +- (void) setInputRect:(SDL_Rect *) rect +{ + _inputRect = *rect; +} + +- (void) insertText:(id) aString +{ + const char *str; + + DEBUG_IME(@"insertText: %@", aString); + + /* Could be NSString or NSAttributedString, so we have + * to test and convert it before return as SDL event */ + if ([aString isKindOfClass: [NSAttributedString class]]) + str = [[aString string] UTF8String]; + else + str = [aString UTF8String]; + + SDL_SendKeyboardText(_keyboard, str); +} + +- (void) doCommandBySelector:(SEL) myselector +{ + [super doCommandBySelector: myselector]; +} + +- (BOOL) hasMarkedText +{ + return _markedText != nil; +} + +- (NSRange) markedRange +{ + return _markedRange; +} + +- (NSRange) selectedRange +{ + return _selectedRange; +} + +- (void) setMarkedText:(id) aString + selectedRange:(NSRange) selRange +{ + if ([aString isKindOfClass: [NSAttributedString class]]) + aString = [aString string]; + + if ([aString length] == 0) + { + [self unmarkText]; + return; + } + + if (_markedText != aString) + { + [_markedText release]; + _markedText = [aString retain]; + } + + _selectedRange = selRange; + _markedRange = NSMakeRange(0, [aString length]); + + SDL_SendEditingText([aString UTF8String], selRange.location, selRange.length); + + DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText, + selRange.location, selRange.length); +} + +- (void) unmarkText +{ + [_markedText release]; + _markedText = nil; +} + +- (NSRect) firstRectForCharacterRange: (NSRange) theRange +{ + float windowHeight = [[self window] frame].size.height; + NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h, + _inputRect.w, _inputRect.h); + + DEBUG_IME(@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@", + theRange.location, theRange.length, windowHeight, + NSStringFromRect(rect)); + rect.origin = [[self window] convertBaseToScreen: rect.origin]; + + return rect; +} + +- (NSAttributedString *) attributedSubstringFromRange: (NSRange) theRange +{ + DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", theRange.location, theRange.length); + return nil; +} + +- (NSInteger) conversationIdentifier +{ + return (NSInteger) self; +} + +// This method returns the index for character that is +// nearest to thePoint. thPoint is in screen coordinate system. +- (NSUInteger) characterIndexForPoint:(NSPoint) thePoint +{ + DEBUG_IME(@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y); + return 0; +} + +// This method is the key to attribute extension. +// We could add new attributes through this method. +// NSInputServer examines the return value of this +// method & constructs appropriate attributed string. +- (NSArray *) validAttributesForMarkedText +{ + return [NSArray array]; +} + @end /* This is the original behavior, before support was added for @@ -478,12 +608,7 @@ { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_Keyboard keyboard; - NSAutoreleasePool *pool; - pool = [[NSAutoreleasePool alloc] init]; - data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)]; - [pool release]; - SDL_zero(keyboard); data->keyboard = SDL_AddKeyboard(&keyboard, -1); UpdateKeymap(data); @@ -498,6 +623,47 @@ } void +Cocoa_StartTextInput(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSView *parentView = [[NSApp keyWindow] contentView]; + + data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)]; + [data->fieldEdit setKeyboard: data->keyboard]; + + if (! [[data->fieldEdit superview] isEqual: parentView]) + { + // DEBUG_IME(@"add fieldEdit to window contentView"); + [data->fieldEdit removeFromSuperview]; + [parentView addSubview: data->fieldEdit]; + [[NSApp keyWindow] makeFirstResponder: data->fieldEdit]; + } + + [pool release]; +} + +void +Cocoa_StopTextInput(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [data->fieldEdit removeFromSuperview]; + [data->fieldEdit release]; + data->fieldEdit = nil; + [pool release]; +} + +void +Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + [data->fieldEdit setInputRect: rect]; +} + +void Cocoa_HandleKeyEvent(_THIS, NSEvent *event) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; @@ -533,11 +699,13 @@ if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */ [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; +#if 0 text = [[event characters] UTF8String]; if(text && *text) { SDL_SendKeyboardText(data->keyboard, text); [data->fieldEdit setString:@""]; } +#endif } break; case NSKeyUp: @@ -559,10 +727,6 @@ NSAutoreleasePool *pool; SDL_DelKeyboard(data->keyboard); - - pool = [[NSAutoreleasePool alloc] init]; - [data->fieldEdit release]; - [pool release]; } /* vi: set ts=4 sw=4 expandtab: */