IMEState // Get marking attributes from SessionCtl.
This commit is contained in:
parent
3b85bd6d7d
commit
1e27947579
|
@ -7,6 +7,7 @@
|
|||
// requirements defined in MIT License.
|
||||
|
||||
import Cocoa
|
||||
import InputMethodKit
|
||||
|
||||
// 所有 IMEState 均遵守該協定:
|
||||
public protocol IMEStateProtocol {
|
||||
|
@ -32,6 +33,7 @@ public protocol IMEStateProtocol {
|
|||
var u16Cursor: Int { get }
|
||||
var cursor: Int { get set }
|
||||
var marker: Int { get set }
|
||||
func attributedString(for session: IMKInputController) -> NSAttributedString
|
||||
}
|
||||
|
||||
public protocol IMEStateDataProtocol {
|
||||
|
@ -57,4 +59,7 @@ public protocol IMEStateDataProtocol {
|
|||
var userPhraseKVPair: (keyArray: [String], value: String) { get }
|
||||
var tooltipColorState: TooltipColorState { get set }
|
||||
mutating func updateTooltipForMarking()
|
||||
func attributedStringNormal(for session: IMKInputController) -> NSAttributedString
|
||||
func attributedStringMarking(for session: IMKInputController) -> NSAttributedString
|
||||
func attributedStringPlaceholder(for session: IMKInputController) -> NSAttributedString
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import InputMethodKit
|
||||
import LangModelAssembly
|
||||
import Shared
|
||||
|
||||
|
@ -197,6 +198,14 @@ public extension IMEState {
|
|||
}
|
||||
}
|
||||
|
||||
func attributedString(for session: IMKInputController) -> NSAttributedString {
|
||||
switch type {
|
||||
case .ofMarking: return data.attributedStringMarking(for: session)
|
||||
case .ofAssociates, .ofSymbolTable: return data.attributedStringPlaceholder(for: session)
|
||||
default: return data.attributedStringNormal(for: session)
|
||||
}
|
||||
}
|
||||
|
||||
/// 該參數僅用作輔助判斷。在 InputHandler 內使用的話,必須再檢查 !compositor.isEmpty。
|
||||
var hasComposition: Bool {
|
||||
switch type {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import InputMethodKit
|
||||
import Shared
|
||||
import Tekkon
|
||||
import TooltipUI
|
||||
|
@ -173,6 +174,72 @@ public struct IMEStateData: IMEStateDataProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - AttributedString 生成器
|
||||
|
||||
public extension IMEStateData {
|
||||
func attributedStringNormal(for session: IMKInputController) -> NSAttributedString {
|
||||
/// 考慮到因為滑鼠點擊等其它行為導致的組字區內容遞交情況,
|
||||
/// 這裡對組字區內容也加上康熙字轉換或者 JIS 漢字轉換處理。
|
||||
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
|
||||
var newBegin = 0
|
||||
for (i, neta) in displayTextSegments.enumerated() {
|
||||
let rangeNow = NSRange(location: newBegin, length: neta.utf16.count)
|
||||
/// 不能用 .thick,否則會看不到游標。
|
||||
var theAttributes: [NSAttributedString.Key: Any]
|
||||
= session.mark(forStyle: kTSMHiliteConvertedText, at: rangeNow)
|
||||
as? [NSAttributedString.Key: Any]
|
||||
?? [.underlineStyle: NSUnderlineStyle.single.rawValue]
|
||||
theAttributes[.markedClauseSegment] = i
|
||||
attributedString.setAttributes(theAttributes, range: rangeNow)
|
||||
newBegin += neta.utf16.count
|
||||
}
|
||||
return attributedString
|
||||
}
|
||||
|
||||
func attributedStringMarking(for session: IMKInputController) -> NSAttributedString {
|
||||
/// 考慮到因為滑鼠點擊等其它行為導致的組字區內容遞交情況,
|
||||
/// 這裡對組字區內容也加上康熙字轉換或者 JIS 漢字轉換處理。
|
||||
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
|
||||
let u16MarkedRange = u16MarkedRange
|
||||
let range1 = NSRange(location: 0, length: u16MarkedRange.lowerBound)
|
||||
let range2 = NSRange(
|
||||
location: u16MarkedRange.lowerBound,
|
||||
length: u16MarkedRange.upperBound - u16MarkedRange.lowerBound
|
||||
)
|
||||
let range3 = NSRange(
|
||||
location: u16MarkedRange.upperBound,
|
||||
length: displayedTextConverted.utf16.count - u16MarkedRange.upperBound
|
||||
)
|
||||
var rawAttribute1: [NSAttributedString.Key: Any]
|
||||
= session.mark(forStyle: kTSMHiliteConvertedText, at: range1)
|
||||
as? [NSAttributedString.Key: Any]
|
||||
?? [.underlineStyle: NSUnderlineStyle.single.rawValue]
|
||||
rawAttribute1[.markedClauseSegment] = 0
|
||||
var rawAttribute2: [NSAttributedString.Key: Any]
|
||||
= session.mark(forStyle: kTSMHiliteSelectedConvertedText, at: range2)
|
||||
as? [NSAttributedString.Key: Any]
|
||||
?? [.underlineStyle: NSUnderlineStyle.thick.rawValue]
|
||||
rawAttribute2[.markedClauseSegment] = 1
|
||||
var rawAttribute3: [NSAttributedString.Key: Any]
|
||||
= session.mark(forStyle: kTSMHiliteConvertedText, at: range3)
|
||||
as? [NSAttributedString.Key: Any]
|
||||
?? [.underlineStyle: NSUnderlineStyle.single.rawValue]
|
||||
rawAttribute3[.markedClauseSegment] = 2
|
||||
attributedString.setAttributes(rawAttribute1, range: range1)
|
||||
attributedString.setAttributes(rawAttribute2, range: range2)
|
||||
attributedString.setAttributes(rawAttribute3, range: range3)
|
||||
return attributedString
|
||||
}
|
||||
|
||||
func attributedStringPlaceholder(for session: IMKInputController) -> NSAttributedString {
|
||||
let attributes: [NSAttributedString.Key: Any]
|
||||
= session.mark(forStyle: kTSMHiliteSelectedRawText, at: .zero)
|
||||
as? [NSAttributedString.Key: Any]
|
||||
?? [.underlineStyle: NSUnderlineStyle.single.rawValue]
|
||||
return .init(string: " ", attributes: attributes)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - IMEState 工具函式
|
||||
|
||||
public extension IMEStateData {
|
||||
|
|
Loading…
Reference in New Issue