diff options
author | Geenz <geenz@geenzo.com> | 2013-03-19 05:50:50 -0400 |
---|---|---|
committer | Geenz <geenz@geenzo.com> | 2013-03-19 05:50:50 -0400 |
commit | ad26f3c39002b6043e5fc4e00f9793e0f0e4941c (patch) | |
tree | 8cfc1c4de80259d9a18eaed3bc085ac6b320a7f8 /indra/llwindow | |
parent | 3c60fb24ca3685614880645af61d44287c369aea (diff) |
IME support (and revamped text input support) semi-working.
Diffstat (limited to 'indra/llwindow')
-rw-r--r-- | indra/llwindow/llopenglview-objc.h | 3 | ||||
-rw-r--r-- | indra/llwindow/llopenglview-objc.mm | 126 | ||||
-rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 12 |
3 files changed, 125 insertions, 16 deletions
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index c3ae34ea50..c144831da4 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -15,9 +15,10 @@ // Some nasty shovelling of LLOpenGLView from LLNativeBindings to prevent any C++ <-> Obj-C interop oddities. // Redraw callback handling removed (for now) due to being unneeded in the patch that preceeds this addition. -@interface LLOpenGLView : NSOpenGLView +@interface LLOpenGLView : NSOpenGLView <NSTextInputClient> { std::string mLastDraggedUrl; + unsigned int mModifiers; } - (id) initWithSamples:(NSUInteger)samples; - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync; diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 6ea523ea05..d568ed2fe5 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -94,6 +94,7 @@ - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync { + [[self window] makeFirstResponder:self]; [self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]]; [self initWithFrame:frame]; @@ -199,6 +200,7 @@ - (void) mouseDown:(NSEvent *)theEvent { + [self becomeFirstResponder]; [_window mouseDown:theEvent]; } @@ -234,7 +236,49 @@ - (void) keyDown:(NSEvent *)theEvent { - [_window keyDown:theEvent]; + [[self inputContext] handleEvent:theEvent]; + uint keycode = [theEvent keyCode]; + + switch (keycode) { + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + callKeyDown(keycode, mModifiers); + break; + + default: + callKeyDown(keycode, mModifiers); + NSString *chars = [theEvent characters]; + for (uint i = 0; i < [chars length]; i++) { + // Enter and Return are special cases. + unichar returntest = [chars characterAtIndex:i]; + if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) && + !([theEvent modifierFlags] & NSCommandKeyMask) && + !([theEvent modifierFlags] & NSAlternateKeyMask) && + !([theEvent modifierFlags] & NSControlKeyMask)) + { + callUnicodeCallback(13, 0); + } else { + // The command key being pressed is also a special case. + // Control + <character> produces an ASCII control character code. + // Command + <character> produces just the character's code. + // Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range. + if ([theEvent modifierFlags] & NSCommandKeyMask) + { + if (returntest >= 64 && returntest <= 95) + { + callUnicodeCallback(returntest - 63, mModifiers); + } else if (returntest >= 97 && returntest <= 122) + { + callUnicodeCallback(returntest - 96, mModifiers); + } + } + } + } + break; + } + } - (void) mouseMoved:(NSEvent *)theEvent @@ -242,9 +286,9 @@ [_window mouseMoved:theEvent]; } -- (void) flagsChanged:(NSEvent *)theEvent -{ - [_window flagsChanged:theEvent]; +- (void)flagsChanged:(NSEvent *)theEvent { + mModifiers = [theEvent modifierFlags]; + callModifier([theEvent modifierFlags]); } - (void) mouseExited:(NSEvent *)theEvent @@ -252,14 +296,9 @@ [_window mouseExited:theEvent]; } -- (BOOL) becomeFirstResponder +- (BOOL) acceptsFirstResponder { - return [_window becomeFirstResponder]; -} - -- (BOOL) resignFirstResponder -{ - return [_window resignFirstResponder]; + return YES; } - (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender @@ -305,6 +344,67 @@ return true; } +- (BOOL)hasMarkedText +{ + return NO; +} + +- (NSRange)markedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (NSRange)selectedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange +{ +} + +- (void)unmarkText +{ + +} + +- (NSArray *)validAttributesForMarkedText +{ + return [NSArray array]; +} + +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange +{ + return nil; +} + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange +{ + for (NSInteger i = 0; i < [aString length]; i++) + { + callUnicodeCallback([aString characterAtIndex:i], mModifiers); + } +} + +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint +{ + return NSNotFound; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange +{ + return NSZeroRect; +} + +- (void)doCommandBySelector:(SEL)aSelector +{ +} + +- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex +{ + return NO; +} + @end // We use a custom NSWindow for our event handling. @@ -315,12 +415,13 @@ - (id) init { - + [self makeFirstResponder:[self contentView]]; return self; } - (void) keyDown:(NSEvent *)theEvent { + uint keycode = [theEvent keyCode]; switch (keycode) { @@ -364,6 +465,7 @@ } break; } + } - (void) keyUp:(NSEvent *)theEvent { diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 34cc371526..08612bace4 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -223,7 +223,10 @@ void callUnicodeCallback(wchar_t character, unsigned int mask) void callFocus() { - gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); + if (gWindowImplementation) + { + gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); + } } void callFocusLost() @@ -369,9 +372,12 @@ void callHandleDragDropped(std::string url) void callQuitHandler() { - if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + if (gWindowImplementation) { - gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); + if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + { + gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); + } } } |