TDKCandidates // Optimize the horizontal layout.

This commit is contained in:
ShikiSuen 2023-02-05 14:59:15 +08:00
parent 0c50046426
commit f8d79b0e2e
7 changed files with 40 additions and 32 deletions

View File

@ -140,6 +140,10 @@ public class CandidateCellData: Hashable {
}
return result.charDescriptions.joined(separator: "\n")
}
public var minWidthToDrawInSwiftUI: Double {
Double(cellLength) + ((displayedText.count > 2) ? 0 : fontSizeKey + 0) + ceil(fontSizeCandidate * 0.4)
}
}
// MARK: - Contents specifically made for macOS 12 and newer.
@ -165,7 +169,7 @@ extension CandidateCellData {
.foregroundColor(.init(nsColor: fontColorCandidate)).lineLimit(1)
}
}.padding(3)
}
}.frame(minWidth: minWidthToDrawInSwiftUI, alignment: .leading)
}.fixedSize(horizontal: false, vertical: true)
}
return result
@ -202,7 +206,7 @@ extension CandidateCellData {
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
.foregroundColor(Color(white: 1)).lineLimit(1)
}.padding(3).foregroundColor(Color(white: 0.9))
}
}.frame(minWidth: minWidthToDrawInSwiftUI, alignment: .leading)
} else {
VStack(spacing: 0) {
HStack(spacing: 4) {
@ -212,7 +216,7 @@ extension CandidateCellData {
.font(.init(CTFontCreateUIFontForLanguage(.system, fontSizeCandidate, locale as CFString)!))
.foregroundColor(Color.primary).lineLimit(1)
}.padding(3).foregroundColor(Color(white: 0.9))
}
}.frame(minWidth: minWidthToDrawInSwiftUI, alignment: .leading)
}
}.fixedSize(horizontal: false, vertical: true)
}

View File

@ -33,7 +33,8 @@ public struct CandidatePool {
public var maxRowWidth: Int { Int(Double(maxRowCapacity + 3) * 2) * Int(ceil(CandidateCellData.unifiedSize)) }
public var maxWindowWidth: Double {
ceil(Double(maxRowCapacity + 3) * 2.7 * ceil(CandidateCellData.unifiedSize) * 1.2)
let testCell = CandidateCellData(key: "XX", displayedText: "XX", isSelected: false)
return Double(maxRowCapacity) * (testCell.minWidthToDrawInSwiftUI + ceil(CandidateCellData.unifiedSize * 0.5))
}
public var currentLineNumber: Int {
@ -158,7 +159,7 @@ public struct CandidatePool {
for (i, candidate) in candidateDataAll.enumerated() {
candidate.index = i
candidate.whichRow = candidateRows.count
let isOverflown: Bool = currentRow.map(\.cellLength).reduce(0, +) + candidate.cellLength > maxRowWidth
let isOverflown: Bool = currentRow.map(\.cellLength).reduce(0, +) > maxRowWidth
if isOverflown || currentRow.count == maxRowCapacity, !currentRow.isEmpty {
candidateRows.append(currentRow)
currentRow.removeAll()

View File

@ -15,11 +15,11 @@ import SwiftUI
@available(macOS 12, *)
struct CandidatePoolViewUIHorizontal_Previews: PreviewProvider {
@State static var testCandidates: [String] = [
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "八月", "中秋",
"二十四歲是學生", "二十四歲", "昏睡紅茶", "食雪漢", "意味深", "學生", "便乗",
"🐂🍺🐂🍺", "🐃🍺", "🐂🍺", "🐃🐂🍺🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺",
"山林", "風吹", "大地", "草枝", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "",
"迫真", "驚愕", "論證", "正論", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "便", "",
"", "", "",
]
static var thePool: CandidatePool {
var result = CandidatePool(candidates: testCandidates, rowCapacity: 6)
@ -62,14 +62,14 @@ public struct VwrCandidateHorizontal: View {
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .leading, spacing: 1.6) {
ForEach(thePool.rangeForCurrentPage, id: \.self) { rowIndex in
HStack(spacing: 10) {
HStack(spacing: ceil(CandidateCellData.unifiedSize * 0.35)) {
ForEach(Array(thePool.candidateLines[rowIndex]), id: \.self) { currentCandidate in
currentCandidate.attributedStringForSwiftUI.fixedSize()
.contentShape(Rectangle())
.frame(
maxWidth: .infinity,
alignment: .topLeading
)
.contentShape(Rectangle())
.onTapGesture { didSelectCandidateAt(currentCandidate.index) }
.contextMenu {
if controller?.delegate?.isCandidateContextMenuEnabled ?? false {
@ -91,7 +91,7 @@ public struct VwrCandidateHorizontal: View {
}
}
}
Spacer()
Spacer(minLength: Double.infinity)
}.frame(
minWidth: 0,
maxWidth: .infinity,
@ -103,8 +103,8 @@ public struct VwrCandidateHorizontal: View {
ForEach(thePool.rangeForLastPageBlanked, id: \.self) { _ in
HStack(spacing: 0) {
thePool.blankCell.attributedStringForSwiftUI
.frame(maxWidth: .infinity, alignment: .topLeading)
.contentShape(Rectangle())
.frame(maxWidth: .infinity, alignment: .topLeading)
Spacer()
}.frame(
minWidth: 0,

View File

@ -15,10 +15,11 @@ import SwiftUI
@available(macOS 12, *)
struct CandidatePoolViewUIVertical_Previews: PreviewProvider {
@State static var testCandidates: [String] = [
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "🐂🍺", "🐃🍺", "八月", "中秋",
"山林", "風吹", "大地", "草枝", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "",
"二十四歲是學生", "二十四歲", "昏睡紅茶", "食雪漢", "意味深", "學生", "便乗",
"🐂🍺🐂🍺", "🐃🍺", "🐂🍺", "🐃🐂🍺🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺",
"迫真", "驚愕", "論證", "正論", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "便", "",
"", "", "",
]
static var thePool: CandidatePool {
var result = CandidatePool(candidates: testCandidates, columnCapacity: 6, selectionKeys: "123456789")

View File

@ -16,11 +16,11 @@ import SwiftUIBackports
@available(macOS 10.15, *)
struct CandidatePoolViewUIHorizontalBackports_Previews: PreviewProvider {
@State static var testCandidates: [String] = [
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "八月", "中秋",
"二十四歲是學生", "二十四歲", "昏睡紅茶", "食雪漢", "意味深", "學生", "便乗",
"🐂🍺🐂🍺", "🐃🍺", "🐂🍺", "🐃🐂🍺🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺",
"山林", "風吹", "大地", "草枝", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "",
"迫真", "驚愕", "論證", "正論", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "便", "",
"", "", "",
]
static var thePool: CandidatePool {
var result = CandidatePool(candidates: testCandidates, rowCapacity: 6)
@ -63,14 +63,14 @@ public struct VwrCandidateHorizontalBackports: View {
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .leading, spacing: 1.6) {
ForEach(thePool.rangeForCurrentPage, id: \.self) { rowIndex in
HStack(spacing: 10) {
HStack(spacing: ceil(CandidateCellData.unifiedSize * 0.35)) {
ForEach(Array(thePool.candidateLines[rowIndex]), id: \.self) { currentCandidate in
currentCandidate.attributedStringForSwiftUIBackports.fixedSize()
.contentShape(Rectangle())
.frame(
maxWidth: .infinity,
alignment: .topLeading
)
.contentShape(Rectangle())
.onTapGesture { didSelectCandidateAt(currentCandidate.index) }
.contextMenu {
if controller?.delegate?.isCandidateContextMenuEnabled ?? false {
@ -92,7 +92,7 @@ public struct VwrCandidateHorizontalBackports: View {
}
}
}
Spacer()
Spacer(minLength: Double.infinity)
}.frame(
minWidth: 0,
maxWidth: .infinity,
@ -104,8 +104,8 @@ public struct VwrCandidateHorizontalBackports: View {
ForEach(thePool.rangeForLastPageBlanked, id: \.self) { _ in
HStack(spacing: 0) {
thePool.blankCell.attributedStringForSwiftUIBackports
.frame(maxWidth: .infinity, alignment: .topLeading)
.contentShape(Rectangle())
.frame(maxWidth: .infinity, alignment: .topLeading)
Spacer()
}.frame(
minWidth: 0,

View File

@ -16,10 +16,11 @@ import SwiftUIBackports
@available(macOS 10.15, *)
struct CandidatePoolViewUIVerticalBackports_Previews: PreviewProvider {
@State static var testCandidates: [String] = [
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "🐂🍺", "🐃🍺", "八月", "中秋",
"山林", "風吹", "大地", "草枝", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "",
"二十四歲是學生", "二十四歲", "昏睡紅茶", "食雪漢", "意味深", "學生", "便乗",
"🐂🍺🐂🍺", "🐃🍺", "🐂🍺", "🐃🐂🍺🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺",
"迫真", "驚愕", "論證", "正論", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "便", "",
"", "", "",
]
static var thePool: CandidatePool {
var result = CandidatePool(candidates: testCandidates, columnCapacity: 6, selectionKeys: "123456789")

View File

@ -13,9 +13,10 @@ import XCTest
final class CandidatePoolTests: XCTestCase {
let testCandidates: [String] = [
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "八月", "中秋",
"山林", "風吹", "大地", "草枝", "", "", "", "", "", "", "", "",
"", "", "", "",
"二十四歲是學生", "二十四歲", "昏睡紅茶", "食雪漢", "意味深", "學生", "便乗",
"迫真", "驚愕", "論證", "正論", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "便", "",
"", "", "",
]
func testPoolHorizontal() throws {