Extract the candidate handler; handle subtleties of vertical text mode.
Now both Left and Right can be used as choose-candidate key. Also the candidate window now doesn't obscure the vertical text being typed by moving to the right to the vertical text. Because of this, Left key feels strange. Adding Right key should give a better mental model.
This commit is contained in:
parent
c48d478b4e
commit
ddbd94bee4
|
@ -118,6 +118,9 @@ SimpleLM gLanguageModel;
|
|||
- (void)_performDeferredSaveUserCandidatesDictionary;
|
||||
- (void)saveUserCandidatesDictionary;
|
||||
- (void)_showCandidateWindowUsingVerticalMode:(BOOL)useVerticalMode client:(id)client;
|
||||
|
||||
- (void)beep;
|
||||
- (BOOL)handleCandidateEventWithInputText:(NSString *)inputText charCode:(UniChar)charCode keyCode:(NSUInteger)keyCode;
|
||||
@end
|
||||
|
||||
// sort helper
|
||||
|
@ -457,72 +460,8 @@ public:
|
|||
NSBeep();
|
||||
}
|
||||
|
||||
- (BOOL)inputText:(NSString*)inputText key:(NSInteger)keyCode modifiers:(NSUInteger)flags client:(id)client
|
||||
- (BOOL)handleCandidateEventWithInputText:(NSString *)inputText charCode:(UniChar)charCode keyCode:(NSUInteger)keyCode
|
||||
{
|
||||
NSRect textFrame = NSZeroRect;
|
||||
NSDictionary *attributes = nil;
|
||||
BOOL useVerticalMode = NO;
|
||||
@try {
|
||||
attributes = [client attributesForCharacterIndex:0 lineHeightRectangle:&textFrame];
|
||||
useVerticalMode = [attributes objectForKey:@"IMKTextOrientation"] && [[attributes objectForKey:@"IMKTextOrientation"] integerValue] == 0;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
// An exception may raise while using Twitter.app's search filed.
|
||||
}
|
||||
|
||||
NSInteger cursorForwardKey = useVerticalMode ? kDownKeyCode : kRightKeyCode;
|
||||
NSInteger cursorBackwardKey = useVerticalMode ? kUpKeyCode : kLeftKeyCode;
|
||||
NSInteger extraChooseCandidateKey = useVerticalMode ? kLeftKeyCode : kDownKeyCode;
|
||||
NSInteger absorbedArrowKey = useVerticalMode ? kRightKeyCode : kUpKeyCode;
|
||||
|
||||
// get the unicode character code
|
||||
UniChar charCode = [inputText length] ? [inputText characterAtIndex:0] : 0;
|
||||
|
||||
if ([[client bundleIdentifier] isEqualToString:@"com.apple.Terminal"] && [NSStringFromClass([client class]) isEqualToString:@"IPMDServerClientWrapper"])
|
||||
{
|
||||
// special handling for com.apple.Terminal
|
||||
_currentDeferredClient = client;
|
||||
}
|
||||
|
||||
// if the inputText is empty, it's a function key combination, we ignore it
|
||||
if (![inputText length]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// if the composing buffer is empty and there's no reading, and there is some function key combination, we ignore it
|
||||
if (![_composingBuffer length] && _bpmfReadingBuffer->isEmpty() && ((flags & NSCommandKeyMask) || (flags & NSControlKeyMask) || (flags & NSAlternateKeyMask) || (flags & NSNumericPadKeyMask))) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
bool composeReading = false;
|
||||
|
||||
// caps lock processing : if caps is locked, temporarily disabled bopomofo.
|
||||
|
||||
if (charCode == 8 || charCode == 13 ||
|
||||
keyCode == absorbedArrowKey || keyCode == extraChooseCandidateKey ||
|
||||
keyCode == cursorForwardKey || keyCode == cursorBackwardKey) {
|
||||
// Do nothing if backspace is pressed
|
||||
} else if (flags & NSAlphaShiftKeyMask){
|
||||
// Now process all possible combination, we hope.
|
||||
if ([_composingBuffer length]) [self commitComposition:client];
|
||||
// First commit everything in the buffer.
|
||||
if (flags & NSShiftKeyMask) return NO;
|
||||
// when shift is pressed, don't do further processing, since it outputs
|
||||
// capital letter anyway.
|
||||
NSString *popedText = [inputText lowercaseString];
|
||||
[client insertText:popedText replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
||||
return YES;
|
||||
}
|
||||
if (flags & NSNumericPadKeyMask) {
|
||||
if (keyCode != kLeftKeyCode && keyCode != kRightKeyCode && keyCode != kDownKeyCode && keyCode != kUpKeyCode && charCode != 32 && isprint(charCode)) {
|
||||
if ([_composingBuffer length]) [self commitComposition:client];
|
||||
NSString *popedText = [inputText lowercaseString];
|
||||
[client insertText:popedText replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
if ([_candidates count]) {
|
||||
if (charCode == 27) {
|
||||
gCurrentCandidateController.visible = NO;
|
||||
[_candidates removeAllObjects];
|
||||
|
@ -647,7 +586,85 @@ public:
|
|||
[self beep];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)inputText:(NSString*)inputText key:(NSInteger)keyCode modifiers:(NSUInteger)flags client:(id)client
|
||||
{
|
||||
NSRect textFrame = NSZeroRect;
|
||||
NSDictionary *attributes = nil;
|
||||
|
||||
bool composeReading = false;
|
||||
BOOL useVerticalMode = NO;
|
||||
|
||||
@try {
|
||||
attributes = [client attributesForCharacterIndex:0 lineHeightRectangle:&textFrame];
|
||||
useVerticalMode = [attributes objectForKey:@"IMKTextOrientation"] && [[attributes objectForKey:@"IMKTextOrientation"] integerValue] == 0;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
// exception may raise while using Twitter.app's search filed.
|
||||
}
|
||||
|
||||
NSInteger cursorForwardKey = useVerticalMode ? kDownKeyCode : kRightKeyCode;
|
||||
NSInteger cursorBackwardKey = useVerticalMode ? kUpKeyCode : kLeftKeyCode;
|
||||
NSInteger extraChooseCandidateKey = useVerticalMode ? kLeftKeyCode : kDownKeyCode;
|
||||
NSInteger absorbedArrowKey = useVerticalMode ? kRightKeyCode : kUpKeyCode;
|
||||
NSInteger verticalModeOnlyChooseCandidateKey = useVerticalMode ? absorbedArrowKey : 0;
|
||||
|
||||
// get the unicode character code
|
||||
UniChar charCode = [inputText length] ? [inputText characterAtIndex:0] : 0;
|
||||
|
||||
if ([[client bundleIdentifier] isEqualToString:@"com.apple.Terminal"] && [NSStringFromClass([client class]) isEqualToString:@"IPMDServerClientWrapper"]) {
|
||||
// special handling for com.apple.Terminal
|
||||
_currentDeferredClient = client;
|
||||
}
|
||||
|
||||
// if the inputText is empty, it's a function key combination, we ignore it
|
||||
if (![inputText length]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// if the composing buffer is empty and there's no reading, and there is some function key combination, we ignore it
|
||||
if (![_composingBuffer length] && _bpmfReadingBuffer->isEmpty() && ((flags & NSCommandKeyMask) || (flags & NSControlKeyMask) || (flags & NSAlternateKeyMask) || (flags & NSNumericPadKeyMask))) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
// Caps Lock processing : if Caps Lock is on, temporarily disable bopomofo.
|
||||
if (charCode == 8 || charCode == 13 || keyCode == absorbedArrowKey || keyCode == extraChooseCandidateKey || keyCode == cursorForwardKey || keyCode == cursorBackwardKey) {
|
||||
// do nothing if backspace is pressed -- we ignore the key
|
||||
}
|
||||
else if (flags & NSAlphaShiftKeyMask) {
|
||||
// process all possible combination, we hope.
|
||||
if ([_composingBuffer length]) {
|
||||
[self commitComposition:client];
|
||||
}
|
||||
|
||||
// first commit everything in the buffer.
|
||||
if (flags & NSShiftKeyMask) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// when shift is pressed, don't do further processing, since it outputs capital letter anyway.
|
||||
NSString *popedText = [inputText lowercaseString];
|
||||
[client insertText:popedText replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (flags & NSNumericPadKeyMask) {
|
||||
if (keyCode != kLeftKeyCode && keyCode != kRightKeyCode && keyCode != kDownKeyCode && keyCode != kUpKeyCode && charCode != 32 && isprint(charCode)) {
|
||||
if ([_composingBuffer length]) {
|
||||
[self commitComposition:client];
|
||||
}
|
||||
|
||||
NSString *popedText = [inputText lowercaseString];
|
||||
[client insertText:popedText replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have candidate, it means we need to pass the event to the candidate handler
|
||||
if ([_candidates count]) {
|
||||
return [self handleCandidateEventWithInputText:inputText charCode:charCode keyCode:keyCode];
|
||||
}
|
||||
|
||||
|
||||
|
@ -704,7 +721,7 @@ public:
|
|||
}
|
||||
|
||||
// keyCode 125 = Down, charCode 32 = Space
|
||||
if (_bpmfReadingBuffer->isEmpty() && [_composingBuffer length] > 0 && (keyCode == extraChooseCandidateKey || charCode == 32)) {
|
||||
if (_bpmfReadingBuffer->isEmpty() && [_composingBuffer length] > 0 && (keyCode == extraChooseCandidateKey || charCode == 32 || (useVerticalMode && (keyCode == verticalModeOnlyChooseCandidateKey)))) {
|
||||
if (charCode == 32) {
|
||||
// if the spacebar is NOT set to be a selection key
|
||||
if (![[NSUserDefaults standardUserDefaults] boolForKey:kChooseCandidateUsingSpaceKey]) {
|
||||
|
@ -728,13 +745,14 @@ public:
|
|||
|
||||
// Esc
|
||||
if (charCode == 27) {
|
||||
// if reading is not empty, we cancel the reading; Apple's built-in Zhuyin (and the erstwhile Hanin) has a default option that Esc "cancels" the current composed character and revert it to Bopomofo reading, in odds with the expectation of users from other platforms
|
||||
|
||||
if (_bpmfReadingBuffer->isEmpty()) {
|
||||
// no nee to beep since the event is deliberately triggered by user
|
||||
|
||||
if (![_composingBuffer length]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
//[self beep];
|
||||
//如果要按 ESC 的時候都已經知道要取消些啥,不必beep
|
||||
}
|
||||
else {
|
||||
_bpmfReadingBuffer->clear();
|
||||
|
@ -742,11 +760,9 @@ public:
|
|||
|
||||
[self updateClientComposingBuffer:client];
|
||||
return YES;
|
||||
//可能的行為包括 1. 取消組字, 把字吃掉 2. 取消 candidate 選擇, 恢復原來的
|
||||
//3. 取消組字,現出注音
|
||||
}
|
||||
|
||||
// The Right key, note we use keyCode here
|
||||
// handle cursor backward
|
||||
if (keyCode == cursorBackwardKey) {
|
||||
if (!_bpmfReadingBuffer->isEmpty()) {
|
||||
[self beep];
|
||||
|
@ -768,7 +784,7 @@ public:
|
|||
return YES;
|
||||
}
|
||||
|
||||
// The Left key, note we use keyCode here
|
||||
// handle cursor forward
|
||||
if (keyCode == cursorForwardKey) {
|
||||
if (!_bpmfReadingBuffer->isEmpty()) {
|
||||
[self beep];
|
||||
|
@ -831,6 +847,7 @@ public:
|
|||
return YES;
|
||||
}
|
||||
|
||||
// punctuation list
|
||||
if ((char)charCode == '`') {
|
||||
if (gLanguageModel.hasUnigramsForKey(string("_punctuation_list"))) {
|
||||
if (_bpmfReadingBuffer->isEmpty()) {
|
||||
|
@ -1110,7 +1127,13 @@ public:
|
|||
NSLog(@"%@", exception);
|
||||
}
|
||||
|
||||
if (useVerticalMode) {
|
||||
[gCurrentCandidateController setWindowTopLeftPoint:NSMakePoint(lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, lineHeightRect.origin.y - 4.0) bottomOutOfScreenAdjustmentHeight:lineHeightRect.size.height + 4.0];
|
||||
}
|
||||
else {
|
||||
[gCurrentCandidateController setWindowTopLeftPoint:NSMakePoint(lineHeightRect.origin.x, lineHeightRect.origin.y - 4.0) bottomOutOfScreenAdjustmentHeight:lineHeightRect.size.height + 4.0];
|
||||
}
|
||||
|
||||
gCurrentCandidateController.visible = YES;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue