2.8.0 SP2 // Vertical TDKCandidates, etc. Merge PR #154 from upd/2.8.0sp2
This commit is contained in:
commit
4257bcace0
|
@ -0,0 +1,37 @@
|
||||||
|
// (c) 2022 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 Shared
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@available(macOS 12, *)
|
||||||
|
extension CandidateCellData {
|
||||||
|
public var attributedStringForSwiftUI: some View {
|
||||||
|
var result: some View {
|
||||||
|
ZStack(alignment: .leading) {
|
||||||
|
if isSelected {
|
||||||
|
Color(nsColor: CandidateCellData.highlightBackground).ignoresSafeArea().cornerRadius(6)
|
||||||
|
}
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
HStack(spacing: 4) {
|
||||||
|
if UserDefaults.standard.bool(forKey: UserDef.kHandleDefaultCandidateFontsByLangIdentifier.rawValue) {
|
||||||
|
Text(AttributedString(attributedStringHeader)).frame(width: CandidateCellData.unifiedSize / 2)
|
||||||
|
Text(AttributedString(attributedString))
|
||||||
|
} else {
|
||||||
|
Text(key).font(.system(size: fontSizeKey).monospaced())
|
||||||
|
.foregroundColor(.init(nsColor: fontColorKey)).lineLimit(1)
|
||||||
|
Text(displayedText).font(.system(size: fontSizeCandidate))
|
||||||
|
.foregroundColor(.init(nsColor: fontColorCandidate)).lineLimit(1)
|
||||||
|
}
|
||||||
|
}.padding(4)
|
||||||
|
}
|
||||||
|
}.fixedSize(horizontal: false, vertical: true)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,53 +12,105 @@ import Shared
|
||||||
/// 候選字窗會用到的資料池單位。
|
/// 候選字窗會用到的資料池單位。
|
||||||
public class CandidatePool {
|
public class CandidatePool {
|
||||||
public let blankCell = CandidateCellData(key: " ", displayedText: " ", isSelected: false)
|
public let blankCell = CandidateCellData(key: " ", displayedText: " ", isSelected: false)
|
||||||
public var currentRowNumber = 0
|
public private(set) var candidateDataAll: [CandidateCellData] = []
|
||||||
public var maximumLinesPerPage = 3
|
|
||||||
public private(set) var selectionKeys: String
|
public private(set) var selectionKeys: String
|
||||||
public private(set) var highlightedIndex: Int = 0
|
public private(set) var highlightedIndex: Int = 0
|
||||||
public private(set) var maxColumnCapacity: Int = 6
|
|
||||||
public private(set) var candidateDataAll: [CandidateCellData] = []
|
// 下述變數只有橫排選字窗才會用到
|
||||||
|
public var currentRowNumber = 0
|
||||||
|
public var maximumRowsPerPage = 3
|
||||||
|
public private(set) var maxRowCapacity: Int = 6
|
||||||
public private(set) var candidateRows: [[CandidateCellData]] = []
|
public private(set) var candidateRows: [[CandidateCellData]] = []
|
||||||
public var isVerticalLayout: Bool { maxColumnCapacity == 1 }
|
|
||||||
public var maxColumnWidth: Int { Int(Double(maxColumnCapacity + 3) * 2) * Int(ceil(CandidateCellData.unifiedSize)) }
|
// 下述變數只有縱排選字窗才會用到
|
||||||
|
public var currentColumnNumber = 0
|
||||||
|
public var maximumColumnsPerPage = 3
|
||||||
|
public private(set) var maxColumnCapacity: Int = 6
|
||||||
|
public private(set) var candidateColumns: [[CandidateCellData]] = []
|
||||||
|
|
||||||
|
// 動態變數
|
||||||
|
public var maxRowWidth: Int { Int(Double(maxRowCapacity + 3) * 2) * Int(ceil(CandidateCellData.unifiedSize)) }
|
||||||
public var maxWindowWidth: Double {
|
public var maxWindowWidth: Double {
|
||||||
ceil(Double(maxColumnCapacity + 3) * 2.7 * ceil(CandidateCellData.unifiedSize) * 1.2)
|
ceil(Double(maxRowCapacity + 3) * 2.7 * ceil(CandidateCellData.unifiedSize) * 1.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var rangeForCurrentPage: Range<Int> {
|
public var rangeForCurrentHorizontalPage: Range<Int> {
|
||||||
currentRowNumber..<min(candidateRows.count, currentRowNumber + maximumLinesPerPage)
|
currentRowNumber..<min(candidateRows.count, currentRowNumber + maximumRowsPerPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var rangeForLastPageBlanked: Range<Int> { 0..<(maximumLinesPerPage - rangeForCurrentPage.count) }
|
public var rangeForCurrentVerticalPage: Range<Int> {
|
||||||
|
currentColumnNumber..<min(candidateColumns.count, currentColumnNumber + maximumColumnsPerPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var rangeForLastHorizontalPageBlanked: Range<Int> {
|
||||||
|
0..<(maximumRowsPerPage - rangeForCurrentHorizontalPage.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var rangeForLastVerticalPageBlanked: Range<Int> {
|
||||||
|
0..<(maximumColumnsPerPage - rangeForCurrentVerticalPage.count)
|
||||||
|
}
|
||||||
|
|
||||||
public enum VerticalDirection {
|
public enum VerticalDirection {
|
||||||
case up
|
case up
|
||||||
case down
|
case down
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 初期化一個候選字池。
|
public enum HorizontalDirection {
|
||||||
|
case left
|
||||||
|
case right
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 初期化一個縱排候選字窗專用資料池。
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - candidates: 要塞入的候選字詞陣列。
|
/// - candidates: 要塞入的候選字詞陣列。
|
||||||
/// - columnCapacity: (第一行的最大候選字詞數量, 陣列畫面展開之後的每一行的最大候選字詞數量)。
|
/// - columnCapacity: (第一縱列的最大候選字詞數量, 陣列畫面展開之後的每一縱列的最大候選字詞數量)。
|
||||||
public init(candidates: [String], columnCapacity: Int = 6, selectionKeys: String = "123456789", locale: String = "") {
|
/// - selectionKeys: 選字鍵。
|
||||||
|
/// - locale: 區域編碼。例:「zh-Hans」或「zh-Hant」。
|
||||||
|
public init(candidates: [String], columnCapacity: Int, selectionKeys: String = "123456789", locale: String = "") {
|
||||||
maxColumnCapacity = max(1, columnCapacity)
|
maxColumnCapacity = max(1, columnCapacity)
|
||||||
self.selectionKeys = selectionKeys
|
self.selectionKeys = selectionKeys
|
||||||
candidateDataAll = candidates.map { .init(key: "0", displayedText: $0) }
|
candidateDataAll = candidates.map { .init(key: "0", displayedText: $0) }
|
||||||
var currentColumn: [CandidateCellData] = []
|
var currentColumn: [CandidateCellData] = []
|
||||||
for (i, candidate) in candidateDataAll.enumerated() {
|
for (i, candidate) in candidateDataAll.enumerated() {
|
||||||
candidate.index = i
|
candidate.index = i
|
||||||
candidate.whichRow = candidateRows.count
|
candidate.whichColumn = candidateColumns.count
|
||||||
let isOverflown: Bool = currentColumn.map(\.cellLength).reduce(0, +) + candidate.cellLength > maxColumnWidth
|
if currentColumn.count == maxColumnCapacity, !currentColumn.isEmpty {
|
||||||
if isOverflown || currentColumn.count == maxColumnCapacity, !currentColumn.isEmpty {
|
candidateColumns.append(currentColumn)
|
||||||
candidateRows.append(currentColumn)
|
|
||||||
currentColumn.removeAll()
|
currentColumn.removeAll()
|
||||||
candidate.whichRow += 1
|
candidate.whichColumn += 1
|
||||||
}
|
}
|
||||||
candidate.subIndex = currentColumn.count
|
candidate.subIndex = currentColumn.count
|
||||||
candidate.locale = locale
|
candidate.locale = locale
|
||||||
currentColumn.append(candidate)
|
currentColumn.append(candidate)
|
||||||
}
|
}
|
||||||
candidateRows.append(currentColumn)
|
candidateColumns.append(currentColumn)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 初期化一個橫排候選字窗專用資料池。
|
||||||
|
/// - Parameters:
|
||||||
|
/// - candidates: 要塞入的候選字詞陣列。
|
||||||
|
/// - rowCapacity: (第一橫行的最大候選字詞數量, 陣列畫面展開之後的每一橫行的最大候選字詞數量)。
|
||||||
|
/// - selectionKeys: 選字鍵。
|
||||||
|
/// - locale: 區域編碼。例:「zh-Hans」或「zh-Hant」。
|
||||||
|
public init(candidates: [String], rowCapacity: Int, selectionKeys: String = "123456789", locale: String = "") {
|
||||||
|
maxRowCapacity = max(1, rowCapacity)
|
||||||
|
self.selectionKeys = selectionKeys
|
||||||
|
candidateDataAll = candidates.map { .init(key: "0", displayedText: $0) }
|
||||||
|
var currentRow: [CandidateCellData] = []
|
||||||
|
for (i, candidate) in candidateDataAll.enumerated() {
|
||||||
|
candidate.index = i
|
||||||
|
candidate.whichRow = candidateRows.count
|
||||||
|
let isOverflown: Bool = currentRow.map(\.cellLength).reduce(0, +) + candidate.cellLength > maxRowWidth
|
||||||
|
if isOverflown || currentRow.count == maxRowCapacity, !currentRow.isEmpty {
|
||||||
|
candidateRows.append(currentRow)
|
||||||
|
currentRow.removeAll()
|
||||||
|
candidate.whichRow += 1
|
||||||
|
}
|
||||||
|
candidate.subIndex = currentRow.count
|
||||||
|
candidate.locale = locale
|
||||||
|
currentRow.append(candidate)
|
||||||
|
}
|
||||||
|
candidateRows.append(currentRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func selectNewNeighborRow(direction: VerticalDirection) {
|
public func selectNewNeighborRow(direction: VerticalDirection) {
|
||||||
|
@ -70,7 +122,7 @@ public class CandidatePool {
|
||||||
if candidateRows.isEmpty { break }
|
if candidateRows.isEmpty { break }
|
||||||
let firstRow = candidateRows[0]
|
let firstRow = candidateRows[0]
|
||||||
let newSubIndex = min(currentSubIndex, firstRow.count - 1)
|
let newSubIndex = min(currentSubIndex, firstRow.count - 1)
|
||||||
highlight(at: firstRow[newSubIndex].index)
|
highlightHorizontal(at: firstRow[newSubIndex].index)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if currentRowNumber >= candidateRows.count - 1 { currentRowNumber = candidateRows.count - 1 }
|
if currentRowNumber >= candidateRows.count - 1 { currentRowNumber = candidateRows.count - 1 }
|
||||||
|
@ -80,13 +132,13 @@ public class CandidatePool {
|
||||||
}
|
}
|
||||||
let targetRow = candidateRows[currentRowNumber - 1]
|
let targetRow = candidateRows[currentRowNumber - 1]
|
||||||
let newSubIndex = min(result, targetRow.count - 1)
|
let newSubIndex = min(result, targetRow.count - 1)
|
||||||
highlight(at: targetRow[newSubIndex].index)
|
highlightHorizontal(at: targetRow[newSubIndex].index)
|
||||||
case .down:
|
case .down:
|
||||||
if currentRowNumber >= candidateRows.count - 1 {
|
if currentRowNumber >= candidateRows.count - 1 {
|
||||||
if candidateRows.isEmpty { break }
|
if candidateRows.isEmpty { break }
|
||||||
let finalRow = candidateRows[candidateRows.count - 1]
|
let finalRow = candidateRows[candidateRows.count - 1]
|
||||||
let newSubIndex = min(currentSubIndex, finalRow.count - 1)
|
let newSubIndex = min(currentSubIndex, finalRow.count - 1)
|
||||||
highlight(at: finalRow[newSubIndex].index)
|
highlightHorizontal(at: finalRow[newSubIndex].index)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if candidateRows[currentRowNumber].count != candidateRows[currentRowNumber + 1].count {
|
if candidateRows[currentRowNumber].count != candidateRows[currentRowNumber + 1].count {
|
||||||
|
@ -95,11 +147,40 @@ public class CandidatePool {
|
||||||
}
|
}
|
||||||
let targetRow = candidateRows[currentRowNumber + 1]
|
let targetRow = candidateRows[currentRowNumber + 1]
|
||||||
let newSubIndex = min(result, targetRow.count - 1)
|
let newSubIndex = min(result, targetRow.count - 1)
|
||||||
highlight(at: targetRow[newSubIndex].index)
|
highlightHorizontal(at: targetRow[newSubIndex].index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func highlight(at indexSpecified: Int) {
|
public func selectNewNeighborColumn(direction: HorizontalDirection) {
|
||||||
|
let currentSubIndex = candidateDataAll[highlightedIndex].subIndex
|
||||||
|
switch direction {
|
||||||
|
case .left:
|
||||||
|
if currentColumnNumber <= 0 {
|
||||||
|
if candidateColumns.isEmpty { break }
|
||||||
|
let firstColumn = candidateColumns[0]
|
||||||
|
let newSubIndex = min(currentSubIndex, firstColumn.count - 1)
|
||||||
|
highlightVertical(at: firstColumn[newSubIndex].index)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if currentColumnNumber >= candidateColumns.count - 1 { currentColumnNumber = candidateColumns.count - 1 }
|
||||||
|
let targetColumn = candidateColumns[currentColumnNumber - 1]
|
||||||
|
let newSubIndex = min(currentSubIndex, targetColumn.count - 1)
|
||||||
|
highlightVertical(at: targetColumn[newSubIndex].index)
|
||||||
|
case .right:
|
||||||
|
if currentColumnNumber >= candidateColumns.count - 1 {
|
||||||
|
if candidateColumns.isEmpty { break }
|
||||||
|
let finalColumn = candidateColumns[candidateColumns.count - 1]
|
||||||
|
let newSubIndex = min(currentSubIndex, finalColumn.count - 1)
|
||||||
|
highlightVertical(at: finalColumn[newSubIndex].index)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let targetColumn = candidateColumns[currentColumnNumber + 1]
|
||||||
|
let newSubIndex = min(currentSubIndex, targetColumn.count - 1)
|
||||||
|
highlightVertical(at: targetColumn[newSubIndex].index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func highlightHorizontal(at indexSpecified: Int) {
|
||||||
var indexSpecified = indexSpecified
|
var indexSpecified = indexSpecified
|
||||||
highlightedIndex = indexSpecified
|
highlightedIndex = indexSpecified
|
||||||
if !(0..<candidateDataAll.count).contains(highlightedIndex) {
|
if !(0..<candidateDataAll.count).contains(highlightedIndex) {
|
||||||
|
@ -120,13 +201,48 @@ public class CandidatePool {
|
||||||
candidate.isSelected = (indexSpecified == i)
|
candidate.isSelected = (indexSpecified == i)
|
||||||
if candidate.isSelected { currentRowNumber = candidate.whichRow }
|
if candidate.isSelected { currentRowNumber = candidate.whichRow }
|
||||||
}
|
}
|
||||||
for (i, candidateColumn) in candidateRows.enumerated() {
|
for (i, candidateRow) in candidateRows.enumerated() {
|
||||||
if i != currentRowNumber {
|
if i != currentRowNumber {
|
||||||
|
candidateRow.forEach {
|
||||||
|
$0.key = " "
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i, neta) in candidateRow.enumerated() {
|
||||||
|
neta.key = selectionKeys.map { String($0) }[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func highlightVertical(at indexSpecified: Int) {
|
||||||
|
var indexSpecified = indexSpecified
|
||||||
|
highlightedIndex = indexSpecified
|
||||||
|
if !(0..<candidateDataAll.count).contains(highlightedIndex) {
|
||||||
|
NSSound.beep()
|
||||||
|
switch highlightedIndex {
|
||||||
|
case candidateDataAll.count...:
|
||||||
|
currentColumnNumber = candidateColumns.count - 1
|
||||||
|
highlightedIndex = max(0, candidateDataAll.count - 1)
|
||||||
|
indexSpecified = highlightedIndex
|
||||||
|
case ..<0:
|
||||||
|
highlightedIndex = 0
|
||||||
|
currentColumnNumber = 0
|
||||||
|
indexSpecified = highlightedIndex
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i, candidate) in candidateDataAll.enumerated() {
|
||||||
|
candidate.isSelected = (indexSpecified == i)
|
||||||
|
if candidate.isSelected { currentColumnNumber = candidate.whichColumn }
|
||||||
|
}
|
||||||
|
for (i, candidateColumn) in candidateColumns.enumerated() {
|
||||||
|
if i != currentColumnNumber {
|
||||||
candidateColumn.forEach {
|
candidateColumn.forEach {
|
||||||
$0.key = " "
|
$0.key = " "
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i, neta) in candidateColumn.enumerated() {
|
for (i, neta) in candidateColumn.enumerated() {
|
||||||
|
if neta.key.isEmpty { continue }
|
||||||
neta.key = selectionKeys.map { String($0) }[i]
|
neta.key = selectionKeys.map { String($0) }[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import Shared
|
||||||
|
|
||||||
open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
|
open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
|
||||||
open var hint: String = ""
|
open var hint: String = ""
|
||||||
open var showPageButtons: Bool = false
|
|
||||||
open var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
open var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
||||||
open var locale: String = ""
|
open var locale: String = ""
|
||||||
open var useLangIdentifier: Bool = false
|
open var useLangIdentifier: Bool = false
|
||||||
|
@ -121,6 +120,14 @@ open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
|
||||||
|
|
||||||
open var tooltip: String = ""
|
open var tooltip: String = ""
|
||||||
|
|
||||||
|
@discardableResult open func showNextLine() -> Bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult open func showPreviousLine() -> Bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
@discardableResult open func highlightNextCandidate() -> Bool {
|
@discardableResult open func highlightNextCandidate() -> Bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
// (c) 2022 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
|
|
||||||
import CocoaExtension
|
|
||||||
import Shared
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
@available(macOS 12, *)
|
|
||||||
public class CtlCandidateTDK: CtlCandidate {
|
|
||||||
public var thePool: CandidatePool = .init(candidates: [])
|
|
||||||
public var theView: VwrCandidateTDK { .init(controller: self, thePool: thePool, hint: hint) }
|
|
||||||
public required init(_ layout: NSUserInterfaceLayoutOrientation = .horizontal) {
|
|
||||||
var contentRect = NSRect(x: 128.0, y: 128.0, width: 0.0, height: 0.0)
|
|
||||||
let styleMask: NSWindow.StyleMask = [.nonactivatingPanel]
|
|
||||||
let panel = NSPanel(
|
|
||||||
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
|
||||||
)
|
|
||||||
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 2)
|
|
||||||
panel.hasShadow = true
|
|
||||||
panel.isOpaque = false
|
|
||||||
panel.backgroundColor = NSColor.clear
|
|
||||||
|
|
||||||
contentRect.origin = NSPoint.zero
|
|
||||||
|
|
||||||
super.init(layout)
|
|
||||||
window = panel
|
|
||||||
currentLayout = layout
|
|
||||||
reloadData()
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, unavailable)
|
|
||||||
required init?(coder _: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func reloadData() {
|
|
||||||
CandidateCellData.highlightBackground = highlightedColor()
|
|
||||||
CandidateCellData.unifiedSize = candidateFont.pointSize
|
|
||||||
guard let delegate = delegate else { return }
|
|
||||||
thePool = .init(
|
|
||||||
candidates: delegate.candidatePairs(conv: true).map(\.1),
|
|
||||||
selectionKeys: delegate.selectionKeys, locale: locale
|
|
||||||
)
|
|
||||||
thePool.highlight(at: 0)
|
|
||||||
updateDisplay()
|
|
||||||
}
|
|
||||||
|
|
||||||
override open func updateDisplay() {
|
|
||||||
DispatchQueue.main.async { [self] in
|
|
||||||
let newView = NSHostingView(rootView: theView.fixedSize())
|
|
||||||
let newSize = newView.fittingSize
|
|
||||||
var newFrame = NSRect.zero
|
|
||||||
if let window = window { newFrame = window.frame }
|
|
||||||
newFrame.size = newSize
|
|
||||||
window?.setFrame(newFrame, display: false)
|
|
||||||
window?.contentView = NSHostingView(rootView: theView.fixedSize())
|
|
||||||
window?.setContentSize(newSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult override public func showNextPage() -> Bool {
|
|
||||||
for _ in 0..<thePool.maximumLinesPerPage {
|
|
||||||
thePool.selectNewNeighborRow(direction: .down)
|
|
||||||
}
|
|
||||||
updateDisplay()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult override public func showPreviousPage() -> Bool {
|
|
||||||
for _ in 0..<thePool.maximumLinesPerPage {
|
|
||||||
thePool.selectNewNeighborRow(direction: .up)
|
|
||||||
}
|
|
||||||
updateDisplay()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult public func showNextLine() -> Bool {
|
|
||||||
thePool.selectNewNeighborRow(direction: .down)
|
|
||||||
updateDisplay()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult public func showPreviousLine() -> Bool {
|
|
||||||
thePool.selectNewNeighborRow(direction: .up)
|
|
||||||
updateDisplay()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult override public func highlightNextCandidate() -> Bool {
|
|
||||||
thePool.highlight(at: thePool.highlightedIndex + 1)
|
|
||||||
updateDisplay()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult override public func highlightPreviousCandidate() -> Bool {
|
|
||||||
thePool.highlight(at: thePool.highlightedIndex - 1)
|
|
||||||
updateDisplay()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func candidateIndexAtKeyLabelIndex(_ id: Int) -> Int {
|
|
||||||
let currentRow = thePool.candidateRows[thePool.currentRowNumber]
|
|
||||||
let actualID = max(0, min(id, currentRow.count - 1))
|
|
||||||
return thePool.candidateRows[thePool.currentRowNumber][actualID].index
|
|
||||||
}
|
|
||||||
|
|
||||||
override public var selectedCandidateIndex: Int {
|
|
||||||
get {
|
|
||||||
thePool.highlightedIndex
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
thePool.highlight(at: newValue)
|
|
||||||
updateDisplay()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,209 @@
|
||||||
|
// (c) 2022 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
|
||||||
|
import CocoaExtension
|
||||||
|
import Shared
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@available(macOS 12, *)
|
||||||
|
public class CtlCandidateTDK: CtlCandidate {
|
||||||
|
public var thePoolHorizontal: CandidatePool = .init(candidates: [], rowCapacity: 6)
|
||||||
|
public var theViewHorizontal: VwrCandidateHorizontal {
|
||||||
|
.init(controller: self, thePool: thePoolHorizontal, hint: hint)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var thePoolVertical: CandidatePool = .init(candidates: [], columnCapacity: 6)
|
||||||
|
public var theViewVertical: VwrCandidateVertical { .init(controller: self, thePool: thePoolVertical, hint: hint) }
|
||||||
|
public required init(_ layout: NSUserInterfaceLayoutOrientation = .horizontal) {
|
||||||
|
var contentRect = NSRect(x: 128.0, y: 128.0, width: 0.0, height: 0.0)
|
||||||
|
let styleMask: NSWindow.StyleMask = [.nonactivatingPanel]
|
||||||
|
let panel = NSPanel(
|
||||||
|
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||||
|
)
|
||||||
|
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 2)
|
||||||
|
panel.hasShadow = true
|
||||||
|
panel.isOpaque = false
|
||||||
|
panel.backgroundColor = NSColor.clear
|
||||||
|
|
||||||
|
contentRect.origin = NSPoint.zero
|
||||||
|
|
||||||
|
super.init(layout)
|
||||||
|
window = panel
|
||||||
|
currentLayout = layout
|
||||||
|
reloadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, unavailable)
|
||||||
|
required init?(coder _: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override public func reloadData() {
|
||||||
|
CandidateCellData.highlightBackground = highlightedColor()
|
||||||
|
CandidateCellData.unifiedSize = candidateFont.pointSize
|
||||||
|
guard let delegate = delegate else { return }
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
thePoolHorizontal = .init(
|
||||||
|
candidates: delegate.candidatePairs(conv: true).map(\.1), rowCapacity: 6,
|
||||||
|
selectionKeys: delegate.selectionKeys, locale: locale
|
||||||
|
)
|
||||||
|
thePoolHorizontal.highlightHorizontal(at: 0)
|
||||||
|
case .vertical:
|
||||||
|
thePoolVertical = .init(
|
||||||
|
candidates: delegate.candidatePairs(conv: true).map(\.1), columnCapacity: 6,
|
||||||
|
selectionKeys: delegate.selectionKeys, locale: locale
|
||||||
|
)
|
||||||
|
thePoolVertical.highlightVertical(at: 0)
|
||||||
|
@unknown default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func updateDisplay() {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
DispatchQueue.main.async { [self] in
|
||||||
|
let newView = NSHostingView(rootView: theViewHorizontal)
|
||||||
|
let newSize = newView.fittingSize
|
||||||
|
window?.contentView = newView
|
||||||
|
window?.setContentSize(newSize)
|
||||||
|
}
|
||||||
|
case .vertical:
|
||||||
|
DispatchQueue.main.async { [self] in
|
||||||
|
let newView = NSHostingView(rootView: theViewVertical)
|
||||||
|
let newSize = newView.fittingSize
|
||||||
|
window?.contentView = newView
|
||||||
|
window?.setContentSize(newSize)
|
||||||
|
}
|
||||||
|
@unknown default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult override public func showNextPage() -> Bool {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
for _ in 0..<thePoolHorizontal.maximumRowsPerPage {
|
||||||
|
thePoolHorizontal.selectNewNeighborRow(direction: .down)
|
||||||
|
}
|
||||||
|
case .vertical:
|
||||||
|
for _ in 0..<thePoolVertical.maximumColumnsPerPage {
|
||||||
|
thePoolVertical.selectNewNeighborColumn(direction: .right)
|
||||||
|
}
|
||||||
|
@unknown default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult override public func showPreviousPage() -> Bool {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
for _ in 0..<thePoolHorizontal.maximumRowsPerPage {
|
||||||
|
thePoolHorizontal.selectNewNeighborRow(direction: .up)
|
||||||
|
}
|
||||||
|
case .vertical:
|
||||||
|
for _ in 0..<thePoolVertical.maximumColumnsPerPage {
|
||||||
|
thePoolVertical.selectNewNeighborColumn(direction: .left)
|
||||||
|
}
|
||||||
|
@unknown default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult override public func showNextLine() -> Bool {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
thePoolHorizontal.selectNewNeighborRow(direction: .down)
|
||||||
|
case .vertical:
|
||||||
|
thePoolVertical.selectNewNeighborColumn(direction: .right)
|
||||||
|
@unknown default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult override public func showPreviousLine() -> Bool {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
thePoolHorizontal.selectNewNeighborRow(direction: .up)
|
||||||
|
case .vertical:
|
||||||
|
thePoolVertical.selectNewNeighborColumn(direction: .left)
|
||||||
|
@unknown default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult override public func highlightNextCandidate() -> Bool {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
thePoolHorizontal.highlightHorizontal(at: thePoolHorizontal.highlightedIndex + 1)
|
||||||
|
case .vertical:
|
||||||
|
thePoolVertical.highlightVertical(at: thePoolVertical.highlightedIndex + 1)
|
||||||
|
@unknown default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult override public func highlightPreviousCandidate() -> Bool {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
thePoolHorizontal.highlightHorizontal(at: thePoolHorizontal.highlightedIndex - 1)
|
||||||
|
case .vertical:
|
||||||
|
thePoolVertical.highlightVertical(at: thePoolVertical.highlightedIndex - 1)
|
||||||
|
@unknown default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override public func candidateIndexAtKeyLabelIndex(_ id: Int) -> Int {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal:
|
||||||
|
let currentRow = thePoolHorizontal.candidateRows[thePoolHorizontal.currentRowNumber]
|
||||||
|
let actualID = max(0, min(id, currentRow.count - 1))
|
||||||
|
return thePoolHorizontal.candidateRows[thePoolHorizontal.currentRowNumber][actualID].index
|
||||||
|
case .vertical:
|
||||||
|
let currentColumn = thePoolVertical.candidateColumns[thePoolVertical.currentColumnNumber]
|
||||||
|
let actualID = max(0, min(id, currentColumn.count - 1))
|
||||||
|
return thePoolVertical.candidateColumns[thePoolVertical.currentColumnNumber][actualID].index
|
||||||
|
@unknown default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public var selectedCandidateIndex: Int {
|
||||||
|
get {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal: return thePoolHorizontal.highlightedIndex
|
||||||
|
case .vertical: return thePoolVertical.highlightedIndex
|
||||||
|
@unknown default: return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
switch currentLayout {
|
||||||
|
case .horizontal: thePoolHorizontal.highlightHorizontal(at: newValue)
|
||||||
|
case .vertical: thePoolVertical.highlightVertical(at: newValue)
|
||||||
|
@unknown default: return
|
||||||
|
}
|
||||||
|
updateDisplay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,27 +13,28 @@ import SwiftUI
|
||||||
// MARK: - Some useless tests
|
// MARK: - Some useless tests
|
||||||
|
|
||||||
@available(macOS 12, *)
|
@available(macOS 12, *)
|
||||||
struct CandidatePoolViewUI_Previews: PreviewProvider {
|
struct CandidatePoolViewUIHorizontal_Previews: PreviewProvider {
|
||||||
@State static var testCandidates: [String] = [
|
@State static var testCandidates: [String] = [
|
||||||
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "八月", "中秋",
|
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "八月", "中秋",
|
||||||
|
"🐂🍺🐂🍺", "🐃🍺", "🐂🍺", "🐃🐂🍺🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺", "🐂🍺", "🐃🍺",
|
||||||
"山林", "風吹", "大地", "草枝", "八", "月", "中", "秋", "山", "林", "涼", "風",
|
"山林", "風吹", "大地", "草枝", "八", "月", "中", "秋", "山", "林", "涼", "風",
|
||||||
"吹", "大", "地", "草", "枝", "擺", "八", "月", "中", "秋", "山", "林", "涼", "風",
|
"吹", "大", "地", "草", "枝", "擺", "八", "月", "中", "秋", "山", "林", "涼", "風",
|
||||||
"吹", "大", "地", "草", "枝", "擺",
|
"吹", "大", "地", "草", "枝", "擺",
|
||||||
]
|
]
|
||||||
static var thePool: CandidatePool {
|
static var thePool: CandidatePool {
|
||||||
let result = CandidatePool(candidates: testCandidates, columnCapacity: 6)
|
let result = CandidatePool(candidates: testCandidates, rowCapacity: 6)
|
||||||
// 下一行待解決:無論這裡怎麼指定高亮選中項是哪一筆,其所在行都得被卷動到使用者眼前。
|
// 下一行待解決:無論這裡怎麼指定高亮選中項是哪一筆,其所在行都得被卷動到使用者眼前。
|
||||||
result.highlight(at: 14)
|
result.highlightHorizontal(at: 5)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
VwrCandidateTDK(controller: .init(.horizontal), thePool: thePool).fixedSize()
|
VwrCandidateHorizontal(controller: .init(.horizontal), thePool: thePool).fixedSize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 12, *)
|
@available(macOS 12, *)
|
||||||
public struct VwrCandidateTDK: View {
|
public struct VwrCandidateHorizontal: View {
|
||||||
public var controller: CtlCandidateTDK
|
public var controller: CtlCandidateTDK
|
||||||
@State public var thePool: CandidatePool
|
@State public var thePool: CandidatePool
|
||||||
@State public var hint: String = ""
|
@State public var hint: String = ""
|
||||||
|
@ -52,26 +53,28 @@ public struct VwrCandidateTDK: View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
ScrollView(.vertical, showsIndicators: true) {
|
ScrollView(.vertical, showsIndicators: true) {
|
||||||
VStack(alignment: .leading, spacing: 1.6) {
|
VStack(alignment: .leading, spacing: 1.6) {
|
||||||
ForEach(thePool.rangeForCurrentPage, id: \.self) { columnIndex in
|
ForEach(thePool.rangeForCurrentHorizontalPage, id: \.self) { rowIndex in
|
||||||
HStack(spacing: 10) {
|
HStack(spacing: 10) {
|
||||||
ForEach(Array(thePool.candidateRows[columnIndex]), id: \.self) { currentCandidate in
|
ForEach(Array(thePool.candidateRows[rowIndex]), id: \.self) { currentCandidate in
|
||||||
currentCandidate.attributedStringForSwiftUI.fixedSize()
|
currentCandidate.attributedStringForSwiftUI.fixedSize()
|
||||||
.frame(maxWidth: .infinity, alignment: .topLeading)
|
.frame(
|
||||||
|
maxWidth: .infinity,
|
||||||
|
alignment: .topLeading
|
||||||
|
)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onTapGesture { didSelectCandidateAt(currentCandidate.index) }
|
.onTapGesture { didSelectCandidateAt(currentCandidate.index) }
|
||||||
}
|
}
|
||||||
Spacer()
|
|
||||||
}.frame(
|
}.frame(
|
||||||
minWidth: 0,
|
minWidth: 0,
|
||||||
maxWidth: .infinity,
|
maxWidth: .infinity,
|
||||||
alignment: .topLeading
|
alignment: .topLeading
|
||||||
).id(columnIndex)
|
).id(rowIndex)
|
||||||
Divider()
|
Divider()
|
||||||
}
|
}
|
||||||
if thePool.maximumLinesPerPage - thePool.rangeForCurrentPage.count > 0 {
|
if thePool.maximumRowsPerPage - thePool.rangeForCurrentHorizontalPage.count > 0 {
|
||||||
ForEach(thePool.rangeForLastPageBlanked, id: \.self) { _ in
|
ForEach(thePool.rangeForLastHorizontalPageBlanked, id: \.self) { _ in
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
thePool.blankCell.attributedStringForSwiftUI.fixedSize()
|
thePool.blankCell.attributedStringForSwiftUI
|
||||||
.frame(maxWidth: .infinity, alignment: .topLeading)
|
.frame(maxWidth: .infinity, alignment: .topLeading)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
Spacer()
|
Spacer()
|
||||||
|
@ -87,41 +90,20 @@ public struct VwrCandidateTDK: View {
|
||||||
}
|
}
|
||||||
.fixedSize(horizontal: false, vertical: true).padding(5)
|
.fixedSize(horizontal: false, vertical: true).padding(5)
|
||||||
.background(Color(nsColor: NSColor.controlBackgroundColor).ignoresSafeArea())
|
.background(Color(nsColor: NSColor.controlBackgroundColor).ignoresSafeArea())
|
||||||
HStack(alignment: .bottom) {
|
ZStack(alignment: .leading) {
|
||||||
Text(hint).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(1)
|
Color(nsColor: hint.isEmpty ? .windowBackgroundColor : CandidateCellData.highlightBackground).ignoresSafeArea()
|
||||||
Spacer()
|
HStack(alignment: .bottom) {
|
||||||
Text(positionLabel).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(
|
Text(hint).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(1)
|
||||||
1)
|
Spacer()
|
||||||
}.padding(6).foregroundColor(.init(nsColor: .controlTextColor))
|
Text(positionLabel).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
||||||
.shadow(color: .init(nsColor: .textBackgroundColor), radius: 1)
|
.lineLimit(
|
||||||
|
1)
|
||||||
|
}
|
||||||
|
.padding(6).foregroundColor(
|
||||||
|
.init(nsColor: hint.isEmpty ? .controlTextColor : .selectedMenuItemTextColor.withAlphaComponent(0.9))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.frame(minWidth: thePool.maxWindowWidth, maxWidth: thePool.maxWindowWidth)
|
.frame(minWidth: thePool.maxWindowWidth, maxWidth: thePool.maxWindowWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 12, *)
|
|
||||||
extension CandidateCellData {
|
|
||||||
public var attributedStringForSwiftUI: some View {
|
|
||||||
var result: some View {
|
|
||||||
ZStack(alignment: .leading) {
|
|
||||||
if isSelected {
|
|
||||||
Color(nsColor: CandidateCellData.highlightBackground).ignoresSafeArea().cornerRadius(6)
|
|
||||||
}
|
|
||||||
VStack(spacing: 0) {
|
|
||||||
HStack(spacing: 4) {
|
|
||||||
if UserDefaults.standard.bool(forKey: UserDef.kHandleDefaultCandidateFontsByLangIdentifier.rawValue) {
|
|
||||||
Text(AttributedString(attributedStringHeader)).frame(width: CandidateCellData.unifiedSize / 2)
|
|
||||||
Text(AttributedString(attributedString))
|
|
||||||
} else {
|
|
||||||
Text(key).font(.system(size: fontSizeKey).monospaced())
|
|
||||||
.foregroundColor(.init(nsColor: fontColorKey)).lineLimit(1)
|
|
||||||
Text(displayedText).font(.system(size: fontSizeCandidate))
|
|
||||||
.foregroundColor(.init(nsColor: fontColorCandidate)).lineLimit(1)
|
|
||||||
}
|
|
||||||
}.padding(4)
|
|
||||||
}
|
|
||||||
}.fixedSize(horizontal: false, vertical: true)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
// (c) 2022 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
|
||||||
|
import Shared
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
// MARK: - Some useless tests
|
||||||
|
|
||||||
|
@available(macOS 12, *)
|
||||||
|
struct CandidatePoolViewUIVertical_Previews: PreviewProvider {
|
||||||
|
@State static var testCandidates: [String] = [
|
||||||
|
"八月中秋山林涼", "八月中秋", "風吹大地", "山林涼", "草枝擺", "🐂🍺", "🐃🍺", "八月", "中秋",
|
||||||
|
"山林", "風吹", "大地", "草枝", "八", "月", "中", "秋", "山", "林", "涼", "風",
|
||||||
|
"吹", "大", "地", "草", "枝", "擺", "八", "月", "中", "秋", "山", "林", "涼", "風",
|
||||||
|
"吹", "大", "地", "草", "枝", "擺",
|
||||||
|
]
|
||||||
|
static var thePool: CandidatePool {
|
||||||
|
let result = CandidatePool(candidates: testCandidates, columnCapacity: 6, selectionKeys: "123456789")
|
||||||
|
// 下一行待解決:無論這裡怎麼指定高亮選中項是哪一筆,其所在行都得被卷動到使用者眼前。
|
||||||
|
result.highlightVertical(at: 5)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
VwrCandidateVertical(controller: .init(.horizontal), thePool: thePool).fixedSize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 12, *)
|
||||||
|
public struct VwrCandidateVertical: View {
|
||||||
|
public var controller: CtlCandidateTDK
|
||||||
|
@State public var thePool: CandidatePool
|
||||||
|
@State public var hint: String = ""
|
||||||
|
|
||||||
|
private var positionLabel: String {
|
||||||
|
(thePool.highlightedIndex + 1).description + "/" + thePool.candidateDataAll.count.description
|
||||||
|
}
|
||||||
|
|
||||||
|
private func didSelectCandidateAt(_ pos: Int) {
|
||||||
|
if let delegate = controller.delegate {
|
||||||
|
delegate.candidatePairSelected(at: pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
ScrollView(.horizontal, showsIndicators: true) {
|
||||||
|
HStack(alignment: .top, spacing: 10) {
|
||||||
|
ForEach(thePool.rangeForCurrentVerticalPage, id: \.self) { columnIndex in
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
ForEach(Array(thePool.candidateColumns[columnIndex]), id: \.self) { currentCandidate in
|
||||||
|
HStack(spacing: 0) {
|
||||||
|
currentCandidate.attributedStringForSwiftUI.fixedSize(horizontal: false, vertical: true)
|
||||||
|
.frame(
|
||||||
|
maxWidth: .infinity,
|
||||||
|
alignment: .topLeading
|
||||||
|
)
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
.onTapGesture { didSelectCandidateAt(currentCandidate.index) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.frame(
|
||||||
|
minWidth: Double(CandidateCellData.unifiedSize * 5),
|
||||||
|
alignment: .topLeading
|
||||||
|
).id(columnIndex)
|
||||||
|
Divider()
|
||||||
|
}
|
||||||
|
if thePool.maximumColumnsPerPage - thePool.rangeForCurrentVerticalPage.count > 0 {
|
||||||
|
ForEach(thePool.rangeForLastVerticalPageBlanked, id: \.self) { _ in
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
ForEach(0..<thePool.maxColumnCapacity, id: \.self) { _ in
|
||||||
|
thePool.blankCell.attributedStringForSwiftUI.fixedSize()
|
||||||
|
.frame(width: Double(CandidateCellData.unifiedSize * 5), alignment: .topLeading)
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
}
|
||||||
|
}.frame(
|
||||||
|
minWidth: 0,
|
||||||
|
maxWidth: .infinity,
|
||||||
|
alignment: .topLeading
|
||||||
|
)
|
||||||
|
Divider()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fixedSize(horizontal: true, vertical: false).padding(5)
|
||||||
|
.background(Color(nsColor: NSColor.controlBackgroundColor).ignoresSafeArea())
|
||||||
|
ZStack(alignment: .leading) {
|
||||||
|
Color(nsColor: hint.isEmpty ? .windowBackgroundColor : CandidateCellData.highlightBackground).ignoresSafeArea()
|
||||||
|
HStack(alignment: .bottom) {
|
||||||
|
Text(hint).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold)).lineLimit(1)
|
||||||
|
Spacer()
|
||||||
|
Text(positionLabel).font(.system(size: max(CandidateCellData.unifiedSize * 0.7, 11), weight: .bold))
|
||||||
|
.lineLimit(
|
||||||
|
1)
|
||||||
|
}
|
||||||
|
.padding(6).foregroundColor(
|
||||||
|
.init(nsColor: hint.isEmpty ? .controlTextColor : .selectedMenuItemTextColor.withAlphaComponent(0.9))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ final class CandidatePoolTests: XCTestCase {
|
||||||
]
|
]
|
||||||
|
|
||||||
func testPoolHorizontal() throws {
|
func testPoolHorizontal() throws {
|
||||||
let pool = CandidatePool(candidates: testCandidates, columnCapacity: 8)
|
let pool = CandidatePool(candidates: testCandidates, rowCapacity: 6)
|
||||||
var strOutput = ""
|
var strOutput = ""
|
||||||
pool.candidateRows.forEach {
|
pool.candidateRows.forEach {
|
||||||
$0.forEach {
|
$0.forEach {
|
||||||
|
@ -32,9 +32,9 @@ final class CandidatePoolTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPoolVertical() throws {
|
func testPoolVertical() throws {
|
||||||
let pool = CandidatePool(candidates: testCandidates, columnCapacity: 8)
|
let pool = CandidatePool(candidates: testCandidates, columnCapacity: 6)
|
||||||
var strOutput = ""
|
var strOutput = ""
|
||||||
pool.candidateRows.forEach {
|
pool.candidateColumns.forEach {
|
||||||
$0.forEach {
|
$0.forEach {
|
||||||
strOutput += $0.displayedText + ", "
|
strOutput += $0.displayedText + ", "
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,15 @@ let package = Package(
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(path: "../vChewing_CocoaExtension")
|
.package(path: "../vChewing_CocoaExtension"),
|
||||||
|
.package(path: "../vChewing_SwiftExtension")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
name: "Shared",
|
name: "Shared",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension")
|
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"),
|
||||||
|
.product(name: "SwiftExtension", package: "vChewing_SwiftExtension")
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -25,7 +25,8 @@ public class CandidateCellData: Hashable {
|
||||||
public var displayedText: String
|
public var displayedText: String
|
||||||
public var size: Double { Self.unifiedSize }
|
public var size: Double { Self.unifiedSize }
|
||||||
public var isSelected: Bool = false
|
public var isSelected: Bool = false
|
||||||
public var whichRow: Int = 0
|
public var whichRow: Int = 0 // 橫排選字窗專用
|
||||||
|
public var whichColumn: Int = 0 // 縱排選字窗專用
|
||||||
public var index: Int = 0
|
public var index: Int = 0
|
||||||
public var subIndex: Int = 0
|
public var subIndex: Int = 0
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ public class CandidateCellData: Hashable {
|
||||||
let rect = attributedStringForLengthCalculation.boundingRect(
|
let rect = attributedStringForLengthCalculation.boundingRect(
|
||||||
with: NSSize(width: 1600.0, height: 1600.0), options: [.usesLineFragmentOrigin]
|
with: NSSize(width: 1600.0, height: 1600.0), options: [.usesLineFragmentOrigin]
|
||||||
)
|
)
|
||||||
let rawResult = ceil(rect.width + size / size)
|
let rawResult = ceil(rect.width)
|
||||||
return Int(rawResult)
|
return Int(rawResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +74,16 @@ public class CandidateCellData: Hashable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public var attributedStringForLengthCalculation: NSAttributedString {
|
public var attributedStringForLengthCalculation: NSAttributedString {
|
||||||
|
let paraStyleKey = NSMutableParagraphStyle()
|
||||||
|
paraStyleKey.setParagraphStyle(NSParagraphStyle.default)
|
||||||
|
paraStyleKey.alignment = .natural
|
||||||
|
let paraStyle = NSMutableParagraphStyle()
|
||||||
|
paraStyle.setParagraphStyle(NSParagraphStyle.default)
|
||||||
|
paraStyle.alignment = .natural
|
||||||
|
paraStyle.lineBreakMode = .byWordWrapping
|
||||||
let attrCandidate: [NSAttributedString.Key: AnyObject] = [
|
let attrCandidate: [NSAttributedString.Key: AnyObject] = [
|
||||||
.font: NSFont.monospacedDigitSystemFont(ofSize: size, weight: .regular)
|
.font: NSFont.monospacedDigitSystemFont(ofSize: size, weight: .regular),
|
||||||
|
.paragraphStyle: paraStyle,
|
||||||
]
|
]
|
||||||
let attrStrCandidate = NSMutableAttributedString(string: displayedText + " ", attributes: attrCandidate)
|
let attrStrCandidate = NSMutableAttributedString(string: displayedText + " ", attributes: attrCandidate)
|
||||||
return attrStrCandidate
|
return attrStrCandidate
|
||||||
|
@ -87,6 +96,7 @@ public class CandidateCellData: Hashable {
|
||||||
let paraStyle = NSMutableParagraphStyle()
|
let paraStyle = NSMutableParagraphStyle()
|
||||||
paraStyle.setParagraphStyle(NSParagraphStyle.default)
|
paraStyle.setParagraphStyle(NSParagraphStyle.default)
|
||||||
paraStyle.alignment = .natural
|
paraStyle.alignment = .natural
|
||||||
|
paraStyle.lineBreakMode = .byWordWrapping
|
||||||
var attrCandidate: [NSAttributedString.Key: AnyObject] = [
|
var attrCandidate: [NSAttributedString.Key: AnyObject] = [
|
||||||
.font: NSFont.monospacedDigitSystemFont(ofSize: size, weight: .regular),
|
.font: NSFont.monospacedDigitSystemFont(ofSize: size, weight: .regular),
|
||||||
.paragraphStyle: paraStyle,
|
.paragraphStyle: paraStyle,
|
||||||
|
|
|
@ -30,13 +30,14 @@ public protocol CtlCandidateProtocol {
|
||||||
var candidateFont: NSFont { get set }
|
var candidateFont: NSFont { get set }
|
||||||
var tooltip: String { get set }
|
var tooltip: String { get set }
|
||||||
var useLangIdentifier: Bool { get set }
|
var useLangIdentifier: Bool { get set }
|
||||||
var showPageButtons: Bool { get set }
|
|
||||||
|
|
||||||
init(_ layout: NSUserInterfaceLayoutOrientation)
|
init(_ layout: NSUserInterfaceLayoutOrientation)
|
||||||
func reloadData()
|
func reloadData()
|
||||||
func updateDisplay()
|
func updateDisplay()
|
||||||
func showNextPage() -> Bool
|
func showNextPage() -> Bool
|
||||||
func showPreviousPage() -> Bool
|
func showPreviousPage() -> Bool
|
||||||
|
func showNextLine() -> Bool
|
||||||
|
func showPreviousLine() -> Bool
|
||||||
func highlightNextCandidate() -> Bool
|
func highlightNextCandidate() -> Bool
|
||||||
func highlightPreviousCandidate() -> Bool
|
func highlightPreviousCandidate() -> Bool
|
||||||
func candidateIndexAtKeyLabelIndex(_: Int) -> Int
|
func candidateIndexAtKeyLabelIndex(_: Int) -> Int
|
||||||
|
|
|
@ -19,7 +19,7 @@ public protocol PrefMgrProtocol {
|
||||||
var keyboardParser: Int { get set }
|
var keyboardParser: Int { get set }
|
||||||
var basicKeyboardLayout: String { get set }
|
var basicKeyboardLayout: String { get set }
|
||||||
var alphanumericalKeyboardLayout: String { get set }
|
var alphanumericalKeyboardLayout: String { get set }
|
||||||
var showPageButtonsInCandidateWindow: Bool { get set }
|
var showNotificationsWhenTogglingCapsLock: Bool { get set }
|
||||||
var candidateListTextSize: Double { get set }
|
var candidateListTextSize: Double { get set }
|
||||||
var shouldAutoReloadUserDataFiles: Bool { get set }
|
var shouldAutoReloadUserDataFiles: Bool { get set }
|
||||||
var useRearCursorMode: Bool { get set }
|
var useRearCursorMode: Bool { get set }
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
// requirements defined in MIT License.
|
// requirements defined in MIT License.
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import SwiftExtension
|
||||||
|
|
||||||
// MARK: - UserDef Snapshot Manager
|
// MARK: - UserDef Snapshot Manager
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ public enum UserDef: String, CaseIterable {
|
||||||
case kKeyboardParser = "KeyboardParser"
|
case kKeyboardParser = "KeyboardParser"
|
||||||
case kBasicKeyboardLayout = "BasicKeyboardLayout"
|
case kBasicKeyboardLayout = "BasicKeyboardLayout"
|
||||||
case kAlphanumericalKeyboardLayout = "AlphanumericalKeyboardLayout"
|
case kAlphanumericalKeyboardLayout = "AlphanumericalKeyboardLayout"
|
||||||
case kShowPageButtonsInCandidateWindow = "ShowPageButtonsInCandidateWindow"
|
case kShowNotificationsWhenTogglingCapsLock = "ShowNotificationsWhenTogglingCapsLock"
|
||||||
case kCandidateListTextSize = "CandidateListTextSize"
|
case kCandidateListTextSize = "CandidateListTextSize"
|
||||||
case kAppleLanguages = "AppleLanguages"
|
case kAppleLanguages = "AppleLanguages"
|
||||||
case kShouldAutoReloadUserDataFiles = "ShouldAutoReloadUserDataFiles"
|
case kShouldAutoReloadUserDataFiles = "ShouldAutoReloadUserDataFiles"
|
||||||
|
@ -214,10 +215,10 @@ public enum CandidateKey {
|
||||||
return NSLocalizedString("There should not be duplicated keys.", comment: "")
|
return NSLocalizedString("There should not be duplicated keys.", comment: "")
|
||||||
case .tooShort:
|
case .tooShort:
|
||||||
return NSLocalizedString(
|
return NSLocalizedString(
|
||||||
"Please specify at least 4 candidate keys.", comment: ""
|
"Please specify at least 6 candidate keys.", comment: ""
|
||||||
)
|
)
|
||||||
case .tooLong:
|
case .tooLong:
|
||||||
return NSLocalizedString("Maximum 15 candidate keys allowed.", comment: "")
|
return NSLocalizedString("Maximum 9 candidate keys allowed.", comment: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,10 +234,10 @@ public enum CandidateKey {
|
||||||
if trimmed.contains(" ") {
|
if trimmed.contains(" ") {
|
||||||
throw CandidateKey.ErrorType.containSpace
|
throw CandidateKey.ErrorType.containSpace
|
||||||
}
|
}
|
||||||
if trimmed.count < 4 {
|
if trimmed.count < 6 {
|
||||||
throw CandidateKey.ErrorType.tooShort
|
throw CandidateKey.ErrorType.tooShort
|
||||||
}
|
}
|
||||||
if trimmed.count > 15 {
|
if trimmed.count > 9 {
|
||||||
throw CandidateKey.ErrorType.tooLong
|
throw CandidateKey.ErrorType.tooLong
|
||||||
}
|
}
|
||||||
let set = Set(Array(trimmed))
|
let set = Set(Array(trimmed))
|
||||||
|
|
|
@ -13,7 +13,7 @@ import Foundation
|
||||||
// Extend the RangeReplaceableCollection to allow it clean duplicated characters.
|
// Extend the RangeReplaceableCollection to allow it clean duplicated characters.
|
||||||
// Ref: https://stackoverflow.com/questions/25738817/
|
// Ref: https://stackoverflow.com/questions/25738817/
|
||||||
extension RangeReplaceableCollection where Element: Hashable {
|
extension RangeReplaceableCollection where Element: Hashable {
|
||||||
public var deduplicate: Self {
|
public var deduplicated: Self {
|
||||||
var set = Set<Element>()
|
var set = Set<Element>()
|
||||||
return filter { set.insert($0).inserted }
|
return filter { set.insert($0).inserted }
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,7 @@ public class KeyHandler {
|
||||||
Megrez.Compositor.KeyValuePaired(key: $0.0, value: $0.1.value)
|
Megrez.Compositor.KeyValuePaired(key: $0.0, value: $0.1.value)
|
||||||
}
|
}
|
||||||
arrCandidates = arrSuggestedCandidates.filter { arrCandidates.contains($0) } + arrCandidates
|
arrCandidates = arrSuggestedCandidates.filter { arrCandidates.contains($0) } + arrCandidates
|
||||||
arrCandidates = arrCandidates.deduplicate
|
arrCandidates = arrCandidates.deduplicated
|
||||||
arrCandidates = arrCandidates.stableSort { $0.key.split(separator: "-").count > $1.key.split(separator: "-").count }
|
arrCandidates = arrCandidates.stableSort { $0.key.split(separator: "-").count > $1.key.split(separator: "-").count }
|
||||||
return arrCandidates.map { ($0.key, $0.value) }
|
return arrCandidates.map { ($0.key, $0.value) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,8 @@ extension KeyHandler {
|
||||||
let updated: Bool =
|
let updated: Bool =
|
||||||
prefs.specifyShiftTabKeyBehavior
|
prefs.specifyShiftTabKeyBehavior
|
||||||
? (input.isShiftHold
|
? (input.isShiftHold
|
||||||
? ctlCandidate.showPreviousPage()
|
? ctlCandidate.showPreviousLine()
|
||||||
: ctlCandidate.showNextPage())
|
: ctlCandidate.showNextLine())
|
||||||
: (input.isShiftHold
|
: (input.isShiftHold
|
||||||
? ctlCandidate.highlightPreviousCandidate()
|
? ctlCandidate.highlightPreviousCandidate()
|
||||||
: ctlCandidate.highlightNextCandidate())
|
: ctlCandidate.highlightNextCandidate())
|
||||||
|
@ -92,9 +92,9 @@ extension KeyHandler {
|
||||||
prefs.specifyShiftSpaceKeyBehavior
|
prefs.specifyShiftSpaceKeyBehavior
|
||||||
? (input.isShiftHold
|
? (input.isShiftHold
|
||||||
? ctlCandidate.highlightNextCandidate()
|
? ctlCandidate.highlightNextCandidate()
|
||||||
: ctlCandidate.showNextPage())
|
: ctlCandidate.showNextLine())
|
||||||
: (input.isShiftHold
|
: (input.isShiftHold
|
||||||
? ctlCandidate.showNextPage()
|
? ctlCandidate.showNextLine()
|
||||||
: ctlCandidate.highlightNextCandidate())
|
: ctlCandidate.highlightNextCandidate())
|
||||||
if !updated {
|
if !updated {
|
||||||
errorCallback("A11C781F")
|
errorCallback("A11C781F")
|
||||||
|
@ -131,7 +131,7 @@ extension KeyHandler {
|
||||||
errorCallback("1145148D")
|
errorCallback("1145148D")
|
||||||
}
|
}
|
||||||
case .vertical:
|
case .vertical:
|
||||||
if !ctlCandidate.showPreviousPage() {
|
if !ctlCandidate.showPreviousLine() {
|
||||||
errorCallback("1919810D")
|
errorCallback("1919810D")
|
||||||
}
|
}
|
||||||
@unknown default:
|
@unknown default:
|
||||||
|
@ -149,7 +149,7 @@ extension KeyHandler {
|
||||||
errorCallback("9B65138D")
|
errorCallback("9B65138D")
|
||||||
}
|
}
|
||||||
case .vertical:
|
case .vertical:
|
||||||
if !ctlCandidate.showNextPage() {
|
if !ctlCandidate.showNextLine() {
|
||||||
errorCallback("9244908D")
|
errorCallback("9244908D")
|
||||||
}
|
}
|
||||||
@unknown default:
|
@unknown default:
|
||||||
|
@ -163,21 +163,8 @@ extension KeyHandler {
|
||||||
if input.isUp {
|
if input.isUp {
|
||||||
switch ctlCandidate.currentLayout {
|
switch ctlCandidate.currentLayout {
|
||||||
case .horizontal:
|
case .horizontal:
|
||||||
if #available(macOS 12, *) {
|
if !ctlCandidate.showPreviousLine() {
|
||||||
if let ctlCandidate = ctlCandidate as? CtlCandidateTDK {
|
errorCallback("9B614524")
|
||||||
ctlCandidate.showPreviousLine()
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
if !ctlCandidate.showPreviousPage() {
|
|
||||||
errorCallback("9B614524")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !ctlCandidate.showPreviousPage() {
|
|
||||||
errorCallback("9B614524")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case .vertical:
|
case .vertical:
|
||||||
if !ctlCandidate.highlightPreviousCandidate() {
|
if !ctlCandidate.highlightPreviousCandidate() {
|
||||||
|
@ -194,21 +181,9 @@ extension KeyHandler {
|
||||||
if input.isDown {
|
if input.isDown {
|
||||||
switch ctlCandidate.currentLayout {
|
switch ctlCandidate.currentLayout {
|
||||||
case .horizontal:
|
case .horizontal:
|
||||||
if #available(macOS 12, *) {
|
if !ctlCandidate.showNextLine() {
|
||||||
if let ctlCandidate = ctlCandidate as? CtlCandidateTDK {
|
errorCallback("92B990DD")
|
||||||
ctlCandidate.showNextLine()
|
break
|
||||||
break
|
|
||||||
} else {
|
|
||||||
if !ctlCandidate.showNextPage() {
|
|
||||||
errorCallback("92B990DD")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !ctlCandidate.showNextPage() {
|
|
||||||
errorCallback("92B990DD")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case .vertical:
|
case .vertical:
|
||||||
if !ctlCandidate.highlightNextCandidate() {
|
if !ctlCandidate.highlightNextCandidate() {
|
||||||
|
@ -322,15 +297,7 @@ extension KeyHandler {
|
||||||
|
|
||||||
if input.isSymbolMenuPhysicalKey {
|
if input.isSymbolMenuPhysicalKey {
|
||||||
var updated = true
|
var updated = true
|
||||||
if #available(macOS 12, *) {
|
updated = input.isShiftHold ? ctlCandidate.showPreviousLine() : ctlCandidate.showNextLine()
|
||||||
if let ctlCandidate = ctlCandidate as? CtlCandidateTDK {
|
|
||||||
updated = input.isShiftHold ? ctlCandidate.showPreviousLine() : ctlCandidate.showNextLine()
|
|
||||||
} else {
|
|
||||||
updated = input.isShiftHold ? ctlCandidate.showPreviousPage() : ctlCandidate.showNextPage()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updated = input.isShiftHold ? ctlCandidate.showPreviousPage() : ctlCandidate.showNextPage()
|
|
||||||
}
|
|
||||||
if !updated {
|
if !updated {
|
||||||
errorCallback("66F3477B")
|
errorCallback("66F3477B")
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,8 @@ public class PrefMgr: PrefMgrProtocol {
|
||||||
)
|
)
|
||||||
public var alphanumericalKeyboardLayout: String
|
public var alphanumericalKeyboardLayout: String
|
||||||
|
|
||||||
@AppProperty(key: UserDef.kShowPageButtonsInCandidateWindow.rawValue, defaultValue: true)
|
@AppProperty(key: UserDef.kShowNotificationsWhenTogglingCapsLock.rawValue, defaultValue: true)
|
||||||
public var showPageButtonsInCandidateWindow: Bool
|
public var showNotificationsWhenTogglingCapsLock: Bool
|
||||||
|
|
||||||
@AppProperty(key: UserDef.kCandidateListTextSize.rawValue, defaultValue: 18)
|
@AppProperty(key: UserDef.kCandidateListTextSize.rawValue, defaultValue: 18)
|
||||||
public var candidateListTextSize: Double {
|
public var candidateListTextSize: Double {
|
||||||
|
@ -233,7 +233,10 @@ public class PrefMgr: PrefMgrProtocol {
|
||||||
@AppProperty(key: UserDef.kCandidateKeys.rawValue, defaultValue: kDefaultCandidateKeys)
|
@AppProperty(key: UserDef.kCandidateKeys.rawValue, defaultValue: kDefaultCandidateKeys)
|
||||||
public var candidateKeys: String {
|
public var candidateKeys: String {
|
||||||
didSet {
|
didSet {
|
||||||
if useIMKCandidateWindow {
|
if candidateKeys != candidateKeys.deduplicated {
|
||||||
|
candidateKeys = candidateKeys.deduplicated
|
||||||
|
}
|
||||||
|
if !(6...9).contains(candidateKeys.count) {
|
||||||
candidateKeys = Self.kDefaultCandidateKeys
|
candidateKeys = Self.kDefaultCandidateKeys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ extension PrefMgr {
|
||||||
disableShiftTogglingAlphanumericalMode = false
|
disableShiftTogglingAlphanumericalMode = false
|
||||||
togglingAlphanumericalModeWithLShift = false
|
togglingAlphanumericalModeWithLShift = false
|
||||||
}
|
}
|
||||||
|
// 自動糾正選字鍵 (利用其 didSet 特性)
|
||||||
|
candidateKeys = candidateKeys
|
||||||
// 客體黑名單自動排序去重複。
|
// 客體黑名單自動排序去重複。
|
||||||
clientsIMKTextInputIncapable = Array(Set(clientsIMKTextInputIncapable)).sorted()
|
clientsIMKTextInputIncapable = Array(Set(clientsIMKTextInputIncapable)).sorted()
|
||||||
// 注拼槽注音排列選項糾錯。
|
// 注拼槽注音排列選項糾錯。
|
||||||
|
|
|
@ -47,7 +47,7 @@ class SessionCtl: IMKInputController {
|
||||||
|
|
||||||
// MARK: -
|
// MARK: -
|
||||||
|
|
||||||
/// 當前 CapsLock 按鍵是否被摁下。
|
/// 當前 Caps Lock 按鍵是否被摁下。
|
||||||
var isCapsLocked: Bool { NSEvent.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock) }
|
var isCapsLocked: Bool { NSEvent.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock) }
|
||||||
|
|
||||||
/// 當前這個 SessionCtl 副本是否處於英數輸入模式。
|
/// 當前這個 SessionCtl 副本是否處於英數輸入模式。
|
||||||
|
@ -68,7 +68,7 @@ class SessionCtl: IMKInputController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shift 按鍵事件分析器的副本。
|
/// Shift 按鍵事件分析器的副本。
|
||||||
/// - Remark: 警告:該工具必須為 Struct 且全專案只能有一個唯一初期化副本。否則會在動 CapsLock 的時候誤以為是在摁 Shift。
|
/// - Remark: 警告:該工具必須為 Struct 且全專案只能有一個唯一初期化副本。否則會在動 Caps Lock 的時候誤以為是在摁 Shift。
|
||||||
static var theShiftKeyDetector = ShiftKeyUpChecker(useLShift: PrefMgr.shared.togglingAlphanumericalModeWithLShift)
|
static var theShiftKeyDetector = ShiftKeyUpChecker(useLShift: PrefMgr.shared.togglingAlphanumericalModeWithLShift)
|
||||||
|
|
||||||
/// `handle(event:)` 會利用這個參數判定某次 Shift 按鍵是否用來切換中英文輸入。
|
/// `handle(event:)` 會利用這個參數判定某次 Shift 按鍵是否用來切換中英文輸入。
|
||||||
|
@ -170,7 +170,7 @@ extension SessionCtl {
|
||||||
keyHandler.ensureKeyboardParser()
|
keyHandler.ensureKeyboardParser()
|
||||||
|
|
||||||
if isASCIIMode, !isCapsLocked, PrefMgr.shared.disableShiftTogglingAlphanumericalMode { isASCIIMode = false }
|
if isASCIIMode, !isCapsLocked, PrefMgr.shared.disableShiftTogglingAlphanumericalMode { isASCIIMode = false }
|
||||||
if isCapsLocked { isASCIIMode = isCapsLocked } // 同步 CapsLock 狀態。
|
if isCapsLocked { isASCIIMode = isCapsLocked } // 同步 Caps Lock 狀態。
|
||||||
|
|
||||||
/// 必須加上下述條件,否則會在每次切換至輸入法本體的視窗(比如偏好設定視窗)時會卡死。
|
/// 必須加上下述條件,否則會在每次切換至輸入法本體的視窗(比如偏好設定視窗)時會卡死。
|
||||||
/// 這是很多 macOS 副廠輸入法的常見失誤之處。
|
/// 這是很多 macOS 副廠輸入法的常見失誤之處。
|
||||||
|
|
|
@ -142,7 +142,6 @@ extension SessionCtl {
|
||||||
Self.ctlCandidateCurrent.hint = NSLocalizedString("Hold ⇧ to choose associates.", comment: "")
|
Self.ctlCandidateCurrent.hint = NSLocalizedString("Hold ⇧ to choose associates.", comment: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
Self.ctlCandidateCurrent.showPageButtons = PrefMgr.shared.showPageButtonsInCandidateWindow
|
|
||||||
Self.ctlCandidateCurrent.useLangIdentifier = PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier
|
Self.ctlCandidateCurrent.useLangIdentifier = PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier
|
||||||
Self.ctlCandidateCurrent.locale = {
|
Self.ctlCandidateCurrent.locale = {
|
||||||
switch inputMode {
|
switch inputMode {
|
||||||
|
|
|
@ -37,14 +37,18 @@ extension SessionCtl {
|
||||||
|
|
||||||
// Caps Lock 通知與切換處理。
|
// Caps Lock 通知與切換處理。
|
||||||
if event.type == .flagsChanged, event.keyCode == KeyCode.kCapsLock.rawValue {
|
if event.type == .flagsChanged, event.keyCode == KeyCode.kCapsLock.rawValue {
|
||||||
let isCapsLockTurnedOn = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock)
|
DispatchQueue.main.async {
|
||||||
let status = NSLocalizedString("NotificationSwitchASCII", comment: "")
|
let isCapsLockTurnedOn = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock)
|
||||||
Notifier.notify(
|
let status = NSLocalizedString("NotificationSwitchASCII", comment: "")
|
||||||
message: isCapsLockTurnedOn
|
if PrefMgr.shared.showNotificationsWhenTogglingCapsLock {
|
||||||
? "Caps Lock" + NSLocalizedString("Alphanumerical Input Mode", comment: "") + "\n" + status
|
Notifier.notify(
|
||||||
: NSLocalizedString("Chinese Input Mode", comment: "") + "\n" + status
|
message: isCapsLockTurnedOn
|
||||||
)
|
? "Caps Lock" + NSLocalizedString("Alphanumerical Input Mode", comment: "") + "\n" + status
|
||||||
isASCIIMode = isCapsLockTurnedOn
|
: NSLocalizedString("Chinese Input Mode", comment: "") + "\n" + status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.isASCIIMode = isCapsLockTurnedOn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用 Shift 開關半形英數模式,僅對 macOS 10.15 及之後的 macOS 有效。
|
// 用 Shift 開關半形英數模式,僅對 macOS 10.15 及之後的 macOS 有效。
|
||||||
|
|
|
@ -12,7 +12,6 @@ import Shared
|
||||||
/// 威注音自用的 IMKCandidates 型別。因為有用到 bridging header,所以無法弄成 Swift Package。
|
/// 威注音自用的 IMKCandidates 型別。因為有用到 bridging header,所以無法弄成 Swift Package。
|
||||||
public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
|
public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
|
||||||
public var hint: String = ""
|
public var hint: String = ""
|
||||||
public var showPageButtons: Bool = false
|
|
||||||
public var locale: String = ""
|
public var locale: String = ""
|
||||||
public var useLangIdentifier: Bool = false
|
public var useLangIdentifier: Bool = false
|
||||||
public var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
public var currentLayout: NSUserInterfaceLayoutOrientation = .horizontal
|
||||||
|
@ -149,6 +148,18 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 該函式會影響 IMK 選字窗。
|
||||||
|
public func showNextLine() -> Bool {
|
||||||
|
do { currentLayout == .vertical ? moveRight(self) : moveDown(self) }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 該函式會影響 IMK 選字窗。
|
||||||
|
public func showPreviousLine() -> Bool {
|
||||||
|
do { currentLayout == .vertical ? moveLeft(self) : moveUp(self) }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
public func candidateIndexAtKeyLabelIndex(_ index: Int) -> Int {
|
public func candidateIndexAtKeyLabelIndex(_ index: Int) -> Int {
|
||||||
guard let delegate = delegate else { return Int.max }
|
guard let delegate = delegate else { return Int.max }
|
||||||
let result = currentPageIndex * keyLabels.count + index
|
let result = currentPageIndex * keyLabels.count + index
|
||||||
|
|
|
@ -47,6 +47,8 @@ struct suiPrefPaneExperience: View {
|
||||||
forKey: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue)
|
forKey: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue)
|
||||||
@State private var selAlwaysShowTooltipTextsHorizontally = UserDefaults.standard.bool(
|
@State private var selAlwaysShowTooltipTextsHorizontally = UserDefaults.standard.bool(
|
||||||
forKey: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue)
|
forKey: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue)
|
||||||
|
@State private var selShowNotificationsWhenTogglingCapsLock = UserDefaults.standard.bool(
|
||||||
|
forKey: UserDef.kShowNotificationsWhenTogglingCapsLock.rawValue)
|
||||||
|
|
||||||
private let contentMaxHeight: Double = 440
|
private let contentMaxHeight: Double = 440
|
||||||
private let contentWidth: Double = {
|
private let contentWidth: Double = {
|
||||||
|
@ -195,6 +197,14 @@ struct suiPrefPaneExperience: View {
|
||||||
}
|
}
|
||||||
).disabled(PrefMgr.shared.disableShiftTogglingAlphanumericalMode == true)
|
).disabled(PrefMgr.shared.disableShiftTogglingAlphanumericalMode == true)
|
||||||
}
|
}
|
||||||
|
Preferences.Section(title: "Caps Lock:") {
|
||||||
|
Toggle(
|
||||||
|
LocalizedStringKey("Show notifications when toggling Caps Lock"),
|
||||||
|
isOn: $selShowNotificationsWhenTogglingCapsLock.onChange {
|
||||||
|
PrefMgr.shared.showNotificationsWhenTogglingCapsLock = selShowNotificationsWhenTogglingCapsLock
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
Preferences.Section(label: { Text(LocalizedStringKey("Misc Settings:")) }) {
|
Preferences.Section(label: { Text(LocalizedStringKey("Misc Settings:")) }) {
|
||||||
Toggle(
|
Toggle(
|
||||||
LocalizedStringKey("Enable Space key for calling candidate window"),
|
LocalizedStringKey("Enable Space key for calling candidate window"),
|
||||||
|
|
|
@ -23,8 +23,6 @@ struct suiPrefPaneGeneral: View {
|
||||||
: ["auto"]
|
: ["auto"]
|
||||||
@State private var selEnableHorizontalCandidateLayout = UserDefaults.standard.bool(
|
@State private var selEnableHorizontalCandidateLayout = UserDefaults.standard.bool(
|
||||||
forKey: UserDef.kUseHorizontalCandidateList.rawValue)
|
forKey: UserDef.kUseHorizontalCandidateList.rawValue)
|
||||||
@State private var selShowPageButtonsInCandidateUI = UserDefaults.standard.bool(
|
|
||||||
forKey: UserDef.kShowPageButtonsInCandidateWindow.rawValue)
|
|
||||||
@State private var selEnableKanjiConvToKangXi = UserDefaults.standard.bool(
|
@State private var selEnableKanjiConvToKangXi = UserDefaults.standard.bool(
|
||||||
forKey: UserDef.kChineseConversionEnabled.rawValue)
|
forKey: UserDef.kChineseConversionEnabled.rawValue)
|
||||||
@State private var selEnableKanjiConvToJIS = UserDefaults.standard.bool(
|
@State private var selEnableKanjiConvToJIS = UserDefaults.standard.bool(
|
||||||
|
@ -129,18 +127,8 @@ struct suiPrefPaneGeneral: View {
|
||||||
.labelsHidden()
|
.labelsHidden()
|
||||||
.horizontalRadioGroupLayout()
|
.horizontalRadioGroupLayout()
|
||||||
.pickerStyle(RadioGroupPickerStyle())
|
.pickerStyle(RadioGroupPickerStyle())
|
||||||
.disabled(!PrefMgr.shared.useIMKCandidateWindow)
|
Text(LocalizedStringKey("Choose your preferred layout of the candidate window."))
|
||||||
if PrefMgr.shared.useIMKCandidateWindow {
|
|
||||||
Text(LocalizedStringKey("Choose your preferred layout of the candidate window."))
|
|
||||||
.preferenceDescription()
|
|
||||||
} else {
|
|
||||||
Text(
|
|
||||||
LocalizedStringKey(
|
|
||||||
"Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.preferenceDescription()
|
.preferenceDescription()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Preferences.Section(label: { Text(LocalizedStringKey("Output Settings:")) }) {
|
Preferences.Section(label: { Text(LocalizedStringKey("Output Settings:")) }) {
|
||||||
Toggle(
|
Toggle(
|
||||||
|
|
|
@ -56,7 +56,7 @@ struct suiPrefPaneKeyboard: View {
|
||||||
items: CandidateKey.suggestions,
|
items: CandidateKey.suggestions,
|
||||||
text: $selSelectionKeys.onChange {
|
text: $selSelectionKeys.onChange {
|
||||||
let value = selSelectionKeys
|
let value = selSelectionKeys
|
||||||
let keys: String = value.trimmingCharacters(in: .whitespacesAndNewlines).deduplicate
|
let keys: String = value.trimmingCharacters(in: .whitespacesAndNewlines).deduplicated
|
||||||
do {
|
do {
|
||||||
try CandidateKey.validate(keys: keys)
|
try CandidateKey.validate(keys: keys)
|
||||||
PrefMgr.shared.candidateKeys = keys
|
PrefMgr.shared.candidateKeys = keys
|
||||||
|
@ -64,8 +64,8 @@ struct suiPrefPaneKeyboard: View {
|
||||||
} catch CandidateKey.ErrorType.empty {
|
} catch CandidateKey.ErrorType.empty {
|
||||||
selSelectionKeys = PrefMgr.shared.candidateKeys
|
selSelectionKeys = PrefMgr.shared.candidateKeys
|
||||||
} catch {
|
} catch {
|
||||||
if let window = ctlPrefUI.shared.controller.window {
|
if let window = ctlPrefUI.shared.controller.window, let error = error as? CandidateKey.ErrorType {
|
||||||
let alert = NSAlert(error: error)
|
let alert = NSAlert(error: error.errorDescription)
|
||||||
alert.beginSheetModal(for: window) { _ in
|
alert.beginSheetModal(for: window) { _ in
|
||||||
selSelectionKeys = PrefMgr.shared.candidateKeys
|
selSelectionKeys = PrefMgr.shared.candidateKeys
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,9 @@ class ctlPrefWindow: NSWindowController {
|
||||||
}
|
}
|
||||||
|
|
||||||
selectionKeyComboBox.stringValue = candidateSelectionKeys
|
selectionKeyComboBox.stringValue = candidateSelectionKeys
|
||||||
selectionKeyComboBox.isEnabled = false // 無法與 IMKCandidates 協作,故禁用。
|
if PrefMgr.shared.useIMKCandidateWindow {
|
||||||
|
selectionKeyComboBox.isEnabled = false // 無法與 IMKCandidates 協作,故禁用。
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 這裡有必要加上這段處理,用來確保藉由偏好設定介面動過的 CNS 開關能夠立刻生效。
|
// 這裡有必要加上這段處理,用來確保藉由偏好設定介面動過的 CNS 開關能夠立刻生效。
|
||||||
|
@ -198,7 +200,7 @@ class ctlPrefWindow: NSWindowController {
|
||||||
let keys = (sender as AnyObject).stringValue?.trimmingCharacters(
|
let keys = (sender as AnyObject).stringValue?.trimmingCharacters(
|
||||||
in: .whitespacesAndNewlines
|
in: .whitespacesAndNewlines
|
||||||
)
|
)
|
||||||
.deduplicate
|
.deduplicated
|
||||||
else {
|
else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -209,8 +211,8 @@ class ctlPrefWindow: NSWindowController {
|
||||||
} catch CandidateKey.ErrorType.empty {
|
} catch CandidateKey.ErrorType.empty {
|
||||||
selectionKeyComboBox.stringValue = PrefMgr.shared.candidateKeys
|
selectionKeyComboBox.stringValue = PrefMgr.shared.candidateKeys
|
||||||
} catch {
|
} catch {
|
||||||
if let window = window {
|
if let window = window, let error = error as? CandidateKey.ErrorType {
|
||||||
let alert = NSAlert(error: error)
|
let alert = NSAlert(error: error.errorDescription)
|
||||||
alert.beginSheetModal(for: window) { _ in
|
alert.beginSheetModal(for: window) { _ in
|
||||||
self.selectionKeyComboBox.stringValue = PrefMgr.shared.candidateKeys
|
self.selectionKeyComboBox.stringValue = PrefMgr.shared.candidateKeys
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,12 +51,11 @@
|
||||||
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
||||||
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
||||||
"Use Phrase Replacement" = "Use Phrase Replacement";
|
"Use Phrase Replacement" = "Use Phrase Replacement";
|
||||||
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
|
||||||
"Candidate keys can only contain ASCII characters like alphanumericals." = "Candidate keys can only contain ASCII characters like alphanumericals.";
|
"Candidate keys can only contain ASCII characters like alphanumericals." = "Candidate keys can only contain ASCII characters like alphanumericals.";
|
||||||
"Candidate keys cannot contain space." = "Candidate keys cannot contain space.";
|
"Candidate keys cannot contain space." = "Candidate keys cannot contain space.";
|
||||||
"There should not be duplicated keys." = "There should not be duplicated keys.";
|
"There should not be duplicated keys." = "There should not be duplicated keys.";
|
||||||
"Please specify at least 4 candidate keys." = "Please specify at least 4 candidate keys.";
|
"Please specify at least 6 candidate keys." = "Please specify at least 6 candidate keys.";
|
||||||
"Maximum 15 candidate keys allowed." = "Maximum 15 candidate keys allowed.";
|
"Maximum 9 candidate keys allowed." = "Maximum 9 candidate keys allowed.";
|
||||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ Phrase replacement mode enabled, interfering user phrase entry.";
|
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ Phrase replacement mode enabled, interfering user phrase entry.";
|
||||||
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ Unhandlable: Chars and Readings in buffer doesn't match.";
|
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ Unhandlable: Chars and Readings in buffer doesn't match.";
|
||||||
"Per-Char Select Mode" = "Per-Char Select Mode";
|
"Per-Char Select Mode" = "Per-Char Select Mode";
|
||||||
|
@ -209,7 +208,7 @@
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+Letter:";
|
"Shift+Letter:" = "Shift+Letter:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
||||||
"Show page buttons in candidate window" = "Show page buttons in candidate window";
|
"Show notifications when toggling Caps Lock" = "Show notifications when toggling Caps Lock";
|
||||||
"Simplified Chinese" = "Simplified Chinese";
|
"Simplified Chinese" = "Simplified Chinese";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
||||||
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Space to +cycle candidates, Shift+Space to +cycle pages";
|
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Space to +cycle candidates, Shift+Space to +cycle pages";
|
||||||
|
@ -217,7 +216,6 @@
|
||||||
"Specify the behavior of intonation key when syllable composer is empty." = "Specify the behavior of intonation key when syllable composer is empty.";
|
"Specify the behavior of intonation key when syllable composer is empty." = "Specify the behavior of intonation key when syllable composer is empty.";
|
||||||
"Starlight" = "Starlight";
|
"Starlight" = "Starlight";
|
||||||
"Stop farting (when typed phonetic combination is invalid, etc.)" = "Stop farting (when typed phonetic combination is invalid, etc.)";
|
"Stop farting (when typed phonetic combination is invalid, etc.)" = "Stop farting (when typed phonetic combination is invalid, etc.)";
|
||||||
"Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window." = "Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window.";
|
|
||||||
"This only works with Tadokoro candidate window." = "This only works with Tadokoro candidate window.";
|
"This only works with Tadokoro candidate window." = "This only works with Tadokoro candidate window.";
|
||||||
"Traditional Chinese" = "Traditional Chinese";
|
"Traditional Chinese" = "Traditional Chinese";
|
||||||
"Trim unfinished readings on commit" = "Trim unfinished readings on commit";
|
"Trim unfinished readings on commit" = "Trim unfinished readings on commit";
|
||||||
|
|
|
@ -51,12 +51,11 @@
|
||||||
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
||||||
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
||||||
"Use Phrase Replacement" = "Use Phrase Replacement";
|
"Use Phrase Replacement" = "Use Phrase Replacement";
|
||||||
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
|
||||||
"Candidate keys can only contain ASCII characters like alphanumericals." = "Candidate keys can only contain ASCII characters like alphanumericals.";
|
"Candidate keys can only contain ASCII characters like alphanumericals." = "Candidate keys can only contain ASCII characters like alphanumericals.";
|
||||||
"Candidate keys cannot contain space." = "Candidate keys cannot contain space.";
|
"Candidate keys cannot contain space." = "Candidate keys cannot contain space.";
|
||||||
"There should not be duplicated keys." = "There should not be duplicated keys.";
|
"There should not be duplicated keys." = "There should not be duplicated keys.";
|
||||||
"Please specify at least 4 candidate keys." = "Please specify at least 4 candidate keys.";
|
"Please specify at least 6 candidate keys." = "Please specify at least 6 candidate keys.";
|
||||||
"Maximum 15 candidate keys allowed." = "Maximum 15 candidate keys allowed.";
|
"Maximum 9 candidate keys allowed." = "Maximum 9 candidate keys allowed.";
|
||||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ Phrase replacement mode enabled, interfering user phrase entry.";
|
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ Phrase replacement mode enabled, interfering user phrase entry.";
|
||||||
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ Unhandlable: Chars and Readings in buffer doesn't match.";
|
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ Unhandlable: Chars and Readings in buffer doesn't match.";
|
||||||
"Per-Char Select Mode" = "Per-Char Select Mode";
|
"Per-Char Select Mode" = "Per-Char Select Mode";
|
||||||
|
@ -209,7 +208,7 @@
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+Letter:";
|
"Shift+Letter:" = "Shift+Letter:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
||||||
"Show page buttons in candidate window" = "Show page buttons in candidate window";
|
"Show notifications when toggling Caps Lock" = "Show notifications when toggling Caps Lock";
|
||||||
"Simplified Chinese" = "Simplified Chinese";
|
"Simplified Chinese" = "Simplified Chinese";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
||||||
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Space to +cycle candidates, Shift+Space to +cycle pages";
|
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Space to +cycle candidates, Shift+Space to +cycle pages";
|
||||||
|
@ -217,7 +216,6 @@
|
||||||
"Specify the behavior of intonation key when syllable composer is empty." = "Specify the behavior of intonation key when syllable composer is empty.";
|
"Specify the behavior of intonation key when syllable composer is empty." = "Specify the behavior of intonation key when syllable composer is empty.";
|
||||||
"Starlight" = "Starlight";
|
"Starlight" = "Starlight";
|
||||||
"Stop farting (when typed phonetic combination is invalid, etc.)" = "Stop farting (when typed phonetic combination is invalid, etc.)";
|
"Stop farting (when typed phonetic combination is invalid, etc.)" = "Stop farting (when typed phonetic combination is invalid, etc.)";
|
||||||
"Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window." = "Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window.";
|
|
||||||
"This only works with Tadokoro candidate window." = "This only works with Tadokoro candidate window.";
|
"This only works with Tadokoro candidate window." = "This only works with Tadokoro candidate window.";
|
||||||
"Traditional Chinese" = "Traditional Chinese";
|
"Traditional Chinese" = "Traditional Chinese";
|
||||||
"Trim unfinished readings on commit" = "Trim unfinished readings on commit";
|
"Trim unfinished readings on commit" = "Trim unfinished readings on commit";
|
||||||
|
|
|
@ -51,12 +51,11 @@
|
||||||
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」は既存語彙:\n ENTER で最優先にし、SHIFT+COMMAND+ENTER で優先順位を下げる;\n BackSpace 或いは Delete で排除。";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」は既存語彙:\n ENTER で最優先にし、SHIFT+COMMAND+ENTER で優先順位を下げる;\n BackSpace 或いは Delete で排除。";
|
||||||
"Edit Phrase Replacement Table…" = "言葉置換表を編集…";
|
"Edit Phrase Replacement Table…" = "言葉置換表を編集…";
|
||||||
"Use Phrase Replacement" = "言葉置換機能";
|
"Use Phrase Replacement" = "言葉置換機能";
|
||||||
"Candidates keys cannot be empty." = "言選り用キー陣列に何かキーをご登録ください。";
|
|
||||||
"Candidate keys can only contain ASCII characters like alphanumericals." = "言選り用キー陣列にはASCII文字だけをご登録ください(英数など)。";
|
"Candidate keys can only contain ASCII characters like alphanumericals." = "言選り用キー陣列にはASCII文字だけをご登録ください(英数など)。";
|
||||||
"Candidate keys cannot contain space." = "言選り用キー陣列にスペースキーは登録できません。";
|
"Candidate keys cannot contain space." = "言選り用キー陣列にスペースキーは登録できません。";
|
||||||
"There should not be duplicated keys." = "言選り用キー陣列に同じキーの重複登録はできません。";
|
"There should not be duplicated keys." = "言選り用キー陣列に同じキーの重複登録はできません。";
|
||||||
"Please specify at least 4 candidate keys." = "言選り用キー陣列に少なくとも4つのキーをご登録ください。";
|
"Please specify at least 6 candidate keys." = "言選り用キー陣列に少なくとも6つのキーをご登録ください。";
|
||||||
"Maximum 15 candidate keys allowed." = "言選り用キー陣列には最多15つキー登録できます。";
|
"Maximum 9 candidate keys allowed." = "言選り用キー陣列には最多9つキー登録できます。";
|
||||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 言葉置換機能稼働中、新添付言葉にも影響。";
|
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 言葉置換機能稼働中、新添付言葉にも影響。";
|
||||||
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 対処不可:緩衝列の字数は読みの数と不同等。";
|
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 対処不可:緩衝列の字数は読みの数と不同等。";
|
||||||
"Per-Char Select Mode" = "全候補入力モード";
|
"Per-Char Select Mode" = "全候補入力モード";
|
||||||
|
@ -82,7 +81,7 @@
|
||||||
"Optimize Memorized Phrases" = "臨時記憶資料を整う";
|
"Optimize Memorized Phrases" = "臨時記憶資料を整う";
|
||||||
"Clear Memorized Phrases" = "臨時記憶資料を削除";
|
"Clear Memorized Phrases" = "臨時記憶資料を削除";
|
||||||
"Currency Numeral Output" = "数字大字変換";
|
"Currency Numeral Output" = "数字大字変換";
|
||||||
"Hold ⇧ to choose associates." = "⇧を押しながら連想候補をご選択ください。";
|
"Hold ⇧ to choose associates." = "⇧を押しながら連想候補を選択。";
|
||||||
|
|
||||||
// The followings are the category names used in the Symbol menu.
|
// The followings are the category names used in the Symbol menu.
|
||||||
"catCommonSymbols" = "常用";
|
"catCommonSymbols" = "常用";
|
||||||
|
@ -209,7 +208,7 @@
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+文字キー:";
|
"Shift+Letter:" = "Shift+文字キー:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "弁音合併入力(入力緩衝列で音読みを漢語弁音に)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "弁音合併入力(入力緩衝列で音読みを漢語弁音に)";
|
||||||
"Show page buttons in candidate window" = "入力候補陳列の側にページボタンを表示";
|
"Show notifications when toggling Caps Lock" = "Caps Lock で切り替えの時に吹出通知メッセージを";
|
||||||
"Simplified Chinese" = "簡体中国語";
|
"Simplified Chinese" = "簡体中国語";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "いくつかのアプリ(例えば MS Edge や Google Chrome などのような Chromium 系ブラウザー)には「Shift キーの入力イベントを複数化してしまう」という支障があり、そしてアプリそれぞれの開発元に修復される可能性はほぼゼロだと言える。威注音入力アプリは対策用の特殊措置を普段に起用している。ご自分の必要によって設定してください。";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "いくつかのアプリ(例えば MS Edge や Google Chrome などのような Chromium 系ブラウザー)には「Shift キーの入力イベントを複数化してしまう」という支障があり、そしてアプリそれぞれの開発元に修復される可能性はほぼゼロだと言える。威注音入力アプリは対策用の特殊措置を普段に起用している。ご自分の必要によって設定してください。";
|
||||||
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Shift+Space で次のページ、Space で次の候補文字を";
|
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Shift+Space で次のページ、Space で次の候補文字を";
|
||||||
|
@ -217,7 +216,6 @@
|
||||||
"Specify the behavior of intonation key when syllable composer is empty." = "音読組立緩衝列が空かされた時の音調キーの行為をご指定ください。";
|
"Specify the behavior of intonation key when syllable composer is empty." = "音読組立緩衝列が空かされた時の音調キーの行為をご指定ください。";
|
||||||
"Starlight" = "星光配列";
|
"Starlight" = "星光配列";
|
||||||
"Stop farting (when typed phonetic combination is invalid, etc.)" = "マナーモード // 外すと入力間違った時に変な声が出る";
|
"Stop farting (when typed phonetic combination is invalid, etc.)" = "マナーモード // 外すと入力間違った時に変な声が出る";
|
||||||
"Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window." = "田所候補陳列ウィンドウは格子状横型陳列しかできません。開発道場のページで IMK 候補陳列ウィンドウを起用してから、今のこのページで縦型・横型陳列の選択はできます。";
|
|
||||||
"This only works with Tadokoro candidate window." = "これは田所候補陳列ウィンドウだけに効ける機能である。";
|
"This only works with Tadokoro candidate window." = "これは田所候補陳列ウィンドウだけに効ける機能である。";
|
||||||
"Traditional Chinese" = "繁体中国語";
|
"Traditional Chinese" = "繁体中国語";
|
||||||
"Trim unfinished readings on commit" = "送り出す緩衝列内容から未完成な音読みを除く";
|
"Trim unfinished readings on commit" = "送り出す緩衝列内容から未完成な音読みを除く";
|
||||||
|
|
|
@ -51,12 +51,11 @@
|
||||||
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:\n 敲 Enter 以升权、敲 Shift+Command+Enter 以降权;\n 敲 BackSpace 或 Delete 以排除。";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:\n 敲 Enter 以升权、敲 Shift+Command+Enter 以降权;\n 敲 BackSpace 或 Delete 以排除。";
|
||||||
"Edit Phrase Replacement Table…" = "编辑语汇置换表…";
|
"Edit Phrase Replacement Table…" = "编辑语汇置换表…";
|
||||||
"Use Phrase Replacement" = "使用语汇置换";
|
"Use Phrase Replacement" = "使用语汇置换";
|
||||||
"Candidates keys cannot be empty." = "您必须指定选字键。";
|
|
||||||
"Candidate keys can only contain ASCII characters like alphanumericals." = "选字键只能是英数等 ASCII 字符。";
|
"Candidate keys can only contain ASCII characters like alphanumericals." = "选字键只能是英数等 ASCII 字符。";
|
||||||
"Candidate keys cannot contain space." = "选字键不得包含空格。";
|
"Candidate keys cannot contain space." = "选字键不得包含空格。";
|
||||||
"There should not be duplicated keys." = "选字键不得重复。";
|
"There should not be duplicated keys." = "选字键不得重复。";
|
||||||
"Please specify at least 4 candidate keys." = "请至少指定四个选字键。";
|
"Please specify at least 6 candidate keys." = "请至少指定 6 个选字键。";
|
||||||
"Maximum 15 candidate keys allowed." = "选字键最多只能指定十五个。";
|
"Maximum 9 candidate keys allowed." = "选字键最多只能指定 9 个。";
|
||||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 语汇置换功能已启用,会波及语汇自订。";
|
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 语汇置换功能已启用,会波及语汇自订。";
|
||||||
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 无法处理:组字区字数与读音数不对应。";
|
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 无法处理:组字区字数与读音数不对应。";
|
||||||
"Per-Char Select Mode" = "模拟逐字选字输入";
|
"Per-Char Select Mode" = "模拟逐字选字输入";
|
||||||
|
@ -209,7 +208,7 @@
|
||||||
"Shift+BackSpace:" = "Shift+退格键:";
|
"Shift+BackSpace:" = "Shift+退格键:";
|
||||||
"Shift+Letter:" = "Shift+字母键:";
|
"Shift+Letter:" = "Shift+字母键:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音并击(组字区内显示汉语拼音)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音并击(组字区内显示汉语拼音)";
|
||||||
"Show page buttons in candidate window" = "在选字窗内显示翻页按钮";
|
"Show notifications when toggling Caps Lock" = "以 Caps Lock 切换输入法/中英模式时显示通知";
|
||||||
"Simplified Chinese" = "简体中文";
|
"Simplified Chinese" = "简体中文";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些应用(比如像是 MS Edge 或者 Chrome 这样的 Chromium 核心的浏览器)可能会使输入的 Shift 按键讯号被重复输入,且其有关研发方很可能不打算修复这些产品缺陷。威注音针对这些应用预设启用了相容措施。请在此根据您的需求自订。";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些应用(比如像是 MS Edge 或者 Chrome 这样的 Chromium 核心的浏览器)可能会使输入的 Shift 按键讯号被重复输入,且其有关研发方很可能不打算修复这些产品缺陷。威注音针对这些应用预设启用了相容措施。请在此根据您的需求自订。";
|
||||||
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Shift+空格键 换下一页,空格键 换选下一个候选字";
|
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Shift+空格键 换下一页,空格键 换选下一个候选字";
|
||||||
|
@ -217,7 +216,6 @@
|
||||||
"Specify the behavior of intonation key when syllable composer is empty." = "指定声调键(在注拼槽为「空」状态时)的行为。";
|
"Specify the behavior of intonation key when syllable composer is empty." = "指定声调键(在注拼槽为「空」状态时)的行为。";
|
||||||
"Starlight" = "星光排列";
|
"Starlight" = "星光排列";
|
||||||
"Stop farting (when typed phonetic combination is invalid, etc.)" = "廉耻模式 // 取消勾选的话,敲错字时会有异音";
|
"Stop farting (when typed phonetic combination is invalid, etc.)" = "廉耻模式 // 取消勾选的话,敲错字时会有异音";
|
||||||
"Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window." = "田所选字窗仅支援横排矩阵布局模式。如欲使用纵排布局模式者,请在开发道场内先启用 IMK 选字窗。";
|
|
||||||
"This only works with Tadokoro candidate window." = "该方法仅对田所选字窗起作用。";
|
"This only works with Tadokoro candidate window." = "该方法仅对田所选字窗起作用。";
|
||||||
"Traditional Chinese" = "繁体中文";
|
"Traditional Chinese" = "繁体中文";
|
||||||
"Trim unfinished readings on commit" = "在递交时清理未完成拼写的读音";
|
"Trim unfinished readings on commit" = "在递交时清理未完成拼写的读音";
|
||||||
|
|
|
@ -51,12 +51,11 @@
|
||||||
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:\n 敲 Enter 以升權、敲 Shift+Command+Enter 以降權;\n 敲 BackSpace 或 Delete 以排除。";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:\n 敲 Enter 以升權、敲 Shift+Command+Enter 以降權;\n 敲 BackSpace 或 Delete 以排除。";
|
||||||
"Edit Phrase Replacement Table…" = "編輯語彙置換表…";
|
"Edit Phrase Replacement Table…" = "編輯語彙置換表…";
|
||||||
"Use Phrase Replacement" = "使用語彙置換";
|
"Use Phrase Replacement" = "使用語彙置換";
|
||||||
"Candidates keys cannot be empty." = "您必須指定選字鍵。";
|
|
||||||
"Candidate keys can only contain ASCII characters like alphanumericals." = "選字鍵只能是英數等 ASCII 字符。";
|
"Candidate keys can only contain ASCII characters like alphanumericals." = "選字鍵只能是英數等 ASCII 字符。";
|
||||||
"Candidate keys cannot contain space." = "選字鍵不得包含空格。";
|
"Candidate keys cannot contain space." = "選字鍵不得包含空格。";
|
||||||
"There should not be duplicated keys." = "選字鍵不得重複。";
|
"There should not be duplicated keys." = "選字鍵不得重複。";
|
||||||
"Please specify at least 4 candidate keys." = "請至少指定四個選字鍵。";
|
"Please specify at least 6 candidate keys." = "請至少指定 6 個選字鍵。";
|
||||||
"Maximum 15 candidate keys allowed." = "選字鍵最多只能指定十五個。";
|
"Maximum 9 candidate keys allowed." = "選字鍵最多只能指定 9 個。";
|
||||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 語彙置換功能已啟用,會波及語彙自訂。";
|
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 語彙置換功能已啟用,會波及語彙自訂。";
|
||||||
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 無法處理:組字區字數與讀音數不對應。";
|
"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 無法處理:組字區字數與讀音數不對應。";
|
||||||
"Per-Char Select Mode" = "模擬逐字選字輸入";
|
"Per-Char Select Mode" = "模擬逐字選字輸入";
|
||||||
|
@ -209,7 +208,7 @@
|
||||||
"Shift+BackSpace:" = "Shift+退格鍵:";
|
"Shift+BackSpace:" = "Shift+退格鍵:";
|
||||||
"Shift+Letter:" = "Shift+字母鍵:";
|
"Shift+Letter:" = "Shift+字母鍵:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音並擊(組字區內顯示漢語拼音)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音並擊(組字區內顯示漢語拼音)";
|
||||||
"Show page buttons in candidate window" = "在選字窗內顯示翻頁按鈕";
|
"Show notifications when toggling Caps Lock" = "以 Caps Lock 切換輸入法/中英模式時顯示通知";
|
||||||
"Simplified Chinese" = "簡體中文";
|
"Simplified Chinese" = "簡體中文";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些應用(比如像是 MS Edge 或者 Chrome 這樣的 Chromium 核心的瀏覽器)可能會使輸入的 Shift 按鍵訊號被重複輸入,且其有關研發方很可能不打算修復這些產品缺陷。威注音針對這些應用預設啟用了相容措施。請在此根據您的需求自訂。";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些應用(比如像是 MS Edge 或者 Chrome 這樣的 Chromium 核心的瀏覽器)可能會使輸入的 Shift 按鍵訊號被重複輸入,且其有關研發方很可能不打算修復這些產品缺陷。威注音針對這些應用預設啟用了相容措施。請在此根據您的需求自訂。";
|
||||||
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Shift+空格鍵 換下一頁,空格鍵 換選下一個候選字";
|
"Space to +cycle candidates, Shift+Space to +cycle pages" = "Shift+空格鍵 換下一頁,空格鍵 換選下一個候選字";
|
||||||
|
@ -217,7 +216,6 @@
|
||||||
"Specify the behavior of intonation key when syllable composer is empty." = "指定聲調鍵(在注拼槽為「空」狀態時)的行為。";
|
"Specify the behavior of intonation key when syllable composer is empty." = "指定聲調鍵(在注拼槽為「空」狀態時)的行為。";
|
||||||
"Starlight" = "星光排列";
|
"Starlight" = "星光排列";
|
||||||
"Stop farting (when typed phonetic combination is invalid, etc.)" = "廉恥模式 // 取消勾選的話,敲錯字時會有異音";
|
"Stop farting (when typed phonetic combination is invalid, etc.)" = "廉恥模式 // 取消勾選的話,敲錯字時會有異音";
|
||||||
"Tadokoro candidate window only supports horizontal grid view. Enable IMK candidate window in DevZone page first if you want to choose vertical candidate window." = "田所選字窗僅支援橫排矩陣佈局模式。如欲使用縱排佈局模式者,請在開發道場內先啟用 IMK 選字窗。";
|
|
||||||
"This only works with Tadokoro candidate window." = "該方法僅對田所選字窗起作用。";
|
"This only works with Tadokoro candidate window." = "該方法僅對田所選字窗起作用。";
|
||||||
"Traditional Chinese" = "繁體中文";
|
"Traditional Chinese" = "繁體中文";
|
||||||
"Trim unfinished readings on commit" = "在遞交時清理未完成拼寫的讀音";
|
"Trim unfinished readings on commit" = "在遞交時清理未完成拼寫的讀音";
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21225" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21225" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21225"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21225"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -36,14 +37,14 @@
|
||||||
</window>
|
</window>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="XWo-36-xGi" userLabel="vwrExperience">
|
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="XWo-36-xGi" userLabel="vwrExperience">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="836" height="396"/>
|
<rect key="frame" x="0.0" y="0.0" width="836" height="418"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="horizontal" alignment="top" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qDj-B9-mZf">
|
<stackView distribution="fill" orientation="horizontal" alignment="top" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qDj-B9-mZf">
|
||||||
<rect key="frame" x="20" y="32" width="796" height="344"/>
|
<rect key="frame" x="20" y="31" width="796" height="367"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="12" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="j9R-fB-ttM">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="12" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="j9R-fB-ttM">
|
||||||
<rect key="frame" x="0.0" y="26" width="402" height="318"/>
|
<rect key="frame" x="0.0" y="49" width="402" height="318"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fO5-4y-X0y">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fO5-4y-X0y">
|
||||||
<rect key="frame" x="0.0" y="277" width="365" height="41"/>
|
<rect key="frame" x="0.0" y="277" width="365" height="41"/>
|
||||||
|
@ -266,10 +267,10 @@
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="12" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VOm-nN-5IB">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="12" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VOm-nN-5IB">
|
||||||
<rect key="frame" x="410" y="0.0" width="386" height="344"/>
|
<rect key="frame" x="410" y="0.0" width="386" height="367"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="7" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="s47-wG-vKA">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="7" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="s47-wG-vKA">
|
||||||
<rect key="frame" x="0.0" y="261" width="386" height="83"/>
|
<rect key="frame" x="0.0" y="284" width="386" height="83"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iCL-n8-VTP">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iCL-n8-VTP">
|
||||||
<rect key="frame" x="-2" y="68" width="323" height="15"/>
|
<rect key="frame" x="-2" y="68" width="323" height="15"/>
|
||||||
|
@ -319,7 +320,7 @@
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOW-jd-XBh">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOW-jd-XBh">
|
||||||
<rect key="frame" x="0.0" y="188" width="386" height="61"/>
|
<rect key="frame" x="0.0" y="211" width="386" height="61"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="J0f-Aw-dxC">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="J0f-Aw-dxC">
|
||||||
<rect key="frame" x="-2" y="46" width="336" height="15"/>
|
<rect key="frame" x="-2" y="46" width="336" height="15"/>
|
||||||
|
@ -365,10 +366,10 @@
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jxD-fv-UYx">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jxD-fv-UYx">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="380" height="176"/>
|
<rect key="frame" x="0.0" y="0.0" width="380" height="199"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="109">
|
<button translatesAutoresizingMaskIntoConstraints="NO" id="109">
|
||||||
<rect key="frame" x="-1" y="160.5" width="285" height="16"/>
|
<rect key="frame" x="-1" y="183.5" width="285" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Enable Space key for calling candidate window" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="110">
|
<buttonCell key="cell" type="check" title="Enable Space key for calling candidate window" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="110">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -378,7 +379,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bE0-Lq-Pj7">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bE0-Lq-Pj7">
|
||||||
<rect key="frame" x="-1" y="137.5" width="266" height="16"/>
|
<rect key="frame" x="-1" y="160.5" width="266" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Use ESC key to clear the entire input buffer" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="f2j-xD-4xK">
|
<buttonCell key="cell" type="check" title="Use ESC key to clear the entire input buffer" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="f2j-xD-4xK">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -388,7 +389,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mzw-F2-aAQ">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mzw-F2-aAQ">
|
||||||
<rect key="frame" x="-1" y="114.5" width="295" height="16"/>
|
<rect key="frame" x="-1" y="137.5" width="295" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Emulating select-candidate-per-character mode" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="ArK-Vk-OoT">
|
<buttonCell key="cell" type="check" title="Emulating select-candidate-per-character mode" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="ArK-Vk-OoT">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -398,7 +399,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="j8R-Hj-3dj">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="j8R-Hj-3dj">
|
||||||
<rect key="frame" x="-1" y="91.5" width="340" height="16"/>
|
<rect key="frame" x="-1" y="114.5" width="340" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Automatically correct reading combinations when typing" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAutoCorrectReadingCombination">
|
<buttonCell key="cell" type="check" title="Automatically correct reading combinations when typing" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAutoCorrectReadingCombination">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -408,7 +409,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6MM-WC-Mpd">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6MM-WC-Mpd">
|
||||||
<rect key="frame" x="-1" y="68.5" width="381" height="16"/>
|
<rect key="frame" x="-1" y="91.5" width="381" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Allow using Enter key to confirm associated candidate selection" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAlsoConfirmAssociatedCandidatesByEnter">
|
<buttonCell key="cell" type="check" title="Allow using Enter key to confirm associated candidate selection" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAlsoConfirmAssociatedCandidatesByEnter">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -418,7 +419,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HaB-rc-AcW">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HaB-rc-AcW">
|
||||||
<rect key="frame" x="-1" y="45.5" width="295" height="16"/>
|
<rect key="frame" x="-1" y="68.5" width="295" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Allow backspace-editing miscomposed readings" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkKeepReadingUponCompositionError">
|
<buttonCell key="cell" type="check" title="Allow backspace-editing miscomposed readings" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkKeepReadingUponCompositionError">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -428,7 +429,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xe6-Pu-3Fa">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xe6-Pu-3Fa">
|
||||||
<rect key="frame" x="-1" y="22.5" width="223" height="16"/>
|
<rect key="frame" x="-1" y="45.5" width="223" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Trim unfinished readings on commit" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="tglTrimUnfinishedReadingsOnCommit">
|
<buttonCell key="cell" type="check" title="Trim unfinished readings on commit" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="tglTrimUnfinishedReadingsOnCommit">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -438,7 +439,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7QM-7z-tpq">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7QM-7z-tpq">
|
||||||
<rect key="frame" x="-1" y="-0.5" width="233" height="16"/>
|
<rect key="frame" x="-1" y="22.5" width="233" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Always show tooltip texts horizontally" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="lblAlwaysShowTooltipTextsHorizontally">
|
<buttonCell key="cell" type="check" title="Always show tooltip texts horizontally" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="lblAlwaysShowTooltipTextsHorizontally">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -447,6 +448,23 @@
|
||||||
<binding destination="32" name="value" keyPath="values.AlwaysShowTooltipTextsHorizontally" id="szi-4g-EIC"/>
|
<binding destination="32" name="value" keyPath="values.AlwaysShowTooltipTextsHorizontally" id="szi-4g-EIC"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="233">
|
||||||
|
<rect key="frame" x="-1" y="-0.5" width="271" height="16"/>
|
||||||
|
<buttonCell key="cell" type="check" title="Show notifications when toggling Caps Lock" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="shc-Nu-UsM">
|
||||||
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
<connections>
|
||||||
|
<binding destination="32" name="value" keyPath="values.ShowNotificationsWhenTogglingCapsLock" id="0e1-3G-eIc"/>
|
||||||
|
</connections>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<binding destination="32" name="enabled" keyPath="values.UseIMKCandidateWindow" id="pHT-37-Eyh">
|
||||||
|
<dictionary key="options">
|
||||||
|
<string key="NSValueTransformerName">NSNegateBoolean</string>
|
||||||
|
</dictionary>
|
||||||
|
</binding>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<visibilityPriorities>
|
<visibilityPriorities>
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
|
@ -457,6 +475,7 @@
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
|
<integer value="1000"/>
|
||||||
</visibilityPriorities>
|
</visibilityPriorities>
|
||||||
<customSpacing>
|
<customSpacing>
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
|
@ -467,6 +486,7 @@
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
|
<real value="3.4028234663852886e+38"/>
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
@ -496,7 +516,7 @@
|
||||||
<constraint firstItem="qDj-B9-mZf" firstAttribute="top" secondItem="XWo-36-xGi" secondAttribute="top" constant="20" symbolic="YES" id="EmH-pX-s2C"/>
|
<constraint firstItem="qDj-B9-mZf" firstAttribute="top" secondItem="XWo-36-xGi" secondAttribute="top" constant="20" symbolic="YES" id="EmH-pX-s2C"/>
|
||||||
<constraint firstItem="qDj-B9-mZf" firstAttribute="leading" secondItem="XWo-36-xGi" secondAttribute="leading" constant="20" symbolic="YES" id="cs3-Kh-czM"/>
|
<constraint firstItem="qDj-B9-mZf" firstAttribute="leading" secondItem="XWo-36-xGi" secondAttribute="leading" constant="20" symbolic="YES" id="cs3-Kh-czM"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<point key="canvasLocation" x="-1091" y="-192"/>
|
<point key="canvasLocation" x="-1091" y="-181"/>
|
||||||
</visualEffectView>
|
</visualEffectView>
|
||||||
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="BUt-lg-GPp" userLabel="vwrGeneral">
|
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="BUt-lg-GPp" userLabel="vwrGeneral">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="445" height="431"/>
|
<rect key="frame" x="0.0" y="0.0" width="445" height="431"/>
|
||||||
|
@ -511,7 +531,6 @@
|
||||||
<constraint firstItem="Agg-8d-6bO" firstAttribute="top" secondItem="gZ0-OK-r7a" secondAttribute="bottom" constant="9.5" id="bzP-jz-kHQ"/>
|
<constraint firstItem="Agg-8d-6bO" firstAttribute="top" secondItem="gZ0-OK-r7a" secondAttribute="bottom" constant="9.5" id="bzP-jz-kHQ"/>
|
||||||
<constraint firstItem="5Rz-c8-hp9" firstAttribute="top" secondItem="90" secondAttribute="bottom" constant="9" id="d7i-nb-E1l"/>
|
<constraint firstItem="5Rz-c8-hp9" firstAttribute="top" secondItem="90" secondAttribute="bottom" constant="9" id="d7i-nb-E1l"/>
|
||||||
<constraint firstItem="28" firstAttribute="top" secondItem="Ldp-U1-36g" secondAttribute="bottom" constant="12" id="mas-hn-K8C"/>
|
<constraint firstItem="28" firstAttribute="top" secondItem="Ldp-U1-36g" secondAttribute="bottom" constant="12" id="mas-hn-K8C"/>
|
||||||
<constraint firstItem="da1-7e-els" firstAttribute="top" secondItem="233" secondAttribute="bottom" constant="9.5" id="rca-Fa-YX4"/>
|
|
||||||
<constraint firstItem="da1-7e-els" firstAttribute="top" secondItem="Tax-1R-BrU" secondAttribute="top" constant="177" id="vTm-gq-EBY"/>
|
<constraint firstItem="da1-7e-els" firstAttribute="top" secondItem="Tax-1R-BrU" secondAttribute="top" constant="177" id="vTm-gq-EBY"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<rows>
|
<rows>
|
||||||
|
@ -635,7 +654,7 @@
|
||||||
</gridCell>
|
</gridCell>
|
||||||
<gridCell row="oKH-BK-XYd" column="X1u-rr-FFP" headOfMergedCell="ytZ-JE-JBZ" id="ytZ-JE-JBZ">
|
<gridCell row="oKH-BK-XYd" column="X1u-rr-FFP" headOfMergedCell="ytZ-JE-JBZ" id="ytZ-JE-JBZ">
|
||||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="Yl4-Ar-L6r">
|
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="Yl4-Ar-L6r">
|
||||||
<rect key="frame" x="-2" y="252" width="314" height="15"/>
|
<rect key="frame" x="-2" y="244" width="314" height="15"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="15" id="Bgf-Qu-fAR"/>
|
<constraint firstAttribute="height" constant="15" id="Bgf-Qu-fAR"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
@ -649,7 +668,7 @@
|
||||||
<gridCell row="oKH-BK-XYd" column="s2d-Vu-rHv" headOfMergedCell="ytZ-JE-JBZ" id="R5f-hg-7u0"/>
|
<gridCell row="oKH-BK-XYd" column="s2d-Vu-rHv" headOfMergedCell="ytZ-JE-JBZ" id="R5f-hg-7u0"/>
|
||||||
<gridCell row="KfK-kF-hJJ" column="X1u-rr-FFP" xPlacement="trailing" yPlacement="top" rowAlignment="none" id="K38-CT-HsS">
|
<gridCell row="KfK-kF-hJJ" column="X1u-rr-FFP" xPlacement="trailing" yPlacement="top" rowAlignment="none" id="K38-CT-HsS">
|
||||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="23">
|
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="23">
|
||||||
<rect key="frame" x="9" y="228" width="131" height="15"/>
|
<rect key="frame" x="9" y="212" width="131" height="15"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Candidate List Layout:" id="24">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Candidate List Layout:" id="24">
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -659,7 +678,7 @@
|
||||||
</gridCell>
|
</gridCell>
|
||||||
<gridCell row="KfK-kF-hJJ" column="s2d-Vu-rHv" yPlacement="top" rowAlignment="none" id="ie1-hW-RKb">
|
<gridCell row="KfK-kF-hJJ" column="s2d-Vu-rHv" yPlacement="top" rowAlignment="none" id="ie1-hW-RKb">
|
||||||
<matrix key="contentView" wantsLayer="YES" verticalHuggingPriority="750" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="19">
|
<matrix key="contentView" wantsLayer="YES" verticalHuggingPriority="750" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="19">
|
||||||
<rect key="frame" x="144" y="228" width="240" height="15"/>
|
<rect key="frame" x="144" y="212" width="240" height="15"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="240" id="gpb-Gt-QDY"/>
|
<constraint firstAttribute="width" constant="240" id="gpb-Gt-QDY"/>
|
||||||
<constraint firstAttribute="height" constant="15" id="wB2-bw-gqA"/>
|
<constraint firstAttribute="height" constant="15" id="wB2-bw-gqA"/>
|
||||||
|
@ -692,25 +711,7 @@
|
||||||
</matrix>
|
</matrix>
|
||||||
</gridCell>
|
</gridCell>
|
||||||
<gridCell row="f3d-br-SXh" column="X1u-rr-FFP" id="HUa-vb-9P8"/>
|
<gridCell row="f3d-br-SXh" column="X1u-rr-FFP" id="HUa-vb-9P8"/>
|
||||||
<gridCell row="f3d-br-SXh" column="s2d-Vu-rHv" yPlacement="center" id="vxY-vh-tw7">
|
<gridCell row="f3d-br-SXh" column="s2d-Vu-rHv" yPlacement="center" id="vxY-vh-tw7"/>
|
||||||
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="233">
|
|
||||||
<rect key="frame" x="143" y="203.5" width="223" height="16"/>
|
|
||||||
<buttonCell key="cell" type="check" title="Show page buttons in candidate list" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="shc-Nu-UsM">
|
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
|
||||||
<font key="font" metaFont="cellTitle"/>
|
|
||||||
<connections>
|
|
||||||
<binding destination="32" name="value" keyPath="values.ShowPageButtonsInCandidateWindow" id="6BK-hU-lqs"/>
|
|
||||||
</connections>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<binding destination="32" name="enabled" keyPath="values.UseIMKCandidateWindow" id="pHT-37-Eyh">
|
|
||||||
<dictionary key="options">
|
|
||||||
<string key="NSValueTransformerName">NSNegateBoolean</string>
|
|
||||||
</dictionary>
|
|
||||||
</binding>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</gridCell>
|
|
||||||
<gridCell row="VsE-7i-d0I" column="X1u-rr-FFP" headOfMergedCell="1LR-8q-4K4" rowAlignment="none" id="1LR-8q-4K4">
|
<gridCell row="VsE-7i-d0I" column="X1u-rr-FFP" headOfMergedCell="1LR-8q-4K4" rowAlignment="none" id="1LR-8q-4K4">
|
||||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="da1-7e-els">
|
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="da1-7e-els">
|
||||||
<rect key="frame" x="-2" y="179" width="404" height="15"/>
|
<rect key="frame" x="-2" y="179" width="404" height="15"/>
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
"RUG-ls-KyA.title" = "Push the cursor in front of the phrase after selection";
|
"RUG-ls-KyA.title" = "Push the cursor in front of the phrase after selection";
|
||||||
"rVQ-Hx-cGi.title" = "Japanese";
|
"rVQ-Hx-cGi.title" = "Japanese";
|
||||||
"s7u-Fm-dVg.title" = "Cycling Pages";
|
"s7u-Fm-dVg.title" = "Cycling Pages";
|
||||||
"shc-Nu-UsM.title" = "Show page buttons in candidate list";
|
"shc-Nu-UsM.title" = "Show notifications when toggling Caps Lock";
|
||||||
"tglDevZoneIMKCandidate.title" = "Use IMK Candidate Window instead of Tadokoro (will reboot the IME)";
|
"tglDevZoneIMKCandidate.title" = "Use IMK Candidate Window instead of Tadokoro (will reboot the IME)";
|
||||||
"tglTrimUnfinishedReadingsOnCommit.title" = "Trim unfinished readings on commit";
|
"tglTrimUnfinishedReadingsOnCommit.title" = "Trim unfinished readings on commit";
|
||||||
"TXr-FF-ehw.title" = "Traditional Chinese";
|
"TXr-FF-ehw.title" = "Traditional Chinese";
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
"RUG-ls-KyA.title" = "候補選択の直後、すぐカーソルを単語の向こうに推す";
|
"RUG-ls-KyA.title" = "候補選択の直後、すぐカーソルを単語の向こうに推す";
|
||||||
"rVQ-Hx-cGi.title" = "和語";
|
"rVQ-Hx-cGi.title" = "和語";
|
||||||
"s7u-Fm-dVg.title" = "ページ";
|
"s7u-Fm-dVg.title" = "ページ";
|
||||||
"shc-Nu-UsM.title" = "ページボタンを表示";
|
"shc-Nu-UsM.title" = "Caps Lock で切り替えの時に吹出通知メッセージを";
|
||||||
"tglDevZoneIMKCandidate.title" = "IMK 候補陳列ウィンドウを起用(入力アプリは自動的に再起動)";
|
"tglDevZoneIMKCandidate.title" = "IMK 候補陳列ウィンドウを起用(入力アプリは自動的に再起動)";
|
||||||
"tglTrimUnfinishedReadingsOnCommit.title" = "送り出す緩衝列内容から未完成な音読みを除く";
|
"tglTrimUnfinishedReadingsOnCommit.title" = "送り出す緩衝列内容から未完成な音読みを除く";
|
||||||
"TXr-FF-ehw.title" = "繁体中国語";
|
"TXr-FF-ehw.title" = "繁体中国語";
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
"RUG-ls-KyA.title" = "在选字后将光标置于该字词的前方";
|
"RUG-ls-KyA.title" = "在选字后将光标置于该字词的前方";
|
||||||
"rVQ-Hx-cGi.title" = "和语";
|
"rVQ-Hx-cGi.title" = "和语";
|
||||||
"s7u-Fm-dVg.title" = "轮替页面";
|
"s7u-Fm-dVg.title" = "轮替页面";
|
||||||
"shc-Nu-UsM.title" = "在选字窗内显示翻页按钮";
|
"shc-Nu-UsM.title" = "以 Caps Lock 切换输入法/中英模式时显示通知";
|
||||||
"tglDevZoneIMKCandidate.title" = "启用与 macOS 内建输入法相同的 IMK 选字窗(会自动重启输入法)";
|
"tglDevZoneIMKCandidate.title" = "启用与 macOS 内建输入法相同的 IMK 选字窗(会自动重启输入法)";
|
||||||
"tglTrimUnfinishedReadingsOnCommit.title" = "在递交时清理未完成拼写的读音";
|
"tglTrimUnfinishedReadingsOnCommit.title" = "在递交时清理未完成拼写的读音";
|
||||||
"TXr-FF-ehw.title" = "繁体中文";
|
"TXr-FF-ehw.title" = "繁体中文";
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
"RUG-ls-KyA.title" = "在選字後將游標置於該字詞的前方";
|
"RUG-ls-KyA.title" = "在選字後將游標置於該字詞的前方";
|
||||||
"rVQ-Hx-cGi.title" = "和語";
|
"rVQ-Hx-cGi.title" = "和語";
|
||||||
"s7u-Fm-dVg.title" = "輪替頁面";
|
"s7u-Fm-dVg.title" = "輪替頁面";
|
||||||
"shc-Nu-UsM.title" = "在選字窗內顯示翻頁按鈕";
|
"shc-Nu-UsM.title" = "以 Caps Lock 切換輸入法/中英模式時顯示通知";
|
||||||
"tglDevZoneIMKCandidate.title" = "啟用與 macOS 內建輸入法相同的 IMK 選字窗(會自動重啟輸入法)";
|
"tglDevZoneIMKCandidate.title" = "啟用與 macOS 內建輸入法相同的 IMK 選字窗(會自動重啟輸入法)";
|
||||||
"tglTrimUnfinishedReadingsOnCommit.title" = "在遞交時清理未完成拼寫的讀音";
|
"tglTrimUnfinishedReadingsOnCommit.title" = "在遞交時清理未完成拼寫的讀音";
|
||||||
"TXr-FF-ehw.title" = "繁體中文";
|
"TXr-FF-ehw.title" = "繁體中文";
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.8.0</string>
|
<string>2.8.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2800</string>
|
<string>2802</string>
|
||||||
<key>UpdateInfoEndpoint</key>
|
<key>UpdateInfoEndpoint</key>
|
||||||
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
|
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
|
||||||
<key>UpdateInfoSite</key>
|
<key>UpdateInfoSite</key>
|
||||||
|
|
|
@ -1262,7 +1262,7 @@
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
@ -1302,7 +1302,7 @@
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
@ -1341,7 +1341,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
@ -1394,7 +1394,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
@ -1529,7 +1529,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
|
@ -1590,7 +1590,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
|
@ -1638,7 +1638,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
@ -1684,7 +1684,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2800;
|
CURRENT_PROJECT_VERSION = 2802;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
|
Loading…
Reference in New Issue