Repo // Implementing reverse-lookup, requiring macOS 10.15 and later.
- Prefs & PrefUI // Add reverse-lookup toggle.
This commit is contained in:
parent
6e67a5edc8
commit
f94ecf5fda
|
@ -14,6 +14,7 @@ open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
|
||||||
open var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
open var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
||||||
open var locale: String = ""
|
open var locale: String = ""
|
||||||
open var useLangIdentifier: Bool = false
|
open var useLangIdentifier: Bool = false
|
||||||
|
open var reverseLookupResult: String = ""
|
||||||
|
|
||||||
open func highlightedColor() -> NSColor {
|
open func highlightedColor() -> NSColor {
|
||||||
var result = NSColor.alternateSelectedControlColor
|
var result = NSColor.alternateSelectedControlColor
|
||||||
|
|
|
@ -19,20 +19,32 @@ public class CtlCandidateTDK: CtlCandidate {
|
||||||
|
|
||||||
@available(macOS 12, *)
|
@available(macOS 12, *)
|
||||||
public var theViewHorizontal: VwrCandidateHorizontal {
|
public var theViewHorizontal: VwrCandidateHorizontal {
|
||||||
.init(controller: self, thePool: thePoolHorizontal, tooltip: tooltip)
|
.init(
|
||||||
|
controller: self, thePool: thePoolHorizontal,
|
||||||
|
tooltip: tooltip, reverseLookupResult: reverseLookupResult
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 12, *)
|
@available(macOS 12, *)
|
||||||
public var theViewVertical: VwrCandidateVertical {
|
public var theViewVertical: VwrCandidateVertical {
|
||||||
.init(controller: self, thePool: thePoolVertical, tooltip: tooltip)
|
.init(
|
||||||
|
controller: self, thePool: thePoolVertical,
|
||||||
|
tooltip: tooltip, reverseLookupResult: reverseLookupResult
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var theViewHorizontalBackports: VwrCandidateHorizontalBackports {
|
public var theViewHorizontalBackports: VwrCandidateHorizontalBackports {
|
||||||
.init(controller: self, thePool: thePoolHorizontal, tooltip: tooltip)
|
.init(
|
||||||
|
controller: self, thePool: thePoolHorizontal,
|
||||||
|
tooltip: tooltip, reverseLookupResult: reverseLookupResult
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var theViewVerticalBackports: VwrCandidateVerticalBackports {
|
public var theViewVerticalBackports: VwrCandidateVerticalBackports {
|
||||||
.init(controller: self, thePool: thePoolVertical, tooltip: tooltip)
|
.init(
|
||||||
|
controller: self, thePool: thePoolVertical,
|
||||||
|
tooltip: tooltip, reverseLookupResult: reverseLookupResult
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var thePool: CandidatePool {
|
public var thePool: CandidatePool {
|
||||||
|
@ -105,6 +117,7 @@ public class CtlCandidateTDK: CtlCandidate {
|
||||||
|
|
||||||
override open func updateDisplay() {
|
override open func updateDisplay() {
|
||||||
guard let window = window else { return }
|
guard let window = window else { return }
|
||||||
|
reverseLookupResult = delegate?.annotate(for: currentSelectedCandidateText) ?? ""
|
||||||
switch currentLayout {
|
switch currentLayout {
|
||||||
case .horizontal:
|
case .horizontal:
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [self] in
|
||||||
|
@ -223,6 +236,13 @@ extension CtlCandidateTDK {
|
||||||
if #unavailable(macOS 12) { return false }
|
if #unavailable(macOS 12) { return false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var currentSelectedCandidateText: String {
|
||||||
|
if thePool.candidateDataAll.count > highlightedIndex {
|
||||||
|
return thePool.candidateDataAll[highlightedIndex].displayedText
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 10.15, *)
|
@available(macOS 10.15, *)
|
||||||
|
|
|
@ -38,6 +38,7 @@ public struct VwrCandidateHorizontal: View {
|
||||||
public var controller: CtlCandidateTDK
|
public var controller: CtlCandidateTDK
|
||||||
@State public var thePool: CandidatePool
|
@State public var thePool: CandidatePool
|
||||||
@State public var tooltip: String = ""
|
@State public var tooltip: String = ""
|
||||||
|
@State public var reverseLookupResult: String = ""
|
||||||
|
|
||||||
private var positionLabel: String {
|
private var positionLabel: String {
|
||||||
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
||||||
|
@ -91,16 +92,21 @@ public struct VwrCandidateHorizontal: View {
|
||||||
}
|
}
|
||||||
.fixedSize(horizontal: false, vertical: true).padding(5)
|
.fixedSize(horizontal: false, vertical: true).padding(5)
|
||||||
.background(Color(nsColor: NSColor.controlBackgroundColor).ignoresSafeArea())
|
.background(Color(nsColor: NSColor.controlBackgroundColor).ignoresSafeArea())
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .trailing) {
|
||||||
Color(nsColor: tooltip.isEmpty ? .windowBackgroundColor : CandidateCellData.highlightBackground)
|
Color(nsColor: tooltip.isEmpty ? .windowBackgroundColor : CandidateCellData.highlightBackground)
|
||||||
.ignoresSafeArea()
|
.ignoresSafeArea()
|
||||||
HStack(alignment: .bottom) {
|
HStack(alignment: .bottom) {
|
||||||
Text(tooltip).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(1)
|
if !tooltip.isEmpty {
|
||||||
|
Text(tooltip).lineLimit(1)
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(positionLabel).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
|
||||||
.lineLimit(
|
|
||||||
1)
|
|
||||||
}
|
}
|
||||||
|
if !reverseLookupResult.isEmpty, !(controller.delegate?.isVerticalTyping ?? true) {
|
||||||
|
Text(reverseLookupResult).lineLimit(1)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Text(positionLabel).lineLimit(1)
|
||||||
|
}
|
||||||
|
.font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
||||||
.padding(7).foregroundColor(
|
.padding(7).foregroundColor(
|
||||||
.init(nsColor: tooltip.isEmpty ? .controlTextColor : .selectedMenuItemTextColor.withAlphaComponent(0.9))
|
.init(nsColor: tooltip.isEmpty ? .controlTextColor : .selectedMenuItemTextColor.withAlphaComponent(0.9))
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,6 +37,7 @@ public struct VwrCandidateVertical: View {
|
||||||
public var controller: CtlCandidateTDK
|
public var controller: CtlCandidateTDK
|
||||||
@State public var thePool: CandidatePool
|
@State public var thePool: CandidatePool
|
||||||
@State public var tooltip: String = ""
|
@State public var tooltip: String = ""
|
||||||
|
@State public var reverseLookupResult: String = ""
|
||||||
|
|
||||||
private var positionLabel: String {
|
private var positionLabel: String {
|
||||||
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
||||||
|
@ -99,20 +100,26 @@ public struct VwrCandidateVertical: View {
|
||||||
}
|
}
|
||||||
.fixedSize(horizontal: true, vertical: false).padding(5)
|
.fixedSize(horizontal: true, vertical: false).padding(5)
|
||||||
.background(Color(nsColor: NSColor.controlBackgroundColor).ignoresSafeArea())
|
.background(Color(nsColor: NSColor.controlBackgroundColor).ignoresSafeArea())
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .trailing) {
|
||||||
Color(nsColor: tooltip.isEmpty ? .windowBackgroundColor : CandidateCellData.highlightBackground)
|
Color(nsColor: tooltip.isEmpty ? .windowBackgroundColor : CandidateCellData.highlightBackground)
|
||||||
.ignoresSafeArea()
|
.ignoresSafeArea()
|
||||||
HStack(alignment: .bottom) {
|
HStack(alignment: .bottom) {
|
||||||
Text(tooltip).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(1)
|
if !tooltip.isEmpty {
|
||||||
|
Text(tooltip).lineLimit(1)
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(positionLabel).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
|
||||||
.lineLimit(
|
|
||||||
1)
|
|
||||||
}
|
}
|
||||||
|
if !reverseLookupResult.isEmpty, !(controller.delegate?.isVerticalTyping ?? true) {
|
||||||
|
Text(reverseLookupResult).lineLimit(1)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Text(positionLabel).lineLimit(1)
|
||||||
|
}
|
||||||
|
.font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
||||||
.padding(7).foregroundColor(
|
.padding(7).foregroundColor(
|
||||||
.init(nsColor: tooltip.isEmpty ? .controlTextColor : .selectedMenuItemTextColor.withAlphaComponent(0.9))
|
.init(nsColor: tooltip.isEmpty ? .controlTextColor : .selectedMenuItemTextColor.withAlphaComponent(0.9))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
}
|
}
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 10).stroke(.white.opacity(0.2), lineWidth: 1)
|
RoundedRectangle(cornerRadius: 10).stroke(.white.opacity(0.2), lineWidth: 1)
|
||||||
|
|
|
@ -40,6 +40,7 @@ public struct VwrCandidateHorizontalBackports: View {
|
||||||
public var controller: CtlCandidateTDK
|
public var controller: CtlCandidateTDK
|
||||||
@State public var thePool: CandidatePool
|
@State public var thePool: CandidatePool
|
||||||
@State public var tooltip: String = ""
|
@State public var tooltip: String = ""
|
||||||
|
@State public var reverseLookupResult: String = ""
|
||||||
|
|
||||||
private var positionLabel: String {
|
private var positionLabel: String {
|
||||||
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
||||||
|
@ -93,7 +94,7 @@ public struct VwrCandidateHorizontalBackports: View {
|
||||||
}
|
}
|
||||||
.fixedSize(horizontal: false, vertical: true).padding(5)
|
.fixedSize(horizontal: false, vertical: true).padding(5)
|
||||||
.background(Color(white: colorScheme == .dark ? 0.1 : 1))
|
.background(Color(white: colorScheme == .dark ? 0.1 : 1))
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .trailing) {
|
||||||
if tooltip.isEmpty {
|
if tooltip.isEmpty {
|
||||||
Color(white: colorScheme == .dark ? 0.2 : 0.9)
|
Color(white: colorScheme == .dark ? 0.2 : 0.9)
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,12 +102,17 @@ public struct VwrCandidateHorizontalBackports: View {
|
||||||
controller.highlightedColorUIBackports
|
controller.highlightedColorUIBackports
|
||||||
}
|
}
|
||||||
HStack(alignment: .bottom) {
|
HStack(alignment: .bottom) {
|
||||||
Text(tooltip).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(1)
|
if !tooltip.isEmpty {
|
||||||
|
Text(tooltip).lineLimit(1)
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(positionLabel).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
|
||||||
.lineLimit(
|
|
||||||
1)
|
|
||||||
}
|
}
|
||||||
|
if !reverseLookupResult.isEmpty, !(controller.delegate?.isVerticalTyping ?? true) {
|
||||||
|
Text(reverseLookupResult).lineLimit(1)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Text(positionLabel).lineLimit(1)
|
||||||
|
}
|
||||||
|
.font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
||||||
.padding(7).foregroundColor(
|
.padding(7).foregroundColor(
|
||||||
tooltip.isEmpty && colorScheme == .light ? Color(white: 0.1) : Color(white: 0.9)
|
tooltip.isEmpty && colorScheme == .light ? Color(white: 0.1) : Color(white: 0.9)
|
||||||
)
|
)
|
||||||
|
|
|
@ -39,6 +39,7 @@ public struct VwrCandidateVerticalBackports: View {
|
||||||
public var controller: CtlCandidateTDK
|
public var controller: CtlCandidateTDK
|
||||||
@State public var thePool: CandidatePool
|
@State public var thePool: CandidatePool
|
||||||
@State public var tooltip: String = ""
|
@State public var tooltip: String = ""
|
||||||
|
@State public var reverseLookupResult: String = ""
|
||||||
|
|
||||||
private var positionLabel: String {
|
private var positionLabel: String {
|
||||||
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
||||||
|
@ -101,7 +102,7 @@ public struct VwrCandidateVerticalBackports: View {
|
||||||
}
|
}
|
||||||
.fixedSize(horizontal: true, vertical: false).padding(5)
|
.fixedSize(horizontal: true, vertical: false).padding(5)
|
||||||
.background(Color(white: colorScheme == .dark ? 0.1 : 1))
|
.background(Color(white: colorScheme == .dark ? 0.1 : 1))
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .trailing) {
|
||||||
if tooltip.isEmpty {
|
if tooltip.isEmpty {
|
||||||
Color(white: colorScheme == .dark ? 0.2 : 0.9)
|
Color(white: colorScheme == .dark ? 0.2 : 0.9)
|
||||||
} else {
|
} else {
|
||||||
|
@ -109,16 +110,22 @@ public struct VwrCandidateVerticalBackports: View {
|
||||||
controller.highlightedColorUIBackports
|
controller.highlightedColorUIBackports
|
||||||
}
|
}
|
||||||
HStack(alignment: .bottom) {
|
HStack(alignment: .bottom) {
|
||||||
Text(tooltip).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(1)
|
if !tooltip.isEmpty {
|
||||||
|
Text(tooltip).lineLimit(1)
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(positionLabel).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
|
||||||
.lineLimit(
|
|
||||||
1)
|
|
||||||
}
|
}
|
||||||
|
if !reverseLookupResult.isEmpty, !(controller.delegate?.isVerticalTyping ?? true) {
|
||||||
|
Text(reverseLookupResult).lineLimit(1)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Text(positionLabel).lineLimit(1)
|
||||||
|
}
|
||||||
|
.font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
||||||
.padding(7).foregroundColor(
|
.padding(7).foregroundColor(
|
||||||
tooltip.isEmpty && colorScheme == .light ? Color(white: 0.1) : Color(white: 0.9)
|
tooltip.isEmpty && colorScheme == .light ? Color(white: 0.1) : Color(white: 0.9)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
}
|
}
|
||||||
.overlay(
|
.overlay(
|
||||||
RoundedRectangle(cornerRadius: 10).stroke(.white.opacity(0.2), lineWidth: 1)
|
RoundedRectangle(cornerRadius: 10).stroke(.white.opacity(0.2), lineWidth: 1)
|
||||||
|
|
|
@ -27,6 +27,7 @@ extension vChewingLM {
|
||||||
public private(set) var keyNameMap: [String: String] = [:]
|
public private(set) var keyNameMap: [String: String] = [:]
|
||||||
public private(set) var charDefMap: [String: [String]] = [:]
|
public private(set) var charDefMap: [String: [String]] = [:]
|
||||||
public private(set) var charDefWildcardMap: [String: [String]] = [:]
|
public private(set) var charDefWildcardMap: [String: [String]] = [:]
|
||||||
|
public private(set) var reverseLookupMap: [String: [String]] = [:]
|
||||||
/// 字根輸入法專用八股文:[字詞:頻次]。
|
/// 字根輸入法專用八股文:[字詞:頻次]。
|
||||||
public private(set) var octagramMap: [String: Int] = [:]
|
public private(set) var octagramMap: [String: Int] = [:]
|
||||||
/// 音韻輸入法專用八股文:[字詞:(頻次, 讀音)]。
|
/// 音韻輸入法專用八股文:[字詞:(頻次, 讀音)]。
|
||||||
|
@ -91,13 +92,15 @@ extension vChewingLM {
|
||||||
if loadingKeys, !cells[0].contains("%keyname") {
|
if loadingKeys, !cells[0].contains("%keyname") {
|
||||||
keyNameMap[strFirstCell] = String(cells[1])
|
keyNameMap[strFirstCell] = String(cells[1])
|
||||||
} else if loadingCharDefinitions, !strLine.contains("%chardef") {
|
} else if loadingCharDefinitions, !strLine.contains("%chardef") {
|
||||||
|
let strSecondCell = String(cells[1])
|
||||||
theMaxKeyLength = max(theMaxKeyLength, cells[0].count)
|
theMaxKeyLength = max(theMaxKeyLength, cells[0].count)
|
||||||
charDefMap[strFirstCell, default: []].append(String(cells[1]))
|
charDefMap[strFirstCell, default: []].append(strSecondCell)
|
||||||
|
reverseLookupMap[strSecondCell, default: []].append(strFirstCell)
|
||||||
var keyComps = strFirstCell.charComponents
|
var keyComps = strFirstCell.charComponents
|
||||||
while !keyComps.isEmpty, !wildcardKey.isEmpty {
|
while !keyComps.isEmpty, !wildcardKey.isEmpty {
|
||||||
keyComps.removeLast()
|
keyComps.removeLast()
|
||||||
if !wildcardKey.isEmpty {
|
if !wildcardKey.isEmpty {
|
||||||
charDefWildcardMap[keyComps.joined() + wildcardKey, default: []].append(String(cells[1]))
|
charDefWildcardMap[keyComps.joined() + wildcardKey, default: []].append(strSecondCell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if loadingOctagramData, !strLine.contains("%octagram") {
|
} else if loadingOctagramData, !strLine.contains("%octagram") {
|
||||||
|
|
|
@ -12,11 +12,14 @@ public protocol CtlCandidateDelegate {
|
||||||
func candidatePairs(conv: Bool) -> [(String, String)]
|
func candidatePairs(conv: Bool) -> [(String, String)]
|
||||||
func candidatePairSelected(at index: Int)
|
func candidatePairSelected(at index: Int)
|
||||||
func candidates(_ sender: Any!) -> [Any]!
|
func candidates(_ sender: Any!) -> [Any]!
|
||||||
|
@discardableResult func annotate(for value: String) -> String
|
||||||
var selectionKeys: String { get }
|
var selectionKeys: String { get }
|
||||||
|
var isVerticalTyping: Bool { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol CtlCandidateProtocol {
|
public protocol CtlCandidateProtocol {
|
||||||
var tooltip: String { get set }
|
var tooltip: String { get set }
|
||||||
|
var reverseLookupResult: String { get set }
|
||||||
var locale: String { get set }
|
var locale: String { get set }
|
||||||
var currentLayout: NSUserInterfaceLayoutOrientation { get set }
|
var currentLayout: NSUserInterfaceLayoutOrientation { get set }
|
||||||
var delegate: CtlCandidateDelegate? { get set }
|
var delegate: CtlCandidateDelegate? { get set }
|
||||||
|
|
|
@ -51,6 +51,7 @@ public protocol PrefMgrProtocol {
|
||||||
var inlineDumpPinyinInLieuOfZhuyin: Bool { get set }
|
var inlineDumpPinyinInLieuOfZhuyin: Bool { get set }
|
||||||
var showTranslatedStrokesInCompositionBuffer: Bool { get set }
|
var showTranslatedStrokesInCompositionBuffer: Bool { get set }
|
||||||
var forceCassetteChineseConversion: Int { get set }
|
var forceCassetteChineseConversion: Int { get set }
|
||||||
|
var showReverseLookupInCandidateUI: Bool { get set }
|
||||||
var cns11643Enabled: Bool { get set }
|
var cns11643Enabled: Bool { get set }
|
||||||
var cassetteEnabled: Bool { get set }
|
var cassetteEnabled: Bool { get set }
|
||||||
var symbolInputEnabled: Bool { get set }
|
var symbolInputEnabled: Bool { get set }
|
||||||
|
|
|
@ -64,6 +64,7 @@ public enum UserDef: String, CaseIterable {
|
||||||
case kOnlyLoadFactoryLangModelsIfNeeded = "OnlyLoadFactoryLangModelsIfNeeded"
|
case kOnlyLoadFactoryLangModelsIfNeeded = "OnlyLoadFactoryLangModelsIfNeeded"
|
||||||
case kShowTranslatedStrokesInCompositionBuffer = "ShowTranslatedStrokesInCompositionBuffer"
|
case kShowTranslatedStrokesInCompositionBuffer = "ShowTranslatedStrokesInCompositionBuffer"
|
||||||
case kForceCassetteChineseConversion = "ForceCassetteChineseConversion"
|
case kForceCassetteChineseConversion = "ForceCassetteChineseConversion"
|
||||||
|
case kShowReverseLookupInCandidateUI = "ShowReverseLookupInCandidateUI"
|
||||||
|
|
||||||
case kUseIMKCandidateWindow = "UseIMKCandidateWindow"
|
case kUseIMKCandidateWindow = "UseIMKCandidateWindow"
|
||||||
case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier"
|
case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier"
|
||||||
|
|
|
@ -150,6 +150,9 @@ public class PrefMgr: PrefMgrProtocol {
|
||||||
@AppProperty(key: UserDef.kForceCassetteChineseConversion.rawValue, defaultValue: 0)
|
@AppProperty(key: UserDef.kForceCassetteChineseConversion.rawValue, defaultValue: 0)
|
||||||
public var forceCassetteChineseConversion: Int
|
public var forceCassetteChineseConversion: Int
|
||||||
|
|
||||||
|
@AppProperty(key: UserDef.kShowReverseLookupInCandidateUI.rawValue, defaultValue: true)
|
||||||
|
public var showReverseLookupInCandidateUI: Bool
|
||||||
|
|
||||||
// MARK: - Settings (Tier 2)
|
// MARK: - Settings (Tier 2)
|
||||||
|
|
||||||
@AppProperty(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false)
|
@AppProperty(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false)
|
||||||
|
|
|
@ -19,6 +19,7 @@ extension PrefMgr {
|
||||||
shiftKeyAccommodationBehavior = 0
|
shiftKeyAccommodationBehavior = 0
|
||||||
disableShiftTogglingAlphanumericalMode = true
|
disableShiftTogglingAlphanumericalMode = true
|
||||||
togglingAlphanumericalModeWithLShift = false
|
togglingAlphanumericalModeWithLShift = false
|
||||||
|
showReverseLookupInCandidateUI = false
|
||||||
}
|
}
|
||||||
// 自動糾正選字鍵 (利用其 didSet 特性)
|
// 自動糾正選字鍵 (利用其 didSet 特性)
|
||||||
candidateKeys = candidateKeys
|
candidateKeys = candidateKeys
|
||||||
|
|
|
@ -56,6 +56,16 @@ extension SessionCtl: InputHandlerDelegate {
|
||||||
// MARK: - Candidate Controller Delegate
|
// MARK: - Candidate Controller Delegate
|
||||||
|
|
||||||
extension SessionCtl: CtlCandidateDelegate {
|
extension SessionCtl: CtlCandidateDelegate {
|
||||||
|
@discardableResult public func annotate(for value: String) -> String {
|
||||||
|
// 這一段專門處理「反查」。
|
||||||
|
if !PrefMgr.shared.showReverseLookupInCandidateUI { return "" }
|
||||||
|
if isVerticalTyping { return "" } // 縱排輸入的場合,選字窗沒那個空間顯示反查結果。
|
||||||
|
if value.isEmpty { return "" } // 空字串沒有需要反查的東西。
|
||||||
|
if value.contains("_") { return "" }
|
||||||
|
guard let lookupResult = LMMgr.currentLM.currentCassette.reverseLookupMap[value] else { return "" }
|
||||||
|
return lookupResult.joined(separator: " ")
|
||||||
|
}
|
||||||
|
|
||||||
public var selectionKeys: String {
|
public var selectionKeys: String {
|
||||||
PrefMgr.shared.useIMKCandidateWindow ? "123456789" : PrefMgr.shared.candidateKeys
|
PrefMgr.shared.useIMKCandidateWindow ? "123456789" : PrefMgr.shared.candidateKeys
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import Shared
|
||||||
/// 威注音自用的 IMKCandidates 型別。因為有用到 bridging header,所以無法弄成 Swift Package。
|
/// 威注音自用的 IMKCandidates 型別。因為有用到 bridging header,所以無法弄成 Swift Package。
|
||||||
public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
|
public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
|
||||||
public var tooltip: String = ""
|
public var tooltip: String = ""
|
||||||
|
public var reverseLookupResult: String = ""
|
||||||
public var locale: String = ""
|
public var locale: String = ""
|
||||||
public var useLangIdentifier: Bool = false
|
public var useLangIdentifier: Bool = false
|
||||||
public var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
public var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
||||||
|
|
|
@ -36,6 +36,8 @@ struct VwrPrefPaneGeneral: View {
|
||||||
@State private var selEnableAutoUpdateCheck = UserDefaults.standard.bool(
|
@State private var selEnableAutoUpdateCheck = UserDefaults.standard.bool(
|
||||||
forKey: UserDef.kCheckUpdateAutomatically.rawValue)
|
forKey: UserDef.kCheckUpdateAutomatically.rawValue)
|
||||||
@State private var selEnableDebugMode = UserDefaults.standard.bool(forKey: UserDef.kIsDebugModeEnabled.rawValue)
|
@State private var selEnableDebugMode = UserDefaults.standard.bool(forKey: UserDef.kIsDebugModeEnabled.rawValue)
|
||||||
|
@State private var selShowReverseLookupInCandidateUI = UserDefaults.standard.bool(
|
||||||
|
forKey: UserDef.kShowReverseLookupInCandidateUI.rawValue)
|
||||||
|
|
||||||
private let contentMaxHeight: Double = 440
|
private let contentMaxHeight: Double = 440
|
||||||
private let contentWidth: Double = {
|
private let contentWidth: Double = {
|
||||||
|
@ -129,6 +131,14 @@ struct VwrPrefPaneGeneral: View {
|
||||||
.pickerStyle(RadioGroupPickerStyle())
|
.pickerStyle(RadioGroupPickerStyle())
|
||||||
Text(LocalizedStringKey("Choose your preferred layout of the candidate window."))
|
Text(LocalizedStringKey("Choose your preferred layout of the candidate window."))
|
||||||
.preferenceDescription()
|
.preferenceDescription()
|
||||||
|
Toggle(
|
||||||
|
LocalizedStringKey("Show available reverse-lookup results in candidate window"),
|
||||||
|
isOn: $selShowReverseLookupInCandidateUI.onChange {
|
||||||
|
PrefMgr.shared.showReverseLookupInCandidateUI = selShowReverseLookupInCandidateUI
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.controlSize(.small)
|
||||||
|
.disabled(PrefMgr.shared.useIMKCandidateWindow)
|
||||||
}
|
}
|
||||||
SSPreferences.Section(label: { Text(LocalizedStringKey("Output Settings:")) }) {
|
SSPreferences.Section(label: { Text(LocalizedStringKey("Output Settings:")) }) {
|
||||||
Toggle(
|
Toggle(
|
||||||
|
|
|
@ -223,6 +223,7 @@
|
||||||
"Selection Keys:" = "Selection Keys:";
|
"Selection Keys:" = "Selection Keys:";
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+Letter:";
|
"Shift+Letter:" = "Shift+Letter:";
|
||||||
|
"Show available reverse-lookup results in candidate window" = "Show available reverse-lookup results in candidate window";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
||||||
"Show notifications when toggling Caps Lock" = "Show notifications when toggling Caps Lock";
|
"Show notifications when toggling Caps Lock" = "Show notifications when toggling Caps Lock";
|
||||||
"Show translated strokes in composition buffer" = "Show translated strokes in composition buffer";
|
"Show translated strokes in composition buffer" = "Show translated strokes in composition buffer";
|
||||||
|
|
|
@ -223,6 +223,7 @@
|
||||||
"Selection Keys:" = "Selection Keys:";
|
"Selection Keys:" = "Selection Keys:";
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+Letter:";
|
"Shift+Letter:" = "Shift+Letter:";
|
||||||
|
"Show available reverse-lookup results in candidate window" = "Show available reverse-lookup results in candidate window";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
||||||
"Show notifications when toggling Caps Lock" = "Show notifications when toggling Caps Lock";
|
"Show notifications when toggling Caps Lock" = "Show notifications when toggling Caps Lock";
|
||||||
"Show translated strokes in composition buffer" = "Show translated strokes in composition buffer";
|
"Show translated strokes in composition buffer" = "Show translated strokes in composition buffer";
|
||||||
|
|
|
@ -223,6 +223,7 @@
|
||||||
"Selection Keys:" = "言選り用キー:";
|
"Selection Keys:" = "言選り用キー:";
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+文字キー:";
|
"Shift+Letter:" = "Shift+文字キー:";
|
||||||
|
"Show available reverse-lookup results in candidate window" = "候補陳列ウィンドウで可能な逆引参照結果を示す";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "弁音合併入力(入力緩衝列で音読みを漢語弁音に)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "弁音合併入力(入力緩衝列で音読みを漢語弁音に)";
|
||||||
"Show notifications when toggling Caps Lock" = "Caps Lock で切り替えの時に吹出通知メッセージを";
|
"Show notifications when toggling Caps Lock" = "Caps Lock で切り替えの時に吹出通知メッセージを";
|
||||||
"Show translated strokes in composition buffer" = "原始キーネームでなく、筆画を入力緩衝列で表示する";
|
"Show translated strokes in composition buffer" = "原始キーネームでなく、筆画を入力緩衝列で表示する";
|
||||||
|
|
|
@ -223,6 +223,7 @@
|
||||||
"Selection Keys:" = "选字键:";
|
"Selection Keys:" = "选字键:";
|
||||||
"Shift+BackSpace:" = "Shift+退格键:";
|
"Shift+BackSpace:" = "Shift+退格键:";
|
||||||
"Shift+Letter:" = "Shift+字母键:";
|
"Shift+Letter:" = "Shift+字母键:";
|
||||||
|
"Show available reverse-lookup results in candidate window" = "在选字窗内显示可用的字根反查结果";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音并击(组字区内显示汉语拼音)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音并击(组字区内显示汉语拼音)";
|
||||||
"Show notifications when toggling Caps Lock" = "以 Caps Lock 切换输入法/中英模式时显示通知";
|
"Show notifications when toggling Caps Lock" = "以 Caps Lock 切换输入法/中英模式时显示通知";
|
||||||
"Show translated strokes in composition buffer" = "在组字区内显示字根、而非原始键盘码";
|
"Show translated strokes in composition buffer" = "在组字区内显示字根、而非原始键盘码";
|
||||||
|
|
|
@ -223,6 +223,7 @@
|
||||||
"Selection Keys:" = "選字鍵:";
|
"Selection Keys:" = "選字鍵:";
|
||||||
"Shift+BackSpace:" = "Shift+退格鍵:";
|
"Shift+BackSpace:" = "Shift+退格鍵:";
|
||||||
"Shift+Letter:" = "Shift+字母鍵:";
|
"Shift+Letter:" = "Shift+字母鍵:";
|
||||||
|
"Show available reverse-lookup results in candidate window" = "在選字窗內顯示可用的字根反查結果";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音並擊(組字區內顯示漢語拼音)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音並擊(組字區內顯示漢語拼音)";
|
||||||
"Show notifications when toggling Caps Lock" = "以 Caps Lock 切換輸入法/中英模式時顯示通知";
|
"Show notifications when toggling Caps Lock" = "以 Caps Lock 切換輸入法/中英模式時顯示通知";
|
||||||
"Show translated strokes in composition buffer" = "在組字區內顯示字根、而非原始鍵盤碼";
|
"Show translated strokes in composition buffer" = "在組字區內顯示字根、而非原始鍵盤碼";
|
||||||
|
|
Loading…
Reference in New Issue