From fadf8d431e66299075aa0f4de7fdbe6a5a00d8fa Mon Sep 17 00:00:00 2001 From: Lukhnos Liu Date: Tue, 18 Sep 2012 22:34:00 -0700 Subject: [PATCH] Support Home/End/Del in input buffer, fixes #63. Also fix two subtle issues: 1. Enter (not Return) key now works in candidate list 2. Cursor index should be compared against builder's length, *not* composed string's length, because the former is counted in code point but the latter in UTF-16 units. The composed string's length might therefore be longer if the string contains codepoints > U+FFFF, which would cause the cursor mechanism to be off. --- Source/InputMethodController.mm | 75 +++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/Source/InputMethodController.mm b/Source/InputMethodController.mm index d3a40325..86662cf8 100644 --- a/Source/InputMethodController.mm +++ b/Source/InputMethodController.mm @@ -87,6 +87,7 @@ static NSString *const kPlainBopomofoModeIdentifier = @"org.openvanilla.inputmet // key code enums enum { + kEnterKeyCode = 76, kUpKeyCode = 126, kDownKeyCode = 125, kLeftKeyCode = 123, @@ -94,7 +95,8 @@ enum { kPageUpKeyCode = 116, kPageDownKeyCode = 121, kHomeKeyCode = 115, - kEndKeyCode = 119 + kEndKeyCode = 119, + kDeleteKeyCode = 117 }; // a global object for saving the "learned" user candidate selections @@ -524,7 +526,7 @@ public: [self updateClientComposingBuffer:_currentCandidateClient]; return YES; } - else if (charCode == 13 || keyCode == 127) { + else if (charCode == 13 || keyCode == kEnterKeyCode) { [self candidateController:gCurrentCandidateController didSelectCandidateAtIndex:gCurrentCandidateController.selectedCandidateIndex]; return YES; } @@ -765,7 +767,6 @@ public: return [self handleCandidateEventWithInputText:inputText charCode:charCode keyCode:keyCode]; } - // see if it's valid BPMF reading if (_bpmfReadingBuffer->isValidKey((char)charCode)) { _bpmfReadingBuffer->combineKey((char)charCode); @@ -896,7 +897,7 @@ public: return NO; } - if (_builder->cursorIndex() < [_composingBuffer length]) { + if (_builder->cursorIndex() < _builder->length()) { _builder->setCursorIndex(_builder->cursorIndex() + 1); } else { @@ -908,6 +909,48 @@ public: return YES; } + if (keyCode == kHomeKeyCode) { + if (!_bpmfReadingBuffer->isEmpty()) { + [self beep]; + } + else { + if (![_composingBuffer length]) { + return NO; + } + + if (_builder->cursorIndex()) { + _builder->setCursorIndex(0); + } + else { + [self beep]; + } + } + + [self updateClientComposingBuffer:client]; + return YES; + } + + if (keyCode == kEndKeyCode) { + if (!_bpmfReadingBuffer->isEmpty()) { + [self beep]; + } + else { + if (![_composingBuffer length]) { + return NO; + } + + if (_builder->cursorIndex() != _builder->length()) { + _builder->setCursorIndex(_builder->length()); + } + else { + [self beep]; + } + } + + [self updateClientComposingBuffer:client]; + return YES; + } + if (keyCode == absorbedArrowKey || keyCode == extraChooseCandidateKey) { if (!_bpmfReadingBuffer->isEmpty()) { [self beep]; @@ -939,6 +982,30 @@ public: return YES; } + // Delete + if (keyCode == kDeleteKeyCode) { + if (_bpmfReadingBuffer->isEmpty()) { + if (![_composingBuffer length]) { + return NO; + } + + if (_builder->cursorIndex() != _builder->length()) { + _builder->deleteReadingAfterCursor(); + [self walk]; + } + else { + [self beep]; + } + } + else { + [self beep]; + } + + [self updateClientComposingBuffer:client]; + return YES; + } + + // Enter if (charCode == 13) { if (![_composingBuffer length]) {