SessionCtl // Cope with `%quick` candidates.
This commit is contained in:
parent
e771654a2f
commit
b0c2bfc54e
|
@ -84,6 +84,12 @@ extension SessionCtl: CtlCandidateDelegate {
|
||||||
let blankResult: [String] = []
|
let blankResult: [String] = []
|
||||||
// 這一段專門處理「反查」。
|
// 這一段專門處理「反查」。
|
||||||
if !PrefMgr.shared.showReverseLookupInCandidateUI { return blankResult }
|
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 isVerticalTyping { return blankResult } // 縱排輸入的場合,選字窗沒有足夠的空間顯示反查結果。
|
||||||
if value.isEmpty { return blankResult } // 空字串沒有需要反查的東西。
|
if value.isEmpty { return blankResult } // 空字串沒有需要反查的東西。
|
||||||
if value.contains("_") { return blankResult }
|
if value.contains("_") { return blankResult }
|
||||||
|
@ -92,7 +98,17 @@ extension SessionCtl: CtlCandidateDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
public var selectionKeys: String {
|
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)] {
|
public func candidatePairs(conv: Bool = false) -> [(keyArray: [String], value: String)] {
|
||||||
|
@ -114,6 +130,7 @@ extension SessionCtl: CtlCandidateDelegate {
|
||||||
|
|
||||||
public func candidatePairSelectionConfirmed(at index: Int) {
|
public func candidatePairSelectionConfirmed(at index: Int) {
|
||||||
guard let inputHandler = inputHandler else { return }
|
guard let inputHandler = inputHandler else { return }
|
||||||
|
guard state.isCandidateContainer else { return }
|
||||||
switch state.type {
|
switch state.type {
|
||||||
case .ofSymbolTable where (0 ..< state.node.members.count).contains(index):
|
case .ofSymbolTable where (0 ..< state.node.members.count).contains(index):
|
||||||
let node = state.node.members[index]
|
let node = state.node.members[index]
|
||||||
|
@ -124,12 +141,10 @@ extension SessionCtl: CtlCandidateDelegate {
|
||||||
}
|
}
|
||||||
case .ofCandidates where (0 ..< state.candidates.count).contains(index):
|
case .ofCandidates where (0 ..< state.candidates.count).contains(index):
|
||||||
let selectedValue = state.candidates[index]
|
let selectedValue = state.candidates[index]
|
||||||
if state.type == .ofCandidates {
|
inputHandler.consolidateNode(
|
||||||
inputHandler.consolidateNode(
|
candidate: selectedValue, respectCursorPushing: true,
|
||||||
candidate: selectedValue, respectCursorPushing: true,
|
preConsolidate: PrefMgr.shared.consolidateContextOnCandidateSelection
|
||||||
preConsolidate: PrefMgr.shared.consolidateContextOnCandidateSelection
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
var result: IMEStateProtocol = inputHandler.generateStateOfInputting()
|
var result: IMEStateProtocol = inputHandler.generateStateOfInputting()
|
||||||
defer { switchState(result) } // 這是最終輸出結果。
|
defer { switchState(result) } // 這是最終輸出結果。
|
||||||
if PrefMgr.shared.useSCPCTypingMode {
|
if PrefMgr.shared.useSCPCTypingMode {
|
||||||
|
@ -157,6 +172,14 @@ extension SessionCtl: CtlCandidateDelegate {
|
||||||
withPair: .init(keyArray: selectedValue.keyArray, value: valueKept)
|
withPair: .init(keyArray: selectedValue.keyArray, value: valueKept)
|
||||||
)
|
)
|
||||||
if !associates.candidates.isEmpty { result = associates }
|
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
|
default: return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,35 +84,33 @@ public extension SessionCtl {
|
||||||
? .vertical
|
? .vertical
|
||||||
: .horizontal)
|
: .horizontal)
|
||||||
|
|
||||||
|
let isInputtingWithCandidates = state.type == .ofInputting && state.isCandidateContainer
|
||||||
/// 先取消既有的選字窗的內容顯示。否則可能會重複生成選字窗的 NSWindow()。
|
/// 先取消既有的選字窗的內容顯示。否則可能會重複生成選字窗的 NSWindow()。
|
||||||
candidateUI?.visible = false
|
candidateUI?.visible = false
|
||||||
/// 然後再重新初期化。
|
|
||||||
if #available(macOS 10.13, *) {
|
if #available(macOS 10.13, *) {
|
||||||
candidateUI =
|
/// 然後再重新初期化。
|
||||||
PrefMgr.shared.useIMKCandidateWindow
|
let useIMK = PrefMgr.shared.useIMKCandidateWindow
|
||||||
? CtlCandidateIMK(candidateLayout) : CtlCandidateTDK(candidateLayout)
|
candidateUI = useIMK ? CtlCandidateIMK(candidateLayout) : CtlCandidateTDK(candidateLayout)
|
||||||
if let candidateTDK = candidateUI as? CtlCandidateTDK {
|
|
||||||
let singleLine = isVerticalTyping || PrefMgr.shared.candidateWindowShowOnlyOneLine
|
|
||||||
candidateTDK.maxLinesPerPage = singleLine ? 1 : 4
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
candidateUI = CtlCandidateTDK(candidateLayout)
|
candidateUI = CtlCandidateTDK(candidateLayout)
|
||||||
}
|
}
|
||||||
|
var singleLine = isVerticalTyping || PrefMgr.shared.candidateWindowShowOnlyOneLine
|
||||||
|
singleLine = singleLine || isInputtingWithCandidates
|
||||||
|
(candidateUI as? CtlCandidateTDK)?.maxLinesPerPage = singleLine ? 1 : 4
|
||||||
|
|
||||||
candidateUI?.candidateFont = Self.candidateFont(
|
candidateUI?.candidateFont = Self.candidateFont(
|
||||||
name: PrefMgr.shared.candidateTextFontName, size: PrefMgr.shared.candidateListTextSize
|
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 {
|
if state.type == .ofAssociates {
|
||||||
candidateUI?.tooltip =
|
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 = {
|
candidateUI?.locale = {
|
||||||
|
|
|
@ -75,6 +75,7 @@ public extension SessionCtl {
|
||||||
setInlineDisplayWithCursor()
|
setInlineDisplayWithCursor()
|
||||||
// 會在工具提示為空的時候自動消除顯示。
|
// 會在工具提示為空的時候自動消除顯示。
|
||||||
showTooltip(newState.tooltip, duration: newState.tooltipDuration)
|
showTooltip(newState.tooltip, duration: newState.tooltipDuration)
|
||||||
|
if newState.isCandidateContainer { showCandidates() }
|
||||||
case .ofMarking:
|
case .ofMarking:
|
||||||
candidateUI?.visible = false
|
candidateUI?.visible = false
|
||||||
setInlineDisplayWithCursor()
|
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: "⇧")
|
handleIMKCandidatesPrepared(state.candidates, prefix: "⇧")
|
||||||
} else if state.type == .ofSymbolTable {
|
case .ofInputting where state.isCandidateContainer:
|
||||||
// 分類符號選單不會出現同符異音項、不需要康熙 / JIS 轉換,所以使用簡化過的處理方式。
|
handleIMKCandidatesPrepared(state.candidates, prefix: "🗲")
|
||||||
arrResult = state.candidates.map(\.value)
|
case .ofCandidates:
|
||||||
} else if state.type == .ofCandidates {
|
|
||||||
guard !state.candidates.isEmpty else { return .init() }
|
guard !state.candidates.isEmpty else { return .init() }
|
||||||
if state.candidates[0].keyArray.joined(separator: "-").contains("_punctuation") {
|
if state.candidates[0].keyArray.joined(separator: "-").contains("_punctuation") {
|
||||||
arrResult = state.candidates.map(\.value) // 標點符號選單處理。
|
arrResult = state.candidates.map(\.value) // 標點符號選單處理。
|
||||||
} else {
|
} else {
|
||||||
handleIMKCandidatesPrepared(state.candidates)
|
handleIMKCandidatesPrepared(state.candidates)
|
||||||
}
|
}
|
||||||
|
case .ofSymbolTable:
|
||||||
|
// 分類符號選單不會出現同符異音項、不需要康熙 / JIS 轉換,所以使用簡化過的處理方式。
|
||||||
|
arrResult = state.candidates.map(\.value)
|
||||||
|
default: break
|
||||||
}
|
}
|
||||||
|
|
||||||
return arrResult
|
return arrResult
|
||||||
|
@ -113,17 +118,21 @@ public extension SessionCtl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.type == .ofAssociates {
|
switch state.type {
|
||||||
|
case .ofAssociates:
|
||||||
fixIndexForIMKCandidates(&indexDeducted, prefix: "⇧", source: candidateString)
|
fixIndexForIMKCandidates(&indexDeducted, prefix: "⇧", source: candidateString)
|
||||||
} else if state.type == .ofSymbolTable {
|
case .ofInputting where state.isCandidateContainer:
|
||||||
|
fixIndexForIMKCandidates(&indexDeducted, prefix: "🗲", source: candidateString)
|
||||||
|
case .ofSymbolTable:
|
||||||
fixSymbolIndexForIMKCandidates()
|
fixSymbolIndexForIMKCandidates()
|
||||||
} else if state.type == .ofCandidates {
|
case .ofCandidates:
|
||||||
guard !state.candidates.isEmpty else { return }
|
guard !state.candidates.isEmpty else { return }
|
||||||
if state.candidates[0].keyArray.description.contains("_punctuation") {
|
if state.candidates[0].keyArray.description.contains("_punctuation") {
|
||||||
fixSymbolIndexForIMKCandidates() // 標點符號選單處理。
|
fixSymbolIndexForIMKCandidates() // 標點符號選單處理。
|
||||||
} else {
|
} else {
|
||||||
fixIndexForIMKCandidates(&indexDeducted, source: candidateString)
|
fixIndexForIMKCandidates(&indexDeducted, source: candidateString)
|
||||||
}
|
}
|
||||||
|
default: break
|
||||||
}
|
}
|
||||||
candidatePairSelectionConfirmed(at: indexDeducted)
|
candidatePairSelectionConfirmed(at: indexDeducted)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"vChewing" = "vChewing";
|
"vChewing" = "vChewing";
|
||||||
|
"Quick Candidates" = "Quick Candidates";
|
||||||
"Alvin Liu (Imitative)" = "Alvin Liu (Imitative)";
|
"Alvin Liu (Imitative)" = "Alvin Liu (Imitative)";
|
||||||
"Previous intonation has been overridden." = "Previous intonation has been overridden.";
|
"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.";
|
"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";
|
"vChewing" = "vChewing";
|
||||||
|
"Quick Candidates" = "Quick Candidates";
|
||||||
"Alvin Liu (Imitative)" = "Alvin Liu (Imitative)";
|
"Alvin Liu (Imitative)" = "Alvin Liu (Imitative)";
|
||||||
"Previous intonation has been overridden." = "Previous intonation has been overridden.";
|
"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.";
|
"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" = "早速候補";
|
||||||
"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" = "快速候选";
|
||||||
"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" = "快速候選";
|
||||||
"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." = "該聲調亦會嘗試與接下來輸入的注音相組合。";
|
||||||
|
|
Loading…
Reference in New Issue