TDKCandidates // Nomenclature update & Add spanLength property.
This commit is contained in:
parent
9da9c12809
commit
a846fe48ac
|
@ -18,8 +18,9 @@ public class CandidateCellData: Hashable {
|
||||||
public var visualDimension: CGSize = .zero
|
public var visualDimension: CGSize = .zero
|
||||||
public var locale = ""
|
public var locale = ""
|
||||||
public static var unifiedSize: Double = 16
|
public static var unifiedSize: Double = 16
|
||||||
public var key: String
|
public var selectionKey: String
|
||||||
public var displayedText: String
|
public var displayedText: String
|
||||||
|
public var spanLength: Int
|
||||||
public var size: Double { Self.unifiedSize }
|
public var size: Double { Self.unifiedSize }
|
||||||
public var isHighlighted: Bool = false
|
public var isHighlighted: Bool = false
|
||||||
public var whichLine: Int = 0
|
public var whichLine: Int = 0
|
||||||
|
@ -38,18 +39,22 @@ public class CandidateCellData: Hashable {
|
||||||
: .init(red: 142 / 255, green: 142 / 255, blue: 147 / 255, alpha: 1)
|
: .init(red: 142 / 255, green: 142 / 255, blue: 147 / 255, alpha: 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(key: String, displayedText: String, isSelected: Bool = false) {
|
public init(
|
||||||
self.key = key
|
key: String, displayedText: String,
|
||||||
|
spanLength spanningLength: Int? = nil, isSelected: Bool = false
|
||||||
|
) {
|
||||||
|
selectionKey = key
|
||||||
self.displayedText = displayedText
|
self.displayedText = displayedText
|
||||||
|
spanLength = max(spanningLength ?? displayedText.count, 1)
|
||||||
isHighlighted = isSelected
|
isHighlighted = isSelected
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func == (lhs: CandidateCellData, rhs: CandidateCellData) -> Bool {
|
public static func == (lhs: CandidateCellData, rhs: CandidateCellData) -> Bool {
|
||||||
lhs.key == rhs.key && lhs.displayedText == rhs.displayedText
|
lhs.selectionKey == rhs.selectionKey && lhs.displayedText == rhs.displayedText
|
||||||
}
|
}
|
||||||
|
|
||||||
public func hash(into hasher: inout Hasher) {
|
public func hash(into hasher: inout Hasher) {
|
||||||
hasher.combine(key)
|
hasher.combine(selectionKey)
|
||||||
hasher.combine(displayedText)
|
hasher.combine(displayedText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +155,7 @@ public class CandidateCellData: Hashable {
|
||||||
.paragraphStyle: Self.sharedParagraphStyle,
|
.paragraphStyle: Self.sharedParagraphStyle,
|
||||||
.foregroundColor: fontColorKey,
|
.foregroundColor: fontColorKey,
|
||||||
]
|
]
|
||||||
let attrStrKey = NSAttributedString(string: key, attributes: attrKey)
|
let attrStrKey = NSAttributedString(string: selectionKey, attributes: attrKey)
|
||||||
return attrStrKey
|
return attrStrKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ public extension CandidateCellData {
|
||||||
themeColor.cornerRadius(6)
|
themeColor.cornerRadius(6)
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
HStack(spacing: 4) {
|
HStack(spacing: 4) {
|
||||||
Text(verbatim: key).font(.custom("Menlo", size: fontSizeKey))
|
Text(verbatim: selectionKey).font(.custom("Menlo", size: fontSizeKey))
|
||||||
.foregroundColor(Color.white.opacity(0.8)).lineLimit(1)
|
.foregroundColor(Color.white.opacity(0.8)).lineLimit(1)
|
||||||
Text(verbatim: displayedText)
|
Text(verbatim: displayedText)
|
||||||
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
|
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
|
||||||
|
@ -44,7 +44,7 @@ public extension CandidateCellData {
|
||||||
} else {
|
} else {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
HStack(spacing: 4) {
|
HStack(spacing: 4) {
|
||||||
Text(verbatim: key).font(.custom("Menlo", size: fontSizeKey))
|
Text(verbatim: selectionKey).font(.custom("Menlo", size: fontSizeKey))
|
||||||
.foregroundColor(Color.secondary).lineLimit(1)
|
.foregroundColor(Color.secondary).lineLimit(1)
|
||||||
Text(verbatim: displayedText)
|
Text(verbatim: displayedText)
|
||||||
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
|
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
|
||||||
|
@ -66,7 +66,7 @@ public extension CandidateCellData {
|
||||||
}
|
}
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
HStack(spacing: 4) {
|
HStack(spacing: 4) {
|
||||||
Text(verbatim: key).font(.system(size: fontSizeKey).monospaced())
|
Text(verbatim: selectionKey).font(.system(size: fontSizeKey).monospaced())
|
||||||
.foregroundColor(.init(nsColor: fontColorKey)).lineLimit(1)
|
.foregroundColor(.init(nsColor: fontColorKey)).lineLimit(1)
|
||||||
Text(verbatim: displayedText)
|
Text(verbatim: displayedText)
|
||||||
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
|
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
|
||||||
|
|
|
@ -77,7 +77,7 @@ public struct CandidatePool {
|
||||||
/// - direction: 橫向排列還是縱向排列(預設情況下是縱向)。
|
/// - direction: 橫向排列還是縱向排列(預設情況下是縱向)。
|
||||||
/// - locale: 區域編碼。例:「zh-Hans」或「zh-Hant」。
|
/// - locale: 區域編碼。例:「zh-Hans」或「zh-Hant」。
|
||||||
public init(
|
public init(
|
||||||
candidates: [String], lines: Int = 3, selectionKeys: String = "123456789",
|
candidates: [([String], String)], lines: Int = 3, selectionKeys: String = "123456789",
|
||||||
layout: LayoutOrientation = .vertical, locale: String = ""
|
layout: LayoutOrientation = .vertical, locale: String = ""
|
||||||
) {
|
) {
|
||||||
self.layout = layout
|
self.layout = layout
|
||||||
|
@ -86,7 +86,9 @@ public struct CandidatePool {
|
||||||
shitCell = CandidateCellData(key: " ", displayedText: "💩", isSelected: false)
|
shitCell = CandidateCellData(key: " ", displayedText: "💩", isSelected: false)
|
||||||
blankCell.locale = locale
|
blankCell.locale = locale
|
||||||
self.selectionKeys = selectionKeys.isEmpty ? "123456789" : selectionKeys
|
self.selectionKeys = selectionKeys.isEmpty ? "123456789" : selectionKeys
|
||||||
var allCandidates = candidates.map { CandidateCellData(key: " ", displayedText: $0) }
|
var allCandidates = candidates.map {
|
||||||
|
CandidateCellData(key: " ", displayedText: $0.1, spanLength: $0.0.count)
|
||||||
|
}
|
||||||
if allCandidates.isEmpty { allCandidates.append(blankCell) }
|
if allCandidates.isEmpty { allCandidates.append(blankCell) }
|
||||||
candidateDataAll = allCandidates
|
candidateDataAll = allCandidates
|
||||||
var currentColumn: [CandidateCellData] = []
|
var currentColumn: [CandidateCellData] = []
|
||||||
|
@ -203,12 +205,12 @@ public extension CandidatePool {
|
||||||
for (i, candidateColumn) in candidateLines.enumerated() {
|
for (i, candidateColumn) in candidateLines.enumerated() {
|
||||||
if i != currentLineNumber {
|
if i != currentLineNumber {
|
||||||
candidateColumn.forEach {
|
candidateColumn.forEach {
|
||||||
$0.key = " "
|
$0.selectionKey = " "
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i, neta) in candidateColumn.enumerated() {
|
for (i, neta) in candidateColumn.enumerated() {
|
||||||
if neta.key.isEmpty { continue }
|
if neta.selectionKey.isEmpty { continue }
|
||||||
neta.key = selectionKeys.map(\.description)[i]
|
neta.selectionKey = selectionKeys.map(\.description)[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class CtlCandidateTDK: CtlCandidate, NSWindowDelegate {
|
||||||
CandidateCellData.unifiedSize = candidateFont.pointSize
|
CandidateCellData.unifiedSize = candidateFont.pointSize
|
||||||
guard let delegate = delegate else { return }
|
guard let delegate = delegate else { return }
|
||||||
Self.thePool = .init(
|
Self.thePool = .init(
|
||||||
candidates: delegate.candidatePairs(conv: true).map(\.1), lines: maxLinesPerPage,
|
candidates: delegate.candidatePairs(conv: true), lines: maxLinesPerPage,
|
||||||
selectionKeys: delegate.selectionKeys, layout: currentLayout.layoutTDK, locale: locale
|
selectionKeys: delegate.selectionKeys, layout: currentLayout.layoutTDK, locale: locale
|
||||||
)
|
)
|
||||||
Self.thePool.tooltip = tooltip
|
Self.thePool.tooltip = tooltip
|
||||||
|
|
|
@ -371,9 +371,16 @@ struct VwrCandidateTDK_Previews: PreviewProvider {
|
||||||
@State static var tooltip = "📼"
|
@State static var tooltip = "📼"
|
||||||
@State static var oldOS: Bool = true
|
@State static var oldOS: Bool = true
|
||||||
|
|
||||||
|
static var testCandidatesConverted: [([String], String)] {
|
||||||
|
testCandidates.map { candidate in
|
||||||
|
let firstValue: [String] = .init(repeating: "", count: candidate.count)
|
||||||
|
return (firstValue, candidate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static var thePoolX: CandidatePool {
|
static var thePoolX: CandidatePool {
|
||||||
var result = CandidatePool(
|
var result = CandidatePool(
|
||||||
candidates: testCandidates, lines: 4,
|
candidates: testCandidatesConverted, lines: 4,
|
||||||
selectionKeys: "123456", layout: .horizontal
|
selectionKeys: "123456", layout: .horizontal
|
||||||
)
|
)
|
||||||
result.reverseLookupResult = Self.reverseLookupResult
|
result.reverseLookupResult = Self.reverseLookupResult
|
||||||
|
@ -384,7 +391,7 @@ struct VwrCandidateTDK_Previews: PreviewProvider {
|
||||||
|
|
||||||
static var thePoolXS: CandidatePool {
|
static var thePoolXS: CandidatePool {
|
||||||
var result = CandidatePool(
|
var result = CandidatePool(
|
||||||
candidates: testCandidates, lines: 1,
|
candidates: testCandidatesConverted, lines: 1,
|
||||||
selectionKeys: "123456", layout: .horizontal
|
selectionKeys: "123456", layout: .horizontal
|
||||||
)
|
)
|
||||||
result.reverseLookupResult = Self.reverseLookupResult
|
result.reverseLookupResult = Self.reverseLookupResult
|
||||||
|
@ -395,7 +402,7 @@ struct VwrCandidateTDK_Previews: PreviewProvider {
|
||||||
|
|
||||||
static var thePoolY: CandidatePool {
|
static var thePoolY: CandidatePool {
|
||||||
var result = CandidatePool(
|
var result = CandidatePool(
|
||||||
candidates: testCandidates, lines: 4,
|
candidates: testCandidatesConverted, lines: 4,
|
||||||
selectionKeys: "123456", layout: .vertical
|
selectionKeys: "123456", layout: .vertical
|
||||||
)
|
)
|
||||||
result.reverseLookupResult = Self.reverseLookupResult
|
result.reverseLookupResult = Self.reverseLookupResult
|
||||||
|
@ -407,7 +414,7 @@ struct VwrCandidateTDK_Previews: PreviewProvider {
|
||||||
|
|
||||||
static var thePoolYS: CandidatePool {
|
static var thePoolYS: CandidatePool {
|
||||||
var result = CandidatePool(
|
var result = CandidatePool(
|
||||||
candidates: testCandidates, lines: 1,
|
candidates: testCandidatesConverted, lines: 1,
|
||||||
selectionKeys: "123456", layout: .vertical
|
selectionKeys: "123456", layout: .vertical
|
||||||
)
|
)
|
||||||
result.reverseLookupResult = Self.reverseLookupResult
|
result.reverseLookupResult = Self.reverseLookupResult
|
||||||
|
|
|
@ -19,8 +19,17 @@ final class CandidatePoolTests: XCTestCase {
|
||||||
"嗯", "哼", "啊",
|
"嗯", "哼", "啊",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
var testCandidatesConverted: [([String], String)] {
|
||||||
|
testCandidates.map { candidate in
|
||||||
|
let firstValue: [String] = .init(repeating: "", count: candidate.count)
|
||||||
|
return (firstValue, candidate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testPoolHorizontal() throws {
|
func testPoolHorizontal() throws {
|
||||||
let pool = CandidatePool(candidates: testCandidates, selectionKeys: "123456", layout: .horizontal)
|
let pool = CandidatePool(
|
||||||
|
candidates: testCandidatesConverted, selectionKeys: "123456", layout: .horizontal
|
||||||
|
)
|
||||||
var strOutput = ""
|
var strOutput = ""
|
||||||
pool.candidateLines.forEach {
|
pool.candidateLines.forEach {
|
||||||
$0.forEach {
|
$0.forEach {
|
||||||
|
@ -33,7 +42,9 @@ final class CandidatePoolTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPoolVertical() throws {
|
func testPoolVertical() throws {
|
||||||
let pool = CandidatePool(candidates: testCandidates, selectionKeys: "123456", layout: .vertical)
|
let pool = CandidatePool(
|
||||||
|
candidates: testCandidatesConverted, selectionKeys: "123456", layout: .vertical
|
||||||
|
)
|
||||||
var strOutput = ""
|
var strOutput = ""
|
||||||
pool.candidateLines.forEach {
|
pool.candidateLines.forEach {
|
||||||
$0.forEach {
|
$0.forEach {
|
||||||
|
|
Loading…
Reference in New Issue