1.7.0sp1 // Null Pointer Fix. Merge Gitee PR!44 from upd/1.7.0sp1
This commit is contained in:
commit
062914d115
2
AUTHORS
2
AUTHORS
|
@ -2,7 +2,7 @@ $ Main contributors and volunteers of this repository (vChewing for macOS):
|
||||||
|
|
||||||
- Shiki Suen // Main developer of vChewing for macOS, Megrez language engine, and Tekkon syllable composer engine.
|
- Shiki Suen // Main developer of vChewing for macOS, Megrez language engine, and Tekkon syllable composer engine.
|
||||||
- Hiraku Wang // Technical reinforcement in Cocoa during the Object-Cpp dev period of this project.
|
- Hiraku Wang // Technical reinforcement in Cocoa during the Object-Cpp dev period of this project.
|
||||||
- Isaac Xen // Technical reinforcement in Swift: SFX Module and StringView Ranges Extension.
|
- Isaac Xen // Technical reinforcement in Swift: SFX Module (NSSound ver.) and StringView Ranges Extension.
|
||||||
|
|
||||||
$ Contributors and volunteeres of the upstream repo, having no responsibility in discussing anything in the current repo:
|
$ Contributors and volunteeres of the upstream repo, having no responsibility in discussing anything in the current repo:
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 06d16d8a468668278ad9f50cc8629983c490fa42
|
Subproject commit 01adac46a15ab0bf907ca1bd362bdd1082e79c4e
|
|
@ -162,36 +162,38 @@ class KeyHandler {
|
||||||
|
|
||||||
func fixNode(value: String, respectCursorPushing: Bool = true) {
|
func fixNode(value: String, respectCursorPushing: Bool = true) {
|
||||||
let cursorIndex = min(actualCandidateCursorIndex + (mgrPrefs.useRearCursorMode ? 1 : 0), builderLength)
|
let cursorIndex = min(actualCandidateCursorIndex + (mgrPrefs.useRearCursorMode ? 1 : 0), builderLength)
|
||||||
let selectedNode: Megrez.NodeAnchor = _builder.grid.fixNodeSelectedCandidate(
|
_builder.grid.fixNodeSelectedCandidate(location: cursorIndex, value: value)
|
||||||
location: cursorIndex, value: value
|
// // 因半衰模組失能,故禁用之。
|
||||||
)
|
// let selectedNode: Megrez.NodeAnchor = _builder.grid.fixNodeSelectedCandidate(
|
||||||
// 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
// location: cursorIndex, value: value
|
||||||
if !mgrPrefs.useSCPCTypingMode {
|
// )
|
||||||
// If the length of the readings and the characters do not match,
|
// // 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
||||||
// it often means it is a special symbol and it should not be stored
|
// if !mgrPrefs.useSCPCTypingMode {
|
||||||
// in the user override model.
|
// // If the length of the readings and the characters do not match,
|
||||||
var addToUserOverrideModel = true
|
// // it often means it is a special symbol and it should not be stored
|
||||||
if selectedNode.spanningLength != value.count {
|
// // in the user override model.
|
||||||
IME.prtDebugIntel("UOM: SpanningLength != value.count, dismissing.")
|
// var addToUserOverrideModel = true
|
||||||
addToUserOverrideModel = false
|
// if selectedNode.spanningLength != value.count {
|
||||||
}
|
// IME.prtDebugIntel("UOM: SpanningLength != value.count, dismissing.")
|
||||||
if addToUserOverrideModel {
|
// addToUserOverrideModel = false
|
||||||
if let theNode = selectedNode.node {
|
// }
|
||||||
// 威注音的 SymbolLM 的 Score 是 -12。
|
// if addToUserOverrideModel {
|
||||||
if theNode.scoreFor(candidate: value) <= -12 {
|
// if let theNode = selectedNode.node {
|
||||||
IME.prtDebugIntel("UOM: Score <= -12, dismissing.")
|
// // 威注音的 SymbolLM 的 Score 是 -12。
|
||||||
addToUserOverrideModel = false
|
// if theNode.scoreFor(candidate: value) <= -12 {
|
||||||
}
|
// IME.prtDebugIntel("UOM: Score <= -12, dismissing.")
|
||||||
}
|
// addToUserOverrideModel = false
|
||||||
}
|
// }
|
||||||
if addToUserOverrideModel {
|
// }
|
||||||
IME.prtDebugIntel("UOM: Start Observation.")
|
// }
|
||||||
_userOverrideModel.observe(
|
// if addToUserOverrideModel {
|
||||||
walkedNodes: _walkedNodes, cursorIndex: cursorIndex, candidate: value,
|
// IME.prtDebugIntel("UOM: Start Observation.")
|
||||||
timestamp: NSDate().timeIntervalSince1970
|
// _userOverrideModel.observe(
|
||||||
)
|
// walkedNodes: _walkedNodes, cursorIndex: cursorIndex, candidate: value,
|
||||||
}
|
// timestamp: NSDate().timeIntervalSince1970
|
||||||
}
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
walk()
|
walk()
|
||||||
|
|
||||||
if mgrPrefs.moveCursorAfterSelectingCandidate, respectCursorPushing {
|
if mgrPrefs.moveCursorAfterSelectingCandidate, respectCursorPushing {
|
||||||
|
|
|
@ -188,7 +188,7 @@ extension KeyHandler {
|
||||||
let poppedText = popOverflowComposingTextAndWalk
|
let poppedText = popOverflowComposingTextAndWalk
|
||||||
|
|
||||||
// ... get and tweak override model suggestion if possible...
|
// ... get and tweak override model suggestion if possible...
|
||||||
dealWithOverrideModelSuggestions()
|
// dealWithOverrideModelSuggestions() // 暫時禁用,因為無法使其生效。
|
||||||
|
|
||||||
// ... then update the text.
|
// ... then update the text.
|
||||||
_composer.clear()
|
_composer.clear()
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// Copyright (c) 2022 and onwards Isaac Xen (MIT License).
|
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
// All possible vChewing-specific modifications are of:
|
|
||||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
|
||||||
/*
|
/*
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,52 +22,15 @@ 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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cocoa
|
import AVFoundation
|
||||||
|
import Foundation
|
||||||
public class clsSFX: NSObject, NSSoundDelegate {
|
|
||||||
private static let shared = clsSFX()
|
|
||||||
override private init() {
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var currentBeep: NSSound?
|
|
||||||
private func beep() {
|
|
||||||
let defaultVolume: Float = 0.4
|
|
||||||
// Stop existing beep
|
|
||||||
if let beep = currentBeep {
|
|
||||||
if beep.isPlaying {
|
|
||||||
for i in 1..<30 {
|
|
||||||
beep.volume = (defaultVolume / Float(i))
|
|
||||||
usleep(1000)
|
|
||||||
}
|
|
||||||
beep.stop()
|
|
||||||
beep.volume = defaultVolume
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create a new beep sound if possible
|
|
||||||
var sndBeep: String
|
|
||||||
if mgrPrefs.shouldNotFartInLieuOfBeep == false {
|
|
||||||
sndBeep = "Fart"
|
|
||||||
} else {
|
|
||||||
sndBeep = "Beep"
|
|
||||||
}
|
|
||||||
guard
|
|
||||||
let beep = NSSound(named: sndBeep)
|
|
||||||
else {
|
|
||||||
NSSound.beep()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
beep.delegate = self
|
|
||||||
beep.volume = defaultVolume
|
|
||||||
beep.play()
|
|
||||||
currentBeep = beep
|
|
||||||
}
|
|
||||||
|
|
||||||
public func sound(_: NSSound, didFinishPlaying _: Bool) {
|
|
||||||
currentBeep = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public class clsSFX {
|
||||||
static func beep() {
|
static func beep() {
|
||||||
shared.beep()
|
let filePath = Bundle.main.path(forResource: mgrPrefs.shouldNotFartInLieuOfBeep ? "Beep" : "Fart", ofType: "m4a")!
|
||||||
|
let fileURL = URL(fileURLWithPath: filePath)
|
||||||
|
var soundID: SystemSoundID = 0
|
||||||
|
AudioServicesCreateSystemSoundID(fileURL as CFURL, &soundID)
|
||||||
|
AudioServicesPlaySystemSound(soundID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -409,8 +409,6 @@ public class ctlCandidateUniversal: ctlCandidate {
|
||||||
let buttonAttribute: [NSAttributedString.Key: Any] = [.font: NSFont.systemFont(ofSize: 9.0)]
|
let buttonAttribute: [NSAttributedString.Key: Any] = [.font: NSFont.systemFont(ofSize: 9.0)]
|
||||||
|
|
||||||
nextPageButton = .init(frame: contentRect)
|
nextPageButton = .init(frame: contentRect)
|
||||||
NSColor.controlBackgroundColor.setFill()
|
|
||||||
NSBezierPath.fill(nextPageButton.bounds)
|
|
||||||
nextPageButton.wantsLayer = true
|
nextPageButton.wantsLayer = true
|
||||||
nextPageButton.layer?.masksToBounds = true
|
nextPageButton.layer?.masksToBounds = true
|
||||||
nextPageButton.layer?.borderColor = NSColor.clear.cgColor
|
nextPageButton.layer?.borderColor = NSColor.clear.cgColor
|
||||||
|
@ -422,8 +420,6 @@ public class ctlCandidateUniversal: ctlCandidate {
|
||||||
string: " ", attributes: buttonAttribute
|
string: " ", attributes: buttonAttribute
|
||||||
) // Next Page Arrow
|
) // Next Page Arrow
|
||||||
prevPageButton = .init(frame: contentRect)
|
prevPageButton = .init(frame: contentRect)
|
||||||
NSColor.controlBackgroundColor.setFill()
|
|
||||||
NSBezierPath.fill(prevPageButton.bounds)
|
|
||||||
prevPageButton.wantsLayer = true
|
prevPageButton.wantsLayer = true
|
||||||
prevPageButton.layer?.masksToBounds = true
|
prevPageButton.layer?.masksToBounds = true
|
||||||
prevPageButton.layer?.borderColor = NSColor.clear.cgColor
|
prevPageButton.layer?.borderColor = NSColor.clear.cgColor
|
||||||
|
@ -439,17 +435,13 @@ public class ctlCandidateUniversal: ctlCandidate {
|
||||||
|
|
||||||
// MARK: Add Page Counter
|
// MARK: Add Page Counter
|
||||||
|
|
||||||
contentRect.size = NSSize(width: 40.0, height: 20.0)
|
contentRect = NSRect(x: 128.0, y: 128.0, width: 48.0, height: 20.0)
|
||||||
pageCounterLabel = .init(frame: contentRect)
|
pageCounterLabel = .init(frame: contentRect)
|
||||||
pageCounterLabel.isEditable = false
|
pageCounterLabel.isEditable = false
|
||||||
pageCounterLabel.isSelectable = false
|
pageCounterLabel.isSelectable = false
|
||||||
pageCounterLabel.isBezeled = false
|
pageCounterLabel.isBezeled = false
|
||||||
pageCounterLabel.textColor = NSColor(
|
pageCounterLabel.attributedStringValue = NSMutableAttributedString(
|
||||||
red: 0.86, green: 0.86, blue: 0.86, alpha: 1.00
|
string: " ", attributes: buttonAttribute
|
||||||
)
|
|
||||||
pageCounterLabel.drawsBackground = true
|
|
||||||
pageCounterLabel.backgroundColor = NSColor(
|
|
||||||
red: 0.18, green: 0.18, blue: 0.18, alpha: 1.00
|
|
||||||
)
|
)
|
||||||
panel.contentView?.addSubview(pageCounterLabel)
|
panel.contentView?.addSubview(pageCounterLabel)
|
||||||
|
|
||||||
|
@ -466,8 +458,6 @@ public class ctlCandidateUniversal: ctlCandidate {
|
||||||
|
|
||||||
prevPageButton.target = self
|
prevPageButton.target = self
|
||||||
prevPageButton.action = #selector(pageButtonAction(_:))
|
prevPageButton.action = #selector(pageButtonAction(_:))
|
||||||
|
|
||||||
pageCounterLabel.font = pageCounterFont
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(*, unavailable)
|
@available(*, unavailable)
|
||||||
|
@ -554,30 +544,6 @@ extension ctlCandidateUniversal {
|
||||||
return totalCount / keyLabelCount + ((totalCount % keyLabelCount) != 0 ? 1 : 0)
|
return totalCount / keyLabelCount + ((totalCount % keyLabelCount) != 0 ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用來顯示頁面計數器的 NSFont。因為結果可 nil,所以最好 guard-let 再用。
|
|
||||||
private var pageCounterFont: NSFont? {
|
|
||||||
var pointSize: CGFloat { candidateView.fractionFontSize }
|
|
||||||
let systemFontDesc = NSFont.systemFont(ofSize: pointSize, weight: .light).fontDescriptor
|
|
||||||
let fractionFontDesc = systemFontDesc.addingAttributes(
|
|
||||||
[
|
|
||||||
NSFontDescriptor.AttributeName.traits: [
|
|
||||||
[
|
|
||||||
NSFontDescriptor.FeatureKey.typeIdentifier: kFractionsType,
|
|
||||||
NSFontDescriptor.FeatureKey.selectorIdentifier: kDiagonalFractionsSelector,
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
return NSFont(descriptor: fractionFontDesc, size: pointSize) ?? nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用來生成拿給頁面計數器用的顯示字串。
|
|
||||||
// TODO: 這衰洨的 pageCount 總是返回空字串,需要調查。
|
|
||||||
private var pageCounterText: String {
|
|
||||||
if pageCount < 2 { return .init() }
|
|
||||||
return "\(currentPageIndex + 1)/"
|
|
||||||
}
|
|
||||||
|
|
||||||
private func layoutCandidateView() {
|
private func layoutCandidateView() {
|
||||||
guard let delegate = delegate else {
|
guard let delegate = delegate else {
|
||||||
return
|
return
|
||||||
|
@ -627,11 +593,11 @@ extension ctlCandidateUniversal {
|
||||||
prevPageButton.isHidden = true
|
prevPageButton.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !pageCounterText.isEmpty {
|
if pageCount >= 2 {
|
||||||
let attrString = NSAttributedString(
|
let attrString = NSMutableAttributedString(
|
||||||
string: pageCounterText.appending(String(pageCount)),
|
string: "\(currentPageIndex + 1)/\(pageCount)",
|
||||||
attributes: [
|
attributes: [
|
||||||
.font: pageCounterFont as AnyObject
|
.font: NSFont.systemFont(ofSize: candidateView.fractionFontSize)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
pageCounterLabel.attributedStringValue = attrString
|
pageCounterLabel.attributedStringValue = attrString
|
||||||
|
@ -641,6 +607,7 @@ extension ctlCandidateUniversal {
|
||||||
)
|
)
|
||||||
|
|
||||||
rect.size.height += 3
|
rect.size.height += 3
|
||||||
|
rect.size.width += 4
|
||||||
let rectOriginY: CGFloat =
|
let rectOriginY: CGFloat =
|
||||||
(currentLayout == .horizontal)
|
(currentLayout == .horizontal)
|
||||||
? (newSize.height - rect.height) / 2
|
? (newSize.height - rect.height) / 2
|
||||||
|
|
Loading…
Reference in New Issue