SessionCtl // Cope with `%quick` candidates.
This commit is contained in:
parent
e771654a2f
commit
b0c2bfc54e
|
@ -84,6 +84,12 @@ extension SessionCtl: CtlCandidateDelegate {
|
|||
let blankResult: [String] = []
|
||||
// 這一段專門處理「反查」。
|
||||
if !PrefMgr.shared.showReverseLookupInCandidateUI { return blankResult }
|
||||
if state.type == .ofInputting, state.isCandidateContainer,
|
||||
inputHandler?.currentLM.nullCandidateInCassette == value
|
||||
{
|
||||
return blankResult
|
||||
}
|
||||
if !PrefMgr.shared.showReverseLookupInCandidateUI { return blankResult }
|
||||
if isVerticalTyping { return blankResult } // 縱排輸入的場合,選字窗沒有足夠的空間顯示反查結果。
|
||||
if value.isEmpty { return blankResult } // 空字串沒有需要反查的東西。
|
||||
if value.contains("_") { return blankResult }
|
||||
|
@ -92,7 +98,17 @@ extension SessionCtl: CtlCandidateDelegate {
|
|||
}
|
||||
|
||||
public var selectionKeys: String {
|
||||
PrefMgr.shared.useIMKCandidateWindow ? "123456789" : PrefMgr.shared.candidateKeys
|
||||
// `%quick` 模式僅支援 1234567890 選字鍵。
|
||||
if state.type == .ofInputting, state.isCandidateContainer {
|
||||
guard let cinCandidateKey = LMMgr.currentLM.cassetteSelectionKey,
|
||||
CandidateKey.validate(keys: cinCandidateKey) == nil
|
||||
else {
|
||||
return "1234567890"
|
||||
}
|
||||
return cinCandidateKey
|
||||
}
|
||||
if PrefMgr.shared.useIMKCandidateWindow { return "123456789" }
|
||||
return PrefMgr.shared.candidateKeys
|
||||
}
|
||||
|
||||
public func candidatePairs(conv: Bool = false) -> [(keyArray: [String], value: String)] {
|
||||
|
@ -114,6 +130,7 @@ extension SessionCtl: CtlCandidateDelegate {
|
|||
|
||||
public func candidatePairSelectionConfirmed(at index: Int) {
|
||||
guard let inputHandler = inputHandler else { return }
|
||||
guard state.isCandidateContainer else { return }
|
||||
switch state.type {
|
||||
case .ofSymbolTable where (0 ..< state.node.members.count).contains(index):
|
||||
let node = state.node.members[index]
|
||||
|
@ -124,12 +141,10 @@ extension SessionCtl: CtlCandidateDelegate {
|
|||
}
|
||||
case .ofCandidates where (0 ..< state.candidates.count).contains(index):
|
||||
let selectedValue = state.candidates[index]
|
||||
if state.type == .ofCandidates {
|
||||
inputHandler.consolidateNode(
|
||||
candidate: selectedValue, respectCursorPushing: true,
|
||||
preConsolidate: PrefMgr.shared.consolidateContextOnCandidateSelection
|
||||
)
|
||||
}
|
||||
inputHandler.consolidateNode(
|
||||
candidate: selectedValue, respectCursorPushing: true,
|
||||
preConsolidate: PrefMgr.shared.consolidateContextOnCandidateSelection
|
||||
)
|
||||
var result: IMEStateProtocol = inputHandler.generateStateOfInputting()
|
||||
defer { switchState(result) } // 這是最終輸出結果。
|
||||
if PrefMgr.shared.useSCPCTypingMode {
|
||||
|
@ -157,6 +172,14 @@ extension SessionCtl: CtlCandidateDelegate {
|
|||
withPair: .init(keyArray: selectedValue.keyArray, value: valueKept)
|
||||
)
|
||||
if !associates.candidates.isEmpty { result = associates }
|
||||
case .ofInputting where (0 ..< state.candidates.count).contains(index):
|
||||
let chosenStr = state.candidates[index].value
|
||||
guard !chosenStr.isEmpty, chosenStr != inputHandler.currentLM.nullCandidateInCassette else {
|
||||
callError("907F9F64")
|
||||
return
|
||||
}
|
||||
let strToCommitFirst = inputHandler.generateStateOfInputting(sansReading: true).displayedText
|
||||
switchState(IMEState.ofCommitting(textToCommit: strToCommitFirst + chosenStr))
|
||||
default: return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,35 +84,33 @@ public extension SessionCtl {
|
|||
? .vertical
|
||||
: .horizontal)
|
||||
|
||||
let isInputtingWithCandidates = state.type == .ofInputting && state.isCandidateContainer
|
||||
/// 先取消既有的選字窗的內容顯示。否則可能會重複生成選字窗的 NSWindow()。
|
||||
candidateUI?.visible = false
|
||||
/// 然後再重新初期化。
|
||||
if #available(macOS 10.13, *) {
|
||||
candidateUI =
|
||||
PrefMgr.shared.useIMKCandidateWindow
|
||||
? CtlCandidateIMK(candidateLayout) : CtlCandidateTDK(candidateLayout)
|
||||
if let candidateTDK = candidateUI as? CtlCandidateTDK {
|
||||
let singleLine = isVerticalTyping || PrefMgr.shared.candidateWindowShowOnlyOneLine
|
||||
candidateTDK.maxLinesPerPage = singleLine ? 1 : 4
|
||||
}
|
||||
/// 然後再重新初期化。
|
||||
let useIMK = PrefMgr.shared.useIMKCandidateWindow
|
||||
candidateUI = useIMK ? CtlCandidateIMK(candidateLayout) : CtlCandidateTDK(candidateLayout)
|
||||
} else {
|
||||
candidateUI = CtlCandidateTDK(candidateLayout)
|
||||
}
|
||||
var singleLine = isVerticalTyping || PrefMgr.shared.candidateWindowShowOnlyOneLine
|
||||
singleLine = singleLine || isInputtingWithCandidates
|
||||
(candidateUI as? CtlCandidateTDK)?.maxLinesPerPage = singleLine ? 1 : 4
|
||||
|
||||
candidateUI?.candidateFont = Self.candidateFont(
|
||||
name: PrefMgr.shared.candidateTextFontName, size: PrefMgr.shared.candidateListTextSize
|
||||
)
|
||||
|
||||
let singleColumn = isVerticalTyping || PrefMgr.shared.candidateWindowShowOnlyOneLine
|
||||
|
||||
if PrefMgr.shared.cassetteEnabled {
|
||||
candidateUI?.tooltip =
|
||||
singleColumn ? "📼" : "📼 " + NSLocalizedString("CIN Cassette Mode", comment: "")
|
||||
}
|
||||
|
||||
if state.type == .ofAssociates {
|
||||
candidateUI?.tooltip =
|
||||
singleColumn ? "⇧" : NSLocalizedString("Hold ⇧ to choose associates.", comment: "")
|
||||
singleLine ? "⇧" : NSLocalizedString("Hold ⇧ to choose associates.", comment: "")
|
||||
} else if state.type == .ofInputting, state.isCandidateContainer {
|
||||
candidateUI?.tooltip =
|
||||
singleLine ? "⚡️" : "⚡️ " + NSLocalizedString("Quick Candidates", comment: "")
|
||||
} else if PrefMgr.shared.cassetteEnabled {
|
||||
candidateUI?.tooltip =
|
||||
singleLine ? "📼" : "📼 " + NSLocalizedString("CIN Cassette Mode", comment: "")
|
||||
}
|
||||
|
||||
candidateUI?.locale = {
|
||||
|
|
|
@ -75,6 +75,7 @@ public extension SessionCtl {
|
|||
setInlineDisplayWithCursor()
|
||||
// 會在工具提示為空的時候自動消除顯示。
|
||||
showTooltip(newState.tooltip, duration: newState.tooltipDuration)
|
||||
if newState.isCandidateContainer { showCandidates() }
|
||||
case .ofMarking:
|
||||
candidateUI?.visible = false
|
||||
setInlineDisplayWithCursor()
|
||||
|
|
|
@ -49,18 +49,23 @@ public extension SessionCtl {
|
|||
}
|
||||
}
|
||||
|
||||
if state.type == .ofAssociates {
|
||||
switch state.type {
|
||||
case .ofDeactivated, .ofEmpty, .ofAbortion, .ofCommitting, .ofMarking: break
|
||||
case .ofAssociates:
|
||||
handleIMKCandidatesPrepared(state.candidates, prefix: "⇧")
|
||||
} else if state.type == .ofSymbolTable {
|
||||
// 分類符號選單不會出現同符異音項、不需要康熙 / JIS 轉換,所以使用簡化過的處理方式。
|
||||
arrResult = state.candidates.map(\.value)
|
||||
} else if state.type == .ofCandidates {
|
||||
case .ofInputting where state.isCandidateContainer:
|
||||
handleIMKCandidatesPrepared(state.candidates, prefix: "🗲")
|
||||
case .ofCandidates:
|
||||
guard !state.candidates.isEmpty else { return .init() }
|
||||
if state.candidates[0].keyArray.joined(separator: "-").contains("_punctuation") {
|
||||
arrResult = state.candidates.map(\.value) // 標點符號選單處理。
|
||||
} else {
|
||||
handleIMKCandidatesPrepared(state.candidates)
|
||||
}
|
||||
case .ofSymbolTable:
|
||||
// 分類符號選單不會出現同符異音項、不需要康熙 / JIS 轉換,所以使用簡化過的處理方式。
|
||||
arrResult = state.candidates.map(\.value)
|
||||
default: break
|
||||
}
|
||||
|
||||
return arrResult
|
||||
|
@ -113,17 +118,21 @@ public extension SessionCtl {
|
|||
}
|
||||
}
|
||||
|
||||
if state.type == .ofAssociates {
|
||||
switch state.type {
|
||||
case .ofAssociates:
|
||||
fixIndexForIMKCandidates(&indexDeducted, prefix: "⇧", source: candidateString)
|
||||
} else if state.type == .ofSymbolTable {
|
||||
case .ofInputting where state.isCandidateContainer:
|
||||
fixIndexForIMKCandidates(&indexDeducted, prefix: "🗲", source: candidateString)
|
||||
case .ofSymbolTable:
|
||||
fixSymbolIndexForIMKCandidates()
|
||||
} else if state.type == .ofCandidates {
|
||||
case .ofCandidates:
|
||||
guard !state.candidates.isEmpty else { return }
|
||||
if state.candidates[0].keyArray.description.contains("_punctuation") {
|
||||
fixSymbolIndexForIMKCandidates() // 標點符號選單處理。
|
||||
} else {
|
||||
fixIndexForIMKCandidates(&indexDeducted, source: candidateString)
|
||||
}
|
||||
default: break
|
||||
}
|
||||
candidatePairSelectionConfirmed(at: indexDeducted)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"vChewing" = "vChewing";
|
||||
"Quick Candidates" = "Quick Candidates";
|
||||
"Alvin Liu (Imitative)" = "Alvin Liu (Imitative)";
|
||||
"Previous intonation has been overridden." = "Previous intonation has been overridden.";
|
||||
"It will attempt to combine with the incoming phonabet input." = "It will attempt to combine with the incoming phonabet input.";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"vChewing" = "vChewing";
|
||||
"Quick Candidates" = "Quick Candidates";
|
||||
"Alvin Liu (Imitative)" = "Alvin Liu (Imitative)";
|
||||
"Previous intonation has been overridden." = "Previous intonation has been overridden.";
|
||||
"It will attempt to combine with the incoming phonabet input." = "It will attempt to combine with the incoming phonabet input.";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"vChewing" = "威注音入力アプリ";
|
||||
"Quick Candidates" = "早速候補";
|
||||
"Alvin Liu (Imitative)" = "劉又銘擬音注音配列";
|
||||
"Previous intonation has been overridden." = "後ろ側の漢字の音調を書き直しました。";
|
||||
"It will attempt to combine with the incoming phonabet input." = "この音調は次の注音入力と組み合わす。";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"vChewing" = "威注音输入法";
|
||||
"Quick Candidates" = "快速候选";
|
||||
"Alvin Liu (Imitative)" = "刘又铭拟音注音排列";
|
||||
"Previous intonation has been overridden." = "已覆写游标身后的汉字的音调。";
|
||||
"It will attempt to combine with the incoming phonabet input." = "该声调亦会尝试与接下来输入的注音相组合。";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"vChewing" = "威注音輸入法";
|
||||
"Quick Candidates" = "快速候選";
|
||||
"Alvin Liu (Imitative)" = "劉又銘擬音注音排列";
|
||||
"Previous intonation has been overridden." = "已覆寫游標身後的漢字的音調。";
|
||||
"It will attempt to combine with the incoming phonabet input." = "該聲調亦會嘗試與接下來輸入的注音相組合。";
|
||||
|
|
Loading…
Reference in New Issue