vChewing-macOS/Source/Modules/IMEState.swift

213 lines
8.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// (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 LangModelAssembly
import Shared
/// SessionCtl
///
/// Finite State Machine/
/// 使
/// 使
///
///
/// IMEState
///
///
/// IMEState
/// IMEState.ofMarking IMEState.ofInputting
///
/// (Constructor)
///
///
///
/// - .Deactivated: 使使
/// - .AssociatedPhrases:
/// 西 .NotEmpty
/// - .Empty: 使
///
/// - .Abortion: Empty
/// .Empty()
/// - .Committing:
/// - .NotEmpty:
/// - .Inputting: 使Compositor
/// - .Marking: 使
///
/// - .ChoosingCandidate: 使
/// - .SymbolTable:
public struct IMEState: IMEStateProtocol {
public var type: StateType = .ofEmpty
public var data: IMEStateDataProtocol = IMEStateData() as IMEStateDataProtocol
public var node: CandidateNode = .init(name: "")
public var isASCIIMode = false
public var isVerticalCandidateWindow = false
init(_ data: IMEStateDataProtocol = IMEStateData() as IMEStateDataProtocol, type: StateType = .ofEmpty) {
self.data = data
self.type = type
isVerticalTyping = SessionCtl.isVerticalTyping
}
init(
_ data: IMEStateDataProtocol = IMEStateData() as IMEStateDataProtocol, type: StateType = .ofEmpty,
node: CandidateNode
) {
self.data = data
self.type = type
self.node = node
self.data.candidates = node.members.map { ("", $0.name) }
}
}
// MARK: -
extension IMEState {
public static func ofDeactivated() -> IMEState { .init(type: .ofDeactivated) }
public static func ofEmpty() -> IMEState { .init(type: .ofEmpty) }
public static func ofAbortion() -> IMEState { .init(type: .ofAbortion) }
public static func ofCommitting(textToCommit: String) -> IMEState {
var result = IMEState(type: .ofCommitting)
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.candidates = candidates
return result
}
public static func ofNotEmpty(displayTextSegments: [String], cursor: Int) -> IMEState {
var result = IMEState(type: .ofNotEmpty)
// displayTextSegments
result.data.displayTextSegments = displayTextSegments.map {
if !SessionCtl.isVerticalTyping { return $0 }
guard PrefMgr.shared.hardenVerticalPunctuations else { return $0 }
var neta = $0
ChineseConverter.hardenVerticalPunctuations(target: &neta, convert: SessionCtl.isVerticalTyping)
return neta
}
result.data.cursor = cursor
result.data.marker = cursor
return result
}
public static func ofInputting(displayTextSegments: [String], cursor: Int) -> IMEState {
var result = Self.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
result.type = .ofInputting
return result
}
public static func ofMarking(
displayTextSegments: [String], markedReadings: [String], cursor: Int, marker: Int
)
-> IMEState
{
var result = Self.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
result.type = .ofMarking
result.data.marker = marker
result.data.markedReadings = markedReadings
result.data.updateTooltipForMarking()
return result
}
public static func ofCandidates(candidates: [(String, String)], displayTextSegments: [String], cursor: Int)
-> IMEState
{
var result = Self.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
result.type = .ofCandidates
result.data.candidates = candidates
return result
}
public static func ofSymbolTable(node: CandidateNode) -> IMEState {
var result = IMEState(type: .ofNotEmpty, node: node)
result.type = .ofSymbolTable
return result
}
}
// MARK: -
extension IMEState {
public var isFilterable: Bool { data.isFilterable }
public var isMarkedLengthValid: Bool { data.isMarkedLengthValid }
public var displayedText: String { data.displayedText }
public var displayedTextConverted: String { data.displayedTextConverted }
public var displayTextSegments: [String] { data.displayTextSegments }
public var markedRange: Range<Int> { data.markedRange }
public var u16MarkedRange: Range<Int> { data.u16MarkedRange }
public var u16Cursor: Int { data.u16Cursor }
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 = Self.ofInputting(displayTextSegments: data.displayTextSegments, cursor: data.cursor)
result.tooltip = data.tooltipBackupForInputting
result.isVerticalTyping = isVerticalTyping
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 }
}
public var tooltip: String {
get { data.tooltip }
set { data.tooltip = newValue }
}
public var attributedString: NSAttributedString {
switch type {
case .ofMarking: return data.attributedStringMarking
case .ofAssociates, .ofSymbolTable: return data.attributedStringPlaceholder
default: return data.attributedStringNormal
}
}
public var hasComposition: Bool {
switch type {
case .ofNotEmpty, .ofInputting, .ofMarking, .ofCandidates: return true
default: return false
}
}
public var isVerticalTyping: Bool {
get { data.isVerticalTyping }
set { data.isVerticalTyping = newValue }
}
public var isCandidateContainer: Bool {
switch type {
case .ofCandidates, .ofAssociates, .ofSymbolTable: return true
default: return false
}
}
public var tooltipBackupForInputting: String {
get { data.tooltipBackupForInputting }
set { data.tooltipBackupForInputting = newValue }
}
}