Repo // Implementing IMKCandidates but disable it.
- It's not in a ready-to-use state yet. Still buggy.
This commit is contained in:
parent
40d3382564
commit
ccc033e620
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
1. The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
2. 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 above.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import InputMethodKit
|
||||
|
||||
public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
||||
public var currentLayout: CandidateLayout = .horizontal
|
||||
|
||||
public weak var delegate: ctlCandidateDelegate? {
|
||||
didSet {
|
||||
reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
public var selectedCandidateIndex: Int = .max
|
||||
|
||||
public var visible: Bool = false {
|
||||
didSet {
|
||||
if visible {
|
||||
show()
|
||||
} else {
|
||||
hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var windowTopLeftPoint: NSPoint = .init(x: 0, y: 0) {
|
||||
didSet {
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
|
||||
self.set(windowTopLeftPoint: self.windowTopLeftPoint, bottomOutOfScreenAdjustmentHeight: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var keyLabels: [CandidateKeyLabel] = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
|
||||
.map {
|
||||
CandidateKeyLabel(key: $0, displayedText: $0)
|
||||
}
|
||||
|
||||
public var keyLabelFont: NSFont = NSFont.monospacedDigitSystemFont(
|
||||
ofSize: 14, weight: .medium
|
||||
)
|
||||
public var candidateFont: NSFont = NSFont.systemFont(ofSize: 18)
|
||||
public var tooltip: String = ""
|
||||
|
||||
var keyCount = 0
|
||||
var displayedCandidates = [String]()
|
||||
|
||||
public func specifyLayout(_ layout: CandidateLayout = .horizontal) {
|
||||
currentLayout = layout
|
||||
switch currentLayout {
|
||||
case .horizontal:
|
||||
setPanelType(kIMKScrollingGridCandidatePanel)
|
||||
case .vertical:
|
||||
setPanelType(kIMKSingleColumnScrollingCandidatePanel)
|
||||
}
|
||||
setAttributes([IMKCandidatesSendServerKeyEventFirst: false])
|
||||
}
|
||||
|
||||
public required init(_ layout: CandidateLayout = .horizontal) {
|
||||
super.init(server: theServer, panelType: kIMKScrollingGridCandidatePanel)
|
||||
specifyLayout(layout)
|
||||
visible = false
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func reloadData() {
|
||||
guard let delegate = delegate else { return }
|
||||
let candidates = delegate.candidatesForController(self).map { theCandidate -> String in
|
||||
let theConverted = IME.kanjiConversionIfRequired(theCandidate.1)
|
||||
return (theCandidate.1 == theConverted) ? theCandidate.1 : "\(theConverted)(\(theCandidate.1))"
|
||||
}
|
||||
setCandidateData(candidates)
|
||||
keyCount = selectionKeys().count
|
||||
selectedCandidateIndex = 0
|
||||
update()
|
||||
}
|
||||
|
||||
public func showNextPage() -> Bool {
|
||||
if selectedCandidateIndex == candidates(self).count - 1 { return false }
|
||||
selectedCandidateIndex = min(selectedCandidateIndex + keyCount, candidates(self).count - 1)
|
||||
return selectCandidate(withIdentifier: selectedCandidateIndex)
|
||||
}
|
||||
|
||||
public func showPreviousPage() -> Bool {
|
||||
if selectedCandidateIndex == 0 { return true }
|
||||
selectedCandidateIndex = max(selectedCandidateIndex - keyCount, 0)
|
||||
return selectCandidate(withIdentifier: selectedCandidateIndex)
|
||||
}
|
||||
|
||||
public func highlightNextCandidate() -> Bool {
|
||||
if selectedCandidateIndex == candidates(self).count - 1 { return false }
|
||||
selectedCandidateIndex = min(selectedCandidateIndex + 1, candidates(self).count - 1)
|
||||
return selectCandidate(withIdentifier: selectedCandidateIndex)
|
||||
}
|
||||
|
||||
public func highlightPreviousCandidate() -> Bool {
|
||||
if selectedCandidateIndex == 0 { return true }
|
||||
selectedCandidateIndex = max(selectedCandidateIndex - 1, 0)
|
||||
return selectCandidate(withIdentifier: selectedCandidateIndex)
|
||||
}
|
||||
|
||||
public func candidateIndexAtKeyLabelIndex(_: Int) -> Int {
|
||||
selectedCandidateIndex
|
||||
}
|
||||
|
||||
public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight _: CGFloat = 0) {
|
||||
setCandidateFrameTopLeft(windowTopLeftPoint)
|
||||
}
|
||||
|
||||
override public func handle(_ event: NSEvent!, client _: Any!) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
return delegate.handleDelegateEvent(event)
|
||||
}
|
||||
}
|
|
@ -116,6 +116,7 @@
|
|||
5BF9DA2A28840E6200DBD48E /* template-replacements.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5BF9DA2528840E6200DBD48E /* template-replacements.txt */; };
|
||||
5BF9DA2B28840E6200DBD48E /* template-userphrases.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5BF9DA2628840E6200DBD48E /* template-userphrases.txt */; };
|
||||
5BF9DA2D288427E000DBD48E /* template-associatedPhrases-cht.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5BF9DA2C2884247800DBD48E /* template-associatedPhrases-cht.txt */; };
|
||||
5BFDF011289635C100417BBC /* ctlCandidateIMK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BFDF010289635C100417BBC /* ctlCandidateIMK.swift */; };
|
||||
6A187E2616004C5900466B2E /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6A187E2816004C5900466B2E /* MainMenu.xib */; };
|
||||
6A225A1F23679F2600F685C6 /* NotarizedArchives in Resources */ = {isa = PBXBuildFile; fileRef = 6A225A1E23679F2600F685C6 /* NotarizedArchives */; };
|
||||
6A2E40F6253A69DA00D1AE1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; };
|
||||
|
@ -320,6 +321,7 @@
|
|||
5BF9DA2528840E6200DBD48E /* template-replacements.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; path = "template-replacements.txt"; sourceTree = "<group>"; usesTabs = 0; };
|
||||
5BF9DA2628840E6200DBD48E /* template-userphrases.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; path = "template-userphrases.txt"; sourceTree = "<group>"; usesTabs = 0; };
|
||||
5BF9DA2C2884247800DBD48E /* template-associatedPhrases-cht.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; name = "template-associatedPhrases-cht.txt"; path = "../Data/components/cht/template-associatedPhrases-cht.txt"; sourceTree = "<group>"; };
|
||||
5BFDF010289635C100417BBC /* ctlCandidateIMK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlCandidateIMK.swift; sourceTree = "<group>"; };
|
||||
5BFDF48C27B51867009523B6 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Main.strings"; sourceTree = "<group>"; };
|
||||
6A0D4EA215FC0D2D00ABF4B3 /* vChewing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = vChewing.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6A0D4EF515FC0DA600ABF4B3 /* IME-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "IME-Info.plist"; sourceTree = "<group>"; };
|
||||
|
@ -570,6 +572,7 @@
|
|||
children = (
|
||||
5B62A34027AE7CD900A19448 /* ctlCandidate.swift */,
|
||||
5B242402284B0D6500520FE4 /* ctlCandidateUniversal.swift */,
|
||||
5BFDF010289635C100417BBC /* ctlCandidateIMK.swift */,
|
||||
);
|
||||
path = CandidateUI;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1203,6 +1206,7 @@
|
|||
5BA9FD4727FEF3C9002DE248 /* PreferencesStyleController.swift in Sources */,
|
||||
5B949BDB2816DDBC00D87B5D /* LMConsolidator.swift in Sources */,
|
||||
5B38F59F281E2E49007D5F5D /* 3_NodeAnchor.swift in Sources */,
|
||||
5BFDF011289635C100417BBC /* ctlCandidateIMK.swift in Sources */,
|
||||
5B62A34727AE7CD900A19448 /* ctlCandidate.swift in Sources */,
|
||||
5BA9FD3F27FEF3C8002DE248 /* Pane.swift in Sources */,
|
||||
5BB802DA27FABA8300CF1C19 /* ctlInputMethod_Menu.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue