From 1648152b2436006039af51830b4137aa66eda8e5 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Fri, 23 Sep 2022 23:03:12 +0800 Subject: [PATCH] Repo // Move IMEState-related protocols to Shared package. --- .../Sources/Shared/CandidateNode.swift} | 0 .../Shared/Protocols/IMEStateProtocol.swift | 64 +++++++++++++ .../Sources/Shared/Shared.swift | 27 ++++++ Packages/vChewing_TooltipUI/Package.swift | 2 + .../Sources/TooltipUI/TooltipUI.swift | 12 +-- Source/Modules/IMEState.swift | 96 ++++++------------- Source/Modules/IMEStateData.swift | 61 ++++++------ .../ctlPopupCompositionBuffer.swift | 2 + Source/Modules/ctlInputMethod_Delegates.swift | 2 +- .../Modules/ctlInputMethod_HandleStates.swift | 2 + 10 files changed, 160 insertions(+), 108 deletions(-) rename Packages/{vChewing_LangModelAssembly/Sources/LangModelAssembly/LMCandidateNode.swift => vChewing_Shared/Sources/Shared/CandidateNode.swift} (100%) create mode 100644 Packages/vChewing_Shared/Sources/Shared/Protocols/IMEStateProtocol.swift diff --git a/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMCandidateNode.swift b/Packages/vChewing_Shared/Sources/Shared/CandidateNode.swift similarity index 100% rename from Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMCandidateNode.swift rename to Packages/vChewing_Shared/Sources/Shared/CandidateNode.swift diff --git a/Packages/vChewing_Shared/Sources/Shared/Protocols/IMEStateProtocol.swift b/Packages/vChewing_Shared/Sources/Shared/Protocols/IMEStateProtocol.swift new file mode 100644 index 00000000..173b86eb --- /dev/null +++ b/Packages/vChewing_Shared/Sources/Shared/Protocols/IMEStateProtocol.swift @@ -0,0 +1,64 @@ +// (c) 2021 and onwards The vChewing Project (MIT-NTL License). +// ==================== +// This code is released under the MIT license (SPDX-License-Identifier: MIT) +// ... with NTL restriction stating that: +// 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 defined in MIT License. + +import Cocoa + +// 所有 IMEState 均遵守該協定: +public protocol IMEStateProtocol { + var type: StateType { get } + var data: StateDataProtocol { get } + var isASCIIMode: Bool { get set } + var isVerticalTyping: Bool { get set } + var isVerticalCandidateWindow: Bool { get set } + var candidates: [(String, String)] { get set } + var hasComposition: Bool { get } + var isCandidateContainer: Bool { get } + var displayedText: String { get } + var displayedTextConverted: String { get } + var textToCommit: String { get set } + var tooltip: String { get set } + var attributedString: NSAttributedString { get } + var convertedToInputting: IMEStateProtocol { get } + var isFilterable: Bool { get } + var isMarkedLengthValid: Bool { get } + var node: CandidateNode { get set } + var displayTextSegments: [String] { get } + var tooltipBackupForInputting: String { get set } + var markedRange: Range { get } + var u16MarkedRange: Range { get } + var u16Cursor: Int { get } + var cursor: Int { get set } + var marker: Int { get set } +} + +public protocol StateDataProtocol { + var cursor: Int { get set } + var marker: Int { get set } + var markedRange: Range { get } + var u16MarkedRange: Range { get } + var u16Cursor: Int { get } + var textToCommit: String { get set } + var markedReadings: [String] { get set } + var displayTextSegments: [String] { get set } + var isFilterable: Bool { get } + var isVerticalTyping: Bool { get set } + var isMarkedLengthValid: Bool { get } + var candidates: [(String, String)] { get set } + var displayedText: String { get set } + var displayedTextConverted: String { get } + var tooltipBackupForInputting: String { get set } + var tooltip: String { get set } + var attributedStringNormal: NSAttributedString { get } + var attributedStringMarking: NSAttributedString { get } + var attributedStringPlaceholder: NSAttributedString { get } + var userPhraseDumped: String { get } + var userPhraseDumpedConverted: String { get } + var doesUserPhraseExist: Bool { get } + var tooltipColorState: TooltipColorState { get set } + mutating func updateTooltipForMarking() +} diff --git a/Packages/vChewing_Shared/Sources/Shared/Shared.swift b/Packages/vChewing_Shared/Sources/Shared/Shared.swift index f0c5da3c..d7ba66e8 100644 --- a/Packages/vChewing_Shared/Sources/Shared/Shared.swift +++ b/Packages/vChewing_Shared/Sources/Shared/Shared.swift @@ -103,6 +103,33 @@ public enum UserDef: String, CaseIterable { } } +// MARK: - Tooltip Color States + +public enum TooltipColorState { + case normal + case redAlert + case warning + case denialOverflow + case denialInsufficiency + case prompt +} + +// MARK: - IMEState types. + +// 用以讓每個狀態自描述的 enum。 +public enum StateType: String { + case ofDeactivated = "Deactivated" + case ofEmpty = "Empty" + case ofAbortion = "Abortion" // 該狀態會自動轉為 Empty + case ofCommitting = "Committing" + case ofAssociates = "Associates" + case ofNotEmpty = "NotEmpty" + case ofInputting = "Inputting" + case ofMarking = "Marking" + case ofCandidates = "Candidates" + case ofSymbolTable = "SymbolTable" +} + // MARK: - Parser for Syllable composer public enum KeyboardParser: Int, CaseIterable { diff --git a/Packages/vChewing_TooltipUI/Package.swift b/Packages/vChewing_TooltipUI/Package.swift index e0060db3..6dd58c26 100644 --- a/Packages/vChewing_TooltipUI/Package.swift +++ b/Packages/vChewing_TooltipUI/Package.swift @@ -15,6 +15,7 @@ let package = Package( dependencies: [ .package(path: "../Fuziki_NSAttributedTextView"), .package(path: "../vChewing_CocoaExtension"), + .package(path: "../vChewing_Shared"), ], targets: [ .target( @@ -22,6 +23,7 @@ let package = Package( dependencies: [ .product(name: "NSAttributedTextView", package: "Fuziki_NSAttributedTextView"), .product(name: "CocoaExtension", package: "vChewing_CocoaExtension"), + .product(name: "Shared", package: "vChewing_Shared"), ] ) ] diff --git a/Packages/vChewing_TooltipUI/Sources/TooltipUI/TooltipUI.swift b/Packages/vChewing_TooltipUI/Sources/TooltipUI/TooltipUI.swift index 42ac77c5..48aa677e 100644 --- a/Packages/vChewing_TooltipUI/Sources/TooltipUI/TooltipUI.swift +++ b/Packages/vChewing_TooltipUI/Sources/TooltipUI/TooltipUI.swift @@ -9,17 +9,9 @@ import Cocoa import CocoaExtension import NSAttributedTextView +import Shared public class TooltipUI: NSWindowController { - public enum ColorStates { - case normal - case redAlert - case warning - case denialOverflow - case denialInsufficiency - case prompt - } - private var messageText: NSAttributedTooltipTextView private var tooltip: String = "" { didSet { @@ -68,7 +60,7 @@ public class TooltipUI: NSWindowController { set(windowTopLeftPoint: point, bottomOutOfScreenAdjustmentHeight: heightDelta) } - public func setColor(state: ColorStates) { + public func setColor(state: TooltipColorState) { var backgroundColor = NSColor.controlBackgroundColor var textColor = NSColor.textColor switch state { diff --git a/Source/Modules/IMEState.swift b/Source/Modules/IMEState.swift index eec9530c..bf810d6d 100644 --- a/Source/Modules/IMEState.swift +++ b/Source/Modules/IMEState.swift @@ -7,47 +7,7 @@ // requirements defined in MIT License. import LangModelAssembly - -// 用以讓每個狀態自描述的 enum。 -public enum StateType: String { - case ofDeactivated = "Deactivated" - case ofEmpty = "Empty" - case ofAbortion = "Abortion" // 該狀態會自動轉為 Empty - case ofCommitting = "Committing" - case ofAssociates = "Associates" - case ofNotEmpty = "NotEmpty" - case ofInputting = "Inputting" - case ofMarking = "Marking" - case ofCandidates = "Candidates" - case ofSymbolTable = "SymbolTable" -} - -// 所有 IMEState 均遵守該協定: -public protocol IMEStateProtocol { - var type: StateType { get } - var data: StateData { get } - var isASCIIMode: Bool { get set } - var isVerticalTyping: Bool { get set } - var isVerticalCandidateWindow: Bool { get set } - var candidates: [(String, String)] { get } - var hasComposition: Bool { get } - var isCandidateContainer: Bool { get } - var displayedText: String { get } - var displayedTextConverted: String { get } - var textToCommit: String { get set } - var tooltip: String { get set } - var attributedString: NSAttributedString { get } - var convertedToInputting: IMEState { get } - var isFilterable: Bool { get } - var isMarkedLengthValid: Bool { get } - var node: CandidateNode { get set } - var displayTextSegments: [String] { get } - var tooltipBackupForInputting: String { get set } - var markedRange: Range { get } - var cursor: Int { get } - var u16MarkedRange: Range { get } - var u16Cursor: Int { get } -} +import Shared /// 用以呈現輸入法控制器(ctlInputMethod)的各種狀態。 /// @@ -82,17 +42,17 @@ public protocol IMEStateProtocol { /// - .SymbolTable: 波浪鍵符號選單專用的狀態,有自身的特殊處理。 public struct IMEState: IMEStateProtocol { public var type: StateType = .ofEmpty - public var data: StateData = .init() + public var data: StateDataProtocol = StateData() as StateDataProtocol public var node: CandidateNode = .init(name: "") public var isASCIIMode = false public var isVerticalCandidateWindow = false - init(_ data: StateData = .init(), type: StateType = .ofEmpty) { + init(_ data: StateDataProtocol = StateData() as StateDataProtocol, type: StateType = .ofEmpty) { self.data = data self.type = type isVerticalTyping = ctlInputMethod.isVerticalTyping } - init(_ data: StateData = .init(), type: StateType = .ofEmpty, node: CandidateNode) { + init(_ data: StateDataProtocol = StateData() as StateDataProtocol, type: StateType = .ofEmpty, node: CandidateNode) { self.data = data self.type = type self.node = node @@ -108,14 +68,14 @@ extension IMEState { public static func ofAbortion() -> IMEState { .init(type: .ofAbortion) } public static func ofCommitting(textToCommit: String) -> IMEState { var result = IMEState(type: .ofCommitting) - result.data.textToCommit = textToCommit + result.textToCommit = textToCommit ChineseConverter.ensureCurrencyNumerals(target: &result.data.textToCommit) return result } public static func ofAssociates(candidates: [(String, String)]) -> IMEState { var result = IMEState(type: .ofAssociates) - result.data.candidates = candidates + result.candidates = candidates return result } @@ -175,15 +135,24 @@ extension IMEState { extension IMEState { public var isFilterable: Bool { data.isFilterable } public var isMarkedLengthValid: Bool { data.isMarkedLengthValid } - public var candidates: [(String, String)] { data.candidates } public var displayedText: String { data.displayedText } public var displayedTextConverted: String { data.displayedTextConverted } - public var cursor: Int { data.cursor } public var displayTextSegments: [String] { data.displayTextSegments } public var markedRange: Range { data.markedRange } public var u16MarkedRange: Range { data.u16MarkedRange } public var u16Cursor: Int { data.u16Cursor } - public var convertedToInputting: IMEState { + + public var cursor: Int { + get { data.cursor } + set { data.cursor = newValue } + } + + public var marker: Int { + get { data.marker } + set { data.marker = newValue } + } + + public var convertedToInputting: IMEStateProtocol { if type == .ofInputting { return self } var result = IMEState.ofInputting(displayTextSegments: data.displayTextSegments, cursor: data.cursor) result.tooltip = data.tooltipBackupForInputting @@ -191,22 +160,19 @@ extension IMEState { return result } + public var candidates: [(String, String)] { + get { data.candidates } + set { data.candidates = newValue } + } + public var textToCommit: String { - get { - data.textToCommit - } - set { - data.textToCommit = newValue - } + get { data.textToCommit } + set { data.textToCommit = newValue } } public var tooltip: String { - get { - data.tooltip - } - set { - data.tooltip = newValue - } + get { data.tooltip } + set { data.tooltip = newValue } } public var attributedString: NSAttributedString { @@ -237,11 +203,7 @@ extension IMEState { } public var tooltipBackupForInputting: String { - get { - data.tooltipBackupForInputting - } - set { - data.tooltipBackupForInputting = newValue - } + get { data.tooltipBackupForInputting } + set { data.tooltipBackupForInputting = newValue } } } diff --git a/Source/Modules/IMEStateData.swift b/Source/Modules/IMEStateData.swift index 9c7b761f..8fa4ccfc 100644 --- a/Source/Modules/IMEStateData.swift +++ b/Source/Modules/IMEStateData.swift @@ -6,10 +6,11 @@ // marks, or product names of Contributor, except as required to fulfill notice // requirements defined in MIT License. +import Shared import Tekkon import TooltipUI -public struct StateData { +public struct StateData: StateDataProtocol { private static var minCandidateLength: Int { PrefMgr.shared.allowBoostingSingleKanjiAsUserPhrase ? 1 : 2 } @@ -18,8 +19,8 @@ public struct StateData { Self.minCandidateLength...PrefMgr.shared.maxCandidateLength } - var displayedText: String = "" - var displayedTextConverted: String { + public var displayedText: String = "" + public var displayedTextConverted: String { /// 先做繁簡轉換 var result = ChineseConverter.kanjiConversionIfRequired(displayedText) if result.utf16.count != displayedText.utf16.count @@ -32,19 +33,19 @@ public struct StateData { // MARK: Cursor & Marker & Range for UTF8 - var cursor: Int = 0 { + public var cursor: Int = 0 { didSet { cursor = min(max(cursor, 0), displayedText.count) } } - var marker: Int = 0 { + public var marker: Int = 0 { didSet { marker = min(max(marker, 0), displayedText.count) } } - var markedRange: Range { + public var markedRange: Range { min(cursor, marker).. { + public var u16MarkedRange: Range { min(u16Cursor, u16Marker)..