KeyHandler // Swiftify: day 3.
This commit is contained in:
parent
ab8ed8f73c
commit
c171d1487a
|
@ -50,7 +50,8 @@ extern InputMode imeModeNULL;
|
|||
- (BOOL)handleInput:(keyParser *)input
|
||||
state:(InputState *)state
|
||||
stateCallback:(void (^)(InputState *))stateCallback
|
||||
errorCallback:(void (^)(void))errorCallback NS_SWIFT_NAME(handle(input:state:stateCallback:errorCallback:));
|
||||
errorCallback:(void (^)(void))errorCallback
|
||||
NS_SWIFT_NAME(handle(input:state:stateCallback:errorCallback:));
|
||||
|
||||
- (void)fixNodeWithValue:(NSString *)value NS_SWIFT_NAME(fixNode(value:));
|
||||
- (void)clear;
|
||||
|
@ -69,11 +70,6 @@ extern InputMode imeModeNULL;
|
|||
stateCallback:(void (^)(InputState *))stateCallback
|
||||
errorCallback:(void (^)(void))errorCallback
|
||||
NS_SWIFT_NAME(handleCandidate(state:input:stateCallback:errorCallback:));
|
||||
- (BOOL)_handleMarkingState:(InputState *)state
|
||||
input:(keyParser *)input
|
||||
stateCallback:(void (^)(InputState *))stateCallback
|
||||
errorCallback:(void (^)(void))errorCallback
|
||||
NS_SWIFT_NAME(handleMarking(state:input:stateCallback:errorCallback:));
|
||||
|
||||
- (BOOL)checkWhetherToneMarkerConfirmsPhoneticReadingBuffer;
|
||||
- (BOOL)chkKeyValidity:(UniChar)value;
|
||||
|
|
|
@ -994,94 +994,6 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_handleMarkingState:(InputStateMarking *)state
|
||||
input:(keyParser *)input
|
||||
stateCallback:(void (^)(InputState *))stateCallback
|
||||
errorCallback:(void (^)(void))errorCallback
|
||||
{
|
||||
|
||||
if ([input isESC])
|
||||
{
|
||||
InputStateInputting *inputting = (InputStateInputting *)[self buildInputtingState];
|
||||
stateCallback(inputting);
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Enter
|
||||
if ([input isEnter])
|
||||
{
|
||||
if (![self.delegate keyHandler:self didRequestWriteUserPhraseWithState:state])
|
||||
{
|
||||
[IME prtDebugIntel:@"5B69CC8D"];
|
||||
errorCallback();
|
||||
return YES;
|
||||
}
|
||||
InputStateInputting *inputting = (InputStateInputting *)[self buildInputtingState];
|
||||
stateCallback(inputting);
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Shift + left
|
||||
if (([input isCursorBackward] || input.emacsKey == vChewingEmacsKeyBackward) && ([input isShiftHold]))
|
||||
{
|
||||
NSUInteger index = state.markerIndex;
|
||||
if (index > 0)
|
||||
{
|
||||
index = [state.composingBuffer previousUtf16PositionFor:index];
|
||||
InputStateMarking *marking = [[InputStateMarking alloc] initWithComposingBuffer:state.composingBuffer
|
||||
cursorIndex:state.cursorIndex
|
||||
markerIndex:index
|
||||
readings:state.readings];
|
||||
marking.tooltipForInputting = state.tooltipForInputting;
|
||||
|
||||
if (marking.markedRange.length == 0)
|
||||
{
|
||||
InputState *inputting = [marking convertToInputting];
|
||||
stateCallback(inputting);
|
||||
}
|
||||
else
|
||||
stateCallback(marking);
|
||||
}
|
||||
else
|
||||
{
|
||||
[IME prtDebugIntel:@"1149908D"];
|
||||
errorCallback();
|
||||
stateCallback(state);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Shift + Right
|
||||
if (([input isCursorForward] || input.emacsKey == vChewingEmacsKeyForward) && ([input isShiftHold]))
|
||||
{
|
||||
NSUInteger index = state.markerIndex;
|
||||
if (index < state.composingBuffer.length)
|
||||
{
|
||||
index = [state.composingBuffer nextUtf16PositionFor:index];
|
||||
InputStateMarking *marking = [[InputStateMarking alloc] initWithComposingBuffer:state.composingBuffer
|
||||
cursorIndex:state.cursorIndex
|
||||
markerIndex:index
|
||||
readings:state.readings];
|
||||
marking.tooltipForInputting = state.tooltipForInputting;
|
||||
if (marking.markedRange.length == 0)
|
||||
{
|
||||
InputState *inputting = [marking convertToInputting];
|
||||
stateCallback(inputting);
|
||||
}
|
||||
else
|
||||
stateCallback(marking);
|
||||
}
|
||||
else
|
||||
{
|
||||
[IME prtDebugIntel:@"9B51408D"];
|
||||
errorCallback();
|
||||
stateCallback(state);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)_handleCandidateState:(InputState *)state
|
||||
input:(keyParser *)input
|
||||
stateCallback:(void (^)(InputState *))stateCallback
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
||||
// All possible vChewing-specific modifications are of:
|
||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
// Refactored from the ObjCpp-version of this class by:
|
||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
import Cocoa
|
||||
|
||||
// MARK: - § Handle Inputs (WIP).
|
||||
@objc extension KeyHandler {
|
||||
func handleInputSwift(
|
||||
input: keyParser,
|
||||
|
@ -35,7 +36,6 @@ import Cocoa
|
|||
) -> Bool {
|
||||
let charCode: UniChar = input.charCode
|
||||
var state = inState // Turn this incoming constant to variable.
|
||||
let emacsKey: vChewingEmacsKey = input.emacsKey
|
||||
let inputText: String = input.inputText ?? ""
|
||||
let emptyState = InputState.Empty()
|
||||
|
||||
|
@ -54,7 +54,7 @@ import Cocoa
|
|||
return false
|
||||
}
|
||||
|
||||
// MARK: - Caps Lock processing.
|
||||
// MARK: Caps Lock processing.
|
||||
// If Caps Lock is ON, temporarily disable bopomofo.
|
||||
// Note: Alphanumerical mode processing.
|
||||
if input.isBackSpace || input.isEnter || input.isAbsorbedArrowKey || input.isExtraChooseCandidateKey
|
||||
|
@ -86,7 +86,7 @@ import Cocoa
|
|||
return true
|
||||
}
|
||||
|
||||
// MARK: - Numeric Pad Processing.
|
||||
// MARK: Numeric Pad Processing.
|
||||
if input.isNumericPad {
|
||||
if !input.isLeft && !input.isRight && !input.isDown
|
||||
&& !input.isUp && !input.isSpace && isPrintable(charCode)
|
||||
|
@ -100,13 +100,13 @@ import Cocoa
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Handle Candidates.
|
||||
// MARK: Handle Candidates.
|
||||
if state is InputState.ChoosingCandidate {
|
||||
return handleCandidate(
|
||||
state: state, input: input, stateCallback: stateCallback, errorCallback: errorCallback)
|
||||
}
|
||||
|
||||
// MARK: - Handle Associated Phrases.
|
||||
// MARK: Handle Associated Phrases.
|
||||
if state is InputState.AssociatedPhrases {
|
||||
let result = handleCandidate(
|
||||
state: state, input: input, stateCallback: stateCallback, errorCallback: errorCallback)
|
||||
|
@ -117,12 +117,12 @@ import Cocoa
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Handle Marking.
|
||||
// MARK: Handle Marking.
|
||||
if state is InputState.Marking {
|
||||
let marking = state as! InputState.Marking
|
||||
|
||||
if handleMarking(
|
||||
state: state as! InputState.Marking, input: input, stateCallback: stateCallback,
|
||||
if _handleMarkingState(
|
||||
state as! InputState.Marking, input: input, stateCallback: stateCallback,
|
||||
errorCallback: errorCallback)
|
||||
{
|
||||
return true
|
||||
|
@ -132,7 +132,7 @@ import Cocoa
|
|||
stateCallback(state)
|
||||
}
|
||||
|
||||
// MARK: - Handle BPMF Keys.
|
||||
// MARK: Handle BPMF Keys.
|
||||
var composeReading: Bool = false
|
||||
let skipPhoneticHandling = input.isReservedKey || input.isControlHold || input.isOptionHold
|
||||
|
||||
|
@ -154,7 +154,7 @@ import Cocoa
|
|||
|
||||
// See if we have composition if Enter/Space is hit and buffer is not empty.
|
||||
// We use "|=" conditioning so that the tone marker key is also taken into account.
|
||||
// However, Swift does not support "|=".
|
||||
// However, Swift does not support "|=".
|
||||
composeReading = composeReading || (!isPhoneticReadingBufferEmpty() && (input.isSpace || input.isEnter))
|
||||
if composeReading {
|
||||
let reading = getSyllableCompositionFromPhoneticReadingBuffer()
|
||||
|
@ -189,7 +189,7 @@ import Cocoa
|
|||
useVerticalMode: input.useVerticalMode)
|
||||
if choosingCandidates.candidates.count == 1 {
|
||||
clear()
|
||||
let text: String = choosingCandidates.candidates.first ?? ""
|
||||
let text: String = choosingCandidates.candidates.first ?? ""
|
||||
let committing = InputState.Committing(poppedText: text)
|
||||
stateCallback(committing)
|
||||
|
||||
|
@ -213,7 +213,7 @@ import Cocoa
|
|||
return true
|
||||
}
|
||||
|
||||
// MARK: - Calling candidate window using Space or Down or PageUp / PageDn.
|
||||
// MARK: Calling candidate window using Space or Down or PageUp / PageDn.
|
||||
|
||||
if isPhoneticReadingBufferEmpty() && (state is InputState.NotEmpty)
|
||||
&& (input.isExtraChooseCandidateKey || input.isExtraChooseCandidateKeyReverse || input.isSpace
|
||||
|
@ -224,8 +224,8 @@ import Cocoa
|
|||
// If the spacebar is NOT set to be a selection key
|
||||
if input.isShiftHold || !mgrPrefs.chooseCandidateUsingSpace {
|
||||
if getBuilderCursorIndex() >= getBuilderLength() {
|
||||
let composingBuffer = (state as! InputState.NotEmpty).composingBuffer
|
||||
if (composingBuffer.count) != 0 {
|
||||
let composingBuffer = (state as! InputState.NotEmpty).composingBuffer
|
||||
if (composingBuffer.count) != 0 {
|
||||
let committing = InputState.Committing(poppedText: composingBuffer)
|
||||
stateCallback(committing)
|
||||
}
|
||||
|
@ -251,14 +251,14 @@ import Cocoa
|
|||
return true
|
||||
}
|
||||
|
||||
// MARK: - Function Keys.
|
||||
// MARK: Function Keys.
|
||||
|
||||
// MARK: Esc
|
||||
|
||||
// MARK: - Still Nothing.
|
||||
// MARK: Still Nothing.
|
||||
// Still nothing? Then we update the composing buffer.
|
||||
// Note that some app has strange behavior if we don't do this,
|
||||
// "thinking" that the key is not actually consumed).
|
||||
// "thinking" that the key is not actually consumed.
|
||||
// 砍掉這一段會導致「F1-F12 按鍵干擾組字區」的問題。
|
||||
// 暫時只能先恢復這段,且補上偵錯彙報機制,方便今後排查故障。
|
||||
if (state is InputState.NotEmpty) || !isPhoneticReadingBufferEmpty() {
|
||||
|
@ -273,21 +273,3 @@ import Cocoa
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - State managements.
|
||||
@objc extension KeyHandler {
|
||||
func _buildCandidateState(
|
||||
_ currentState: InputState.NotEmpty,
|
||||
useVerticalMode: Bool
|
||||
) -> InputState.ChoosingCandidate {
|
||||
let candidatesArray = getCandidatesArray()
|
||||
|
||||
let state = InputState.ChoosingCandidate(
|
||||
composingBuffer: currentState.composingBuffer,
|
||||
cursorIndex: currentState.cursorIndex,
|
||||
candidates: candidatesArray as! [String],
|
||||
useVerticalMode: useVerticalMode)
|
||||
return state
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
// Refactored from the ObjCpp-version of this class by:
|
||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
1. The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
2. No trademark license is granted to use the trade names, trademarks, service
|
||||
marks, or product names of Contributor, except as required to fulfill notice
|
||||
requirements above.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Cocoa
|
||||
|
||||
// MARK: - § State managements.
|
||||
@objc extension KeyHandler {
|
||||
|
||||
// MARK: 用以生成候選詞數組
|
||||
func _buildCandidateState(
|
||||
_ currentState: InputState.NotEmpty,
|
||||
useVerticalMode: Bool
|
||||
) -> InputState.ChoosingCandidate {
|
||||
let candidatesArray = getCandidatesArray()
|
||||
|
||||
let state = InputState.ChoosingCandidate(
|
||||
composingBuffer: currentState.composingBuffer,
|
||||
cursorIndex: currentState.cursorIndex,
|
||||
candidates: candidatesArray as! [String],
|
||||
useVerticalMode: useVerticalMode)
|
||||
return state
|
||||
}
|
||||
|
||||
// MARK: 用以處理就地新增自訂語彙時的行為
|
||||
func _handleMarkingState(
|
||||
_ state: InputState.Marking,
|
||||
input: keyParser,
|
||||
stateCallback: @escaping (InputState) -> Void,
|
||||
errorCallback: @escaping () -> Void
|
||||
) -> Bool {
|
||||
|
||||
if input.isESC {
|
||||
let inputting = buildInputtingState() as! InputState.Inputting
|
||||
stateCallback(inputting)
|
||||
return true
|
||||
}
|
||||
|
||||
// Enter
|
||||
if input.isEnter {
|
||||
if let keyHandlerDelegate = delegate {
|
||||
if !keyHandlerDelegate.keyHandler(self, didRequestWriteUserPhraseWith: state) {
|
||||
IME.prtDebugIntel("5B69CC8D")
|
||||
errorCallback()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
let inputting = buildInputtingState() as! InputState.Inputting
|
||||
stateCallback(inputting)
|
||||
return true
|
||||
}
|
||||
|
||||
// Shift + Left
|
||||
if (input.isCursorBackward || input.emacsKey == vChewingEmacsKey.backward) && (input.isShiftHold) {
|
||||
var index = state.markerIndex
|
||||
if index > 0 {
|
||||
index = UInt((state.composingBuffer as NSString).previousUtf16Position(for: Int(index)))
|
||||
let marking = InputState.Marking(
|
||||
composingBuffer: state.composingBuffer,
|
||||
cursorIndex: state.cursorIndex,
|
||||
markerIndex: index,
|
||||
readings: state.readings)
|
||||
marking.tooltipForInputting = state.tooltipForInputting
|
||||
|
||||
if marking.markedRange.length == 0 {
|
||||
let inputting = marking.convertToInputting()
|
||||
stateCallback(inputting)
|
||||
} else {
|
||||
stateCallback(marking)
|
||||
}
|
||||
} else {
|
||||
IME.prtDebugIntel("1149908D")
|
||||
errorCallback()
|
||||
stateCallback(state)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Shift + Right
|
||||
if (input.isCursorForward || input.emacsKey == vChewingEmacsKey.forward) && (input.isShiftHold) {
|
||||
var index = state.markerIndex
|
||||
// 這裡繼續用 NSString 是為了與 Zonble 之前引入的 NSStringUtils 相容。
|
||||
// 不然的話,這行判斷會失敗、引發「9B51408D」錯誤。
|
||||
if index < ((state.composingBuffer as NSString).length) {
|
||||
index = UInt((state.composingBuffer as NSString).nextUtf16Position(for: Int(index)))
|
||||
let marking = InputState.Marking(
|
||||
composingBuffer: state.composingBuffer,
|
||||
cursorIndex: state.cursorIndex,
|
||||
markerIndex: index,
|
||||
readings: state.readings)
|
||||
marking.tooltipForInputting = state.tooltipForInputting
|
||||
if marking.markedRange.length == 0 {
|
||||
let inputting = marking.convertToInputting()
|
||||
stateCallback(inputting)
|
||||
} else {
|
||||
stateCallback(marking)
|
||||
}
|
||||
} else {
|
||||
IME.prtDebugIntel("9B51408D")
|
||||
errorCallback()
|
||||
stateCallback(state)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
5B27AD6B27CB1F9B000ED75B /* data-zhuyinwen.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B27AD6927CB1F9B000ED75B /* data-zhuyinwen.txt */; };
|
||||
5B2DB16F27AF6891006D874E /* data-chs.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16D27AF6891006D874E /* data-chs.txt */; };
|
||||
5B2DB17027AF6891006D874E /* data-cht.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16E27AF6891006D874E /* data-cht.txt */; };
|
||||
5B3133BF280B229700A4A505 /* KeyHandler_States.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3133BE280B229700A4A505 /* KeyHandler_States.swift */; };
|
||||
5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; };
|
||||
5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */; };
|
||||
5B62A32F27AE78B000A19448 /* CoreLM.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A32D27AE78B000A19448 /* CoreLM.mm */; };
|
||||
|
@ -186,6 +187,7 @@
|
|||
5B2DB16E27AF6891006D874E /* data-cht.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "data-cht.txt"; path = "Data/data-cht.txt"; sourceTree = "<group>"; };
|
||||
5B2DB17127AF8771006D874E /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Data/Makefile; sourceTree = "<group>"; };
|
||||
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = "<group>"; };
|
||||
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyHandler_States.swift; sourceTree = "<group>"; };
|
||||
5B5E535127EF261400C6AA1E /* IME.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IME.swift; sourceTree = "<group>"; };
|
||||
5B62A32627AE77BB00A19448 /* LMConsolidator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LMConsolidator.h; sourceTree = "<group>"; };
|
||||
5B62A32727AE77BB00A19448 /* LMConsolidator.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LMConsolidator.mm; sourceTree = "<group>"; };
|
||||
|
@ -426,6 +428,7 @@
|
|||
D4E569DA27A34CC100AC2CEF /* KeyHandler.h */,
|
||||
D4E569DB27A34CC100AC2CEF /* KeyHandler.mm */,
|
||||
5B7F225C2808501000DDD3CB /* KeyHandler.swift */,
|
||||
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */,
|
||||
D456576D279E4F7B00DF6BC9 /* KeyParser.swift */,
|
||||
6ACC3D3E27914F2400F1B140 /* KeyValueBlobReader.cpp */,
|
||||
6ACC3D3C27914AAB00F1B140 /* KeyValueBlobReader.h */,
|
||||
|
@ -1080,6 +1083,7 @@
|
|||
5BE78BE027B38804005EA1BE /* LMConsolidator.mm in Sources */,
|
||||
D456576E279E4F7B00DF6BC9 /* KeyParser.swift in Sources */,
|
||||
5BA9FD1027FEDB6B002DE248 /* suiPrefPaneKeyboard.swift in Sources */,
|
||||
5B3133BF280B229700A4A505 /* KeyHandler_States.swift in Sources */,
|
||||
5BA9FD4327FEF3C8002DE248 /* Preferences.swift in Sources */,
|
||||
5BA9FD4427FEF3C8002DE248 /* SegmentedControlStyleViewController.swift in Sources */,
|
||||
D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue