NotifierUI // Refactor into a standalone package.
This commit is contained in:
parent
d8fb9aee1d
commit
1f5481a8d4
|
@ -0,0 +1,9 @@
|
|||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
/*.xcodeproj
|
||||
xcuserdata/
|
||||
DerivedData/
|
||||
.swiftpm/config/registries.json
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
.netrc
|
|
@ -0,0 +1,22 @@
|
|||
// swift-tools-version:5.3
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "NotifierUI",
|
||||
platforms: [
|
||||
.macOS(.v10_11)
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
name: "NotifierUI",
|
||||
targets: ["NotifierUI"]
|
||||
)
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "NotifierUI",
|
||||
dependencies: []
|
||||
)
|
||||
]
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
# NotifierUI
|
||||
|
||||
威注音的飄雲通知視窗。
|
||||
|
||||
```
|
||||
// (c) 2021 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.
|
||||
```
|
|
@ -0,0 +1,155 @@
|
|||
// (c) 2021 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
|
||||
|
||||
public class Notifier: NSWindowController {
|
||||
public static func notify(message: String) {
|
||||
Self.message = message
|
||||
}
|
||||
|
||||
static var message: String = "" {
|
||||
didSet {
|
||||
if !Self.message.isEmpty {
|
||||
Self.message = Notifier(message).blankValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private Declarations
|
||||
|
||||
private static var instanceStack: [Notifier] = []
|
||||
private let blankValue = ""
|
||||
|
||||
@discardableResult private init(_ message: String) {
|
||||
let rawMessage = message.replacingOccurrences(of: "\n", with: "")
|
||||
guard let screenRect = NSScreen.main?.visibleFrame, !rawMessage.isEmpty else {
|
||||
super.init(window: nil)
|
||||
return
|
||||
}
|
||||
let kLargeFontSize: Double = 17
|
||||
let kSmallFontSize: Double = 15
|
||||
let messageArray = message.components(separatedBy: "\n")
|
||||
|
||||
let paraStyle = NSMutableParagraphStyle()
|
||||
paraStyle.setParagraphStyle(NSParagraphStyle.default)
|
||||
paraStyle.alignment = .center
|
||||
let attrTitle: [NSAttributedString.Key: AnyObject] = [
|
||||
.foregroundColor: NSColor.controlTextColor,
|
||||
.font: NSFont.boldSystemFont(ofSize: kLargeFontSize),
|
||||
.paragraphStyle: paraStyle,
|
||||
]
|
||||
let attrString = NSMutableAttributedString(string: messageArray[0], attributes: attrTitle)
|
||||
let attrAlt: [NSAttributedString.Key: AnyObject] = [
|
||||
.foregroundColor: NSColor.secondaryLabelColor,
|
||||
.font: NSFont.systemFont(ofSize: kSmallFontSize),
|
||||
.paragraphStyle: paraStyle,
|
||||
]
|
||||
let additionalString = messageArray.count > 1 ? "\n\(messageArray[1])" : ""
|
||||
let attrStringAlt = NSMutableAttributedString(string: additionalString, attributes: attrAlt)
|
||||
attrString.insert(attrStringAlt, at: attrString.length)
|
||||
|
||||
let textRect: NSRect = attrString.boundingRect(
|
||||
with: NSSize(width: 1600.0, height: 1600.0), options: [.usesLineFragmentOrigin]
|
||||
)
|
||||
let windowWidth = Double(4) * kLargeFontSize + textRect.width
|
||||
let contentRect = NSRect(x: 0, y: 0, width: windowWidth, height: 60.0)
|
||||
var windowRect = contentRect
|
||||
windowRect.origin.x = screenRect.maxX - windowRect.width - 10
|
||||
windowRect.origin.y = screenRect.maxY - windowRect.height - 10
|
||||
let styleMask: NSWindow.StyleMask = [.borderless]
|
||||
|
||||
let transparentVisualEffect = NSVisualEffectView()
|
||||
transparentVisualEffect.blendingMode = .behindWindow
|
||||
transparentVisualEffect.state = .active
|
||||
|
||||
let theWindow = NSWindow(
|
||||
contentRect: windowRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||
)
|
||||
theWindow.contentView = transparentVisualEffect
|
||||
theWindow.isMovableByWindowBackground = true
|
||||
theWindow.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel))
|
||||
theWindow.hasShadow = true
|
||||
theWindow.backgroundColor = .textBackgroundColor
|
||||
theWindow.title = ""
|
||||
theWindow.titlebarAppearsTransparent = true
|
||||
theWindow.titleVisibility = .hidden
|
||||
theWindow.showsToolbarButton = false
|
||||
theWindow.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
|
||||
theWindow.standardWindowButton(NSWindow.ButtonType.miniaturizeButton)?.isHidden = true
|
||||
theWindow.standardWindowButton(NSWindow.ButtonType.closeButton)?.isHidden = true
|
||||
theWindow.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
|
||||
theWindow.isReleasedWhenClosed = true
|
||||
theWindow.isMovable = false
|
||||
|
||||
let lblMessage = NSTextField()
|
||||
lblMessage.attributedStringValue = attrString
|
||||
lblMessage.drawsBackground = false
|
||||
lblMessage.font = .boldSystemFont(ofSize: NSFont.systemFontSize(for: .regular))
|
||||
lblMessage.frame = contentRect
|
||||
lblMessage.isBezeled = false
|
||||
lblMessage.isEditable = false
|
||||
lblMessage.isSelectable = false
|
||||
lblMessage.textColor = .controlTextColor
|
||||
theWindow.contentView?.addSubview(lblMessage)
|
||||
|
||||
let x = lblMessage.frame.origin.x
|
||||
let y = ((theWindow.frame.height) - textRect.height) / 1.9
|
||||
let newFrame = NSRect(x: x, y: y, width: theWindow.frame.width, height: textRect.height)
|
||||
lblMessage.frame = newFrame
|
||||
|
||||
super.init(window: theWindow)
|
||||
display()
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override public func close() {
|
||||
super.close()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private Functions
|
||||
|
||||
extension Notifier {
|
||||
private func shiftExistingWindowPositions() {
|
||||
guard let window = window, !Self.instanceStack.isEmpty else { return }
|
||||
for theInstanceWindow in Self.instanceStack.compactMap(\.window) {
|
||||
var theOrigin = theInstanceWindow.frame
|
||||
theOrigin.origin.y -= (10 + window.frame.height)
|
||||
theInstanceWindow.setFrame(theOrigin, display: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func fadeIn() {
|
||||
guard let window = window else { return }
|
||||
let afterRect = window.frame
|
||||
var beforeRect = afterRect
|
||||
beforeRect.origin.x -= 20
|
||||
window.setFrame(beforeRect, display: true)
|
||||
window.orderFront(self)
|
||||
window.setFrame(afterRect, display: true, animate: true)
|
||||
}
|
||||
|
||||
private func display() {
|
||||
let existingInstanceArray = Self.instanceStack.compactMap(\.window)
|
||||
if !existingInstanceArray.isEmpty {
|
||||
existingInstanceArray.forEach { $0.alphaValue *= 0.5 }
|
||||
}
|
||||
shiftExistingWindowPositions()
|
||||
fadeIn()
|
||||
Self.instanceStack.insert(self, at: 0)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
self.close()
|
||||
Self.instanceStack.removeAll(where: { $0.window == nil })
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
import BookmarkManager
|
||||
import LangModelAssembly
|
||||
import Megrez
|
||||
import NotifierUI
|
||||
import Shared
|
||||
|
||||
/// 使用者辭典資料預設範例檔案名稱。
|
||||
|
@ -98,7 +99,7 @@ public enum LMMgr {
|
|||
}
|
||||
if !Self.lmCHT.isLanguageModelLoaded {
|
||||
showFinishNotification = true
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Loading CHT Core Dict...", comment: "")
|
||||
)
|
||||
group.enter()
|
||||
|
@ -109,7 +110,7 @@ public enum LMMgr {
|
|||
}
|
||||
if !Self.lmCHS.isLanguageModelLoaded {
|
||||
showFinishNotification = true
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Loading CHS Core Dict...", comment: "")
|
||||
)
|
||||
group.enter()
|
||||
|
@ -120,7 +121,7 @@ public enum LMMgr {
|
|||
}
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
if showFinishNotification {
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Core Dict loading complete.", comment: "")
|
||||
)
|
||||
}
|
||||
|
@ -162,7 +163,7 @@ public enum LMMgr {
|
|||
case .imeModeCHS:
|
||||
if !Self.lmCHS.isLanguageModelLoaded {
|
||||
showFinishNotification = true
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Loading CHS Core Dict...", comment: "")
|
||||
)
|
||||
group.enter()
|
||||
|
@ -174,7 +175,7 @@ public enum LMMgr {
|
|||
case .imeModeCHT:
|
||||
if !Self.lmCHT.isLanguageModelLoaded {
|
||||
showFinishNotification = true
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Loading CHT Core Dict...", comment: "")
|
||||
)
|
||||
group.enter()
|
||||
|
@ -187,7 +188,7 @@ public enum LMMgr {
|
|||
}
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
if showFinishNotification {
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Core Dict loading complete.", comment: "")
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
// (c) 2021 and onwards Weizhong Yang (MIT License).
|
||||
// All possible vChewing-specific modifications are of:
|
||||
// (c) 2021 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.
|
||||
|
||||
private protocol NotifierWindowDelegate: AnyObject {
|
||||
func windowDidBecomeClicked(_ window: NotifierWindow)
|
||||
}
|
||||
|
||||
private class NotifierWindow: NSWindow {
|
||||
weak var clickDelegate: NotifierWindowDelegate?
|
||||
|
||||
override func mouseDown(with _: NSEvent) {
|
||||
clickDelegate?.windowDidBecomeClicked(self)
|
||||
}
|
||||
}
|
||||
|
||||
private let kWindowWidth: CGFloat = 213.0
|
||||
private let kWindowHeight: CGFloat = 60.0
|
||||
|
||||
public class NotifierController: NSWindowController, NotifierWindowDelegate {
|
||||
static var message: String = "" {
|
||||
didSet {
|
||||
if !Self.message.isEmpty {
|
||||
NotifierController.initiateWithNoStay(message: message)
|
||||
Self.message = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var messageTextField: NSTextField
|
||||
|
||||
private var message: String = "" {
|
||||
didSet {
|
||||
let paraStyle = NSMutableParagraphStyle()
|
||||
paraStyle.setParagraphStyle(NSParagraphStyle.default)
|
||||
paraStyle.alignment = .center
|
||||
let attr: [NSAttributedString.Key: AnyObject] = [
|
||||
.foregroundColor: foregroundColor,
|
||||
.font: NSFont.boldSystemFont(ofSize: NSFont.systemFontSize(for: .regular)),
|
||||
.paragraphStyle: paraStyle,
|
||||
]
|
||||
let attrString = NSAttributedString(string: message, attributes: attr)
|
||||
messageTextField.attributedStringValue = attrString
|
||||
let width = window?.frame.width ?? kWindowWidth
|
||||
let rect = attrString.boundingRect(
|
||||
with: NSSize(width: width, height: 1600), options: .usesLineFragmentOrigin
|
||||
)
|
||||
let height = rect.height
|
||||
let x = messageTextField.frame.origin.x
|
||||
let y = ((window?.frame.height ?? kWindowHeight) - height) / 2
|
||||
let newFrame = NSRect(x: x, y: y, width: width, height: height)
|
||||
messageTextField.frame = newFrame
|
||||
}
|
||||
}
|
||||
|
||||
private var shouldStay = false
|
||||
private var backgroundColor: NSColor = .textBackgroundColor {
|
||||
didSet {
|
||||
window?.backgroundColor = backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
private var foregroundColor: NSColor = .controlTextColor {
|
||||
didSet {
|
||||
messageTextField.textColor = foregroundColor
|
||||
}
|
||||
}
|
||||
|
||||
private var waitTimer: Timer?
|
||||
private var fadeTimer: Timer?
|
||||
|
||||
private static var instanceCount = 0
|
||||
private static var lastLocation = NSPoint.zero
|
||||
|
||||
private static func initiateWithNoStay(message: String) {
|
||||
let controller = NotifierController()
|
||||
controller.message = message
|
||||
controller.show()
|
||||
}
|
||||
|
||||
public static func notify(message: String) {
|
||||
Self.message = message
|
||||
}
|
||||
|
||||
public static func notify(message: String, stay: Bool) {
|
||||
let controller = NotifierController()
|
||||
controller.message = message
|
||||
controller.shouldStay = stay
|
||||
controller.show()
|
||||
}
|
||||
|
||||
private static func increaseInstanceCount() {
|
||||
instanceCount += 1
|
||||
}
|
||||
|
||||
private static func decreaseInstanceCount() {
|
||||
instanceCount -= 1
|
||||
if instanceCount < 0 {
|
||||
instanceCount = 0
|
||||
}
|
||||
}
|
||||
|
||||
private init() {
|
||||
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||
let contentRect = NSRect(x: 0, y: 0, width: kWindowWidth, height: kWindowHeight)
|
||||
var windowRect = contentRect
|
||||
windowRect.origin.x = screenRect.maxX - windowRect.width - 10
|
||||
windowRect.origin.y = screenRect.maxY - windowRect.height - 10
|
||||
let styleMask: NSWindow.StyleMask = [.fullSizeContentView, .titled]
|
||||
|
||||
let transparentVisualEffect = NSVisualEffectView()
|
||||
transparentVisualEffect.blendingMode = .behindWindow
|
||||
transparentVisualEffect.state = .active
|
||||
|
||||
let panel = NotifierWindow(
|
||||
contentRect: windowRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||
)
|
||||
panel.contentView = transparentVisualEffect
|
||||
panel.isMovableByWindowBackground = true
|
||||
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel))
|
||||
panel.hasShadow = true
|
||||
panel.backgroundColor = backgroundColor
|
||||
panel.title = ""
|
||||
panel.titlebarAppearsTransparent = true
|
||||
panel.titleVisibility = .hidden
|
||||
panel.showsToolbarButton = false
|
||||
panel.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
|
||||
panel.standardWindowButton(NSWindow.ButtonType.miniaturizeButton)?.isHidden = true
|
||||
panel.standardWindowButton(NSWindow.ButtonType.closeButton)?.isHidden = true
|
||||
panel.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
|
||||
|
||||
messageTextField = NSTextField()
|
||||
messageTextField.frame = contentRect
|
||||
messageTextField.isEditable = false
|
||||
messageTextField.isSelectable = false
|
||||
messageTextField.isBezeled = false
|
||||
messageTextField.textColor = foregroundColor
|
||||
messageTextField.drawsBackground = false
|
||||
messageTextField.font = .boldSystemFont(ofSize: NSFont.systemFontSize(for: .regular))
|
||||
panel.contentView?.addSubview(messageTextField)
|
||||
|
||||
super.init(window: panel)
|
||||
|
||||
panel.clickDelegate = self
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func show() {
|
||||
func setStartLocation() {
|
||||
if Self.instanceCount == 0 {
|
||||
return
|
||||
}
|
||||
let lastLocation = Self.lastLocation
|
||||
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||
var windowRect = window?.frame ?? NSRect.seniorTheBeast
|
||||
windowRect.origin.x = lastLocation.x
|
||||
windowRect.origin.y = lastLocation.y - 10 - windowRect.height
|
||||
|
||||
if windowRect.origin.y < screenRect.minY {
|
||||
return
|
||||
}
|
||||
|
||||
window?.setFrame(windowRect, display: true)
|
||||
}
|
||||
|
||||
func moveIn() {
|
||||
let afterRect = window?.frame ?? NSRect.seniorTheBeast
|
||||
Self.lastLocation = afterRect.origin
|
||||
var beforeRect = afterRect
|
||||
beforeRect.origin.y += 10
|
||||
window?.setFrame(beforeRect, display: true)
|
||||
window?.orderFront(self)
|
||||
window?.setFrame(afterRect, display: true, animate: true)
|
||||
}
|
||||
|
||||
setStartLocation()
|
||||
moveIn()
|
||||
Self.increaseInstanceCount()
|
||||
waitTimer = Timer.scheduledTimer(
|
||||
timeInterval: shouldStay ? 5 : 1, target: self, selector: #selector(fadeOut),
|
||||
userInfo: nil,
|
||||
repeats: false
|
||||
)
|
||||
}
|
||||
|
||||
@objc private func doFadeOut(_: Timer) {
|
||||
let opacity = window?.alphaValue ?? 0
|
||||
if opacity <= 0 {
|
||||
close()
|
||||
} else {
|
||||
window?.alphaValue = opacity - 0.2
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func fadeOut() {
|
||||
waitTimer?.invalidate()
|
||||
waitTimer = nil
|
||||
Self.decreaseInstanceCount()
|
||||
fadeTimer = Timer.scheduledTimer(
|
||||
timeInterval: 0.01, target: self, selector: #selector(doFadeOut(_:)), userInfo: nil,
|
||||
repeats: true
|
||||
)
|
||||
}
|
||||
|
||||
override public func close() {
|
||||
waitTimer?.invalidate()
|
||||
waitTimer = nil
|
||||
fadeTimer?.invalidate()
|
||||
fadeTimer = nil
|
||||
super.close()
|
||||
}
|
||||
|
||||
fileprivate func windowDidBecomeClicked(_: NotifierWindow) {
|
||||
fadeOut()
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
// requirements defined in MIT License.
|
||||
|
||||
import IMKUtils
|
||||
import NotifierUI
|
||||
import Shared
|
||||
import ShiftKeyUpChecker
|
||||
import Tekkon
|
||||
|
@ -272,7 +273,7 @@ class ctlInputMethod: IMKInputController {
|
|||
if #available(macOS 10.15, *) {
|
||||
if Self.theShiftKeyDetector.check(event), !PrefMgr.shared.disableShiftTogglingAlphanumericalMode {
|
||||
if !shouldUseShiftToggleHandle || (!rencentKeyHandledByKeyHandlerEtc && shouldUseShiftToggleHandle) {
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: isASCIIMode.toggled()
|
||||
? NSLocalizedString("Alphanumerical Input Mode", comment: "")
|
||||
: NSLocalizedString("Chinese Input Mode", comment: "")
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// marks, or product names of Contributor, except as required to fulfill notice
|
||||
// requirements defined in MIT License.
|
||||
|
||||
import NotifierUI
|
||||
import Preferences
|
||||
|
||||
extension Bool {
|
||||
|
@ -223,7 +224,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleSCPCTypingMode(_: Any? = nil) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.useSCPCTypingMode.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -233,7 +234,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleChineseConverter(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.chineseConversionEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -243,7 +244,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleShiftJISShinjitaiOutput(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.shiftJISShinjitaiOutputEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -253,7 +254,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleCurrencyNumerals(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.currencyNumeralsEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -263,7 +264,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleHalfWidthPunctuation(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.halfWidthPunctuationEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -273,7 +274,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleCNS11643Enabled(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.cns11643Enabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -283,7 +284,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleSymbolEnabled(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.symbolInputEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -293,7 +294,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func toggleAssociatedPhrasesEnabled(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.associatedPhrasesEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
@ -303,7 +304,7 @@ extension ctlInputMethod {
|
|||
|
||||
@objc func togglePhraseReplacement(_: Any?) {
|
||||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
Notifier.notify(
|
||||
message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n"
|
||||
+ (PrefMgr.shared.phraseReplacementEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */; };
|
||||
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; };
|
||||
5B62A34727AE7CD900A19448 /* ctlCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34027AE7CD900A19448 /* ctlCandidate.swift */; };
|
||||
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.swift */; };
|
||||
5B630A3C28CC97020010D076 /* ctlPopupCompositionBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */; };
|
||||
5B6C141228A9D4B30098ADF8 /* ctlInputMethod_HandleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* ctlInputMethod_HandleEvent.swift */; };
|
||||
5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; };
|
||||
|
@ -58,6 +57,7 @@
|
|||
5BC447A02865686500EDC323 /* data-symbols.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71E283B4AEA0078EB25 /* data-symbols.plist */; };
|
||||
5BC447A12865686500EDC323 /* data-zhuyinwen.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71F283B4AEA0078EB25 /* data-zhuyinwen.plist */; };
|
||||
5BC447A628656A1900EDC323 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A228656A1900EDC323 /* Placeholder.swift */; };
|
||||
5BC5E01E28DDE4770094E427 /* NotifierUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5BC5E01D28DDE4770094E427 /* NotifierUI */; };
|
||||
5BCCAFF828DB19A300AB1B27 /* PrefMgr_Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BCCAFF728DB19A300AB1B27 /* PrefMgr_Extension.swift */; };
|
||||
5BD0113D2818543900609769 /* KeyHandler_Core.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113C2818543900609769 /* KeyHandler_Core.swift */; };
|
||||
5BD05BCA27B2A43D004C4F1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; };
|
||||
|
@ -206,7 +206,6 @@
|
|||
5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlTooltip.swift; sourceTree = "<group>"; };
|
||||
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B62A34027AE7CD900A19448 /* ctlCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlCandidate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B62A34527AE7CD900A19448 /* NotifierController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = NotifierController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlPopupCompositionBuffer.swift; sourceTree = "<group>"; };
|
||||
5B65B919284D0185007C558B /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
5B6C141128A9D4B30098ADF8 /* ctlInputMethod_HandleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlInputMethod_HandleEvent.swift; sourceTree = "<group>"; };
|
||||
|
@ -246,6 +245,7 @@
|
|||
5BC2652127E04B7B00700291 /* uninstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; lineEnding = 0; path = uninstall.sh; sourceTree = "<group>"; };
|
||||
5BC447A228656A1900EDC323 /* Placeholder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Placeholder.swift; sourceTree = "<group>"; };
|
||||
5BC447AB2865BEF500EDC323 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; path = AUTHORS; sourceTree = "<group>"; };
|
||||
5BC5E01C28DDE4270094E427 /* vChewing_NotifierUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = vChewing_NotifierUI; path = Packages/vChewing_NotifierUI; sourceTree = "<group>"; };
|
||||
5BCCAFF728DB19A300AB1B27 /* PrefMgr_Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefMgr_Extension.swift; sourceTree = "<group>"; };
|
||||
5BD0113C2818543900609769 /* KeyHandler_Core.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = KeyHandler_Core.swift; sourceTree = "<group>"; usesTabs = 0; };
|
||||
5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = vChewingPhraseEditor.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -353,6 +353,7 @@
|
|||
5B40113928D7050D00A9D4CB /* Shared in Frameworks */,
|
||||
5BFC63C628D48806004A77B7 /* NSAttributedTextView in Frameworks */,
|
||||
5BDB7A3B28D4824A001AC277 /* FolderMonitor in Frameworks */,
|
||||
5BC5E01E28DDE4770094E427 /* NotifierUI in Frameworks */,
|
||||
5B40113C28D71C0100A9D4CB /* Uninstaller in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -434,7 +435,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
5B62A33E27AE7CD900A19448 /* CandidateUI */,
|
||||
5B62A34427AE7CD900A19448 /* NotifierUI */,
|
||||
5B630A3A28CC96D80010D076 /* PopupCompositionBufferUI */,
|
||||
5BA9FD0927FED9F3002DE248 /* PrefUI */,
|
||||
5B62A34227AE7CD900A19448 /* TooltipUI */,
|
||||
|
@ -481,14 +481,6 @@
|
|||
path = TooltipUI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5B62A34427AE7CD900A19448 /* NotifierUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5B62A34527AE7CD900A19448 /* NotifierController.swift */,
|
||||
);
|
||||
path = NotifierUI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5B62A35027AE7F6600A19448 /* Data */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -595,6 +587,7 @@
|
|||
5BFC63C728D49511004A77B7 /* vChewing_IMKUtils */,
|
||||
5BFC63CD28D4AC98004A77B7 /* vChewing_LangModelAssembly */,
|
||||
5BDB7A3328D47587001AC277 /* vChewing_Megrez */,
|
||||
5BC5E01C28DDE4270094E427 /* vChewing_NotifierUI */,
|
||||
5B98114628D6198000CBC605 /* vChewing_PinyinPhonaConverter */,
|
||||
5B963C9E28D5C14600DCEE88 /* vChewing_Shared */,
|
||||
5B963CA128D5C22D00DCEE88 /* vChewing_SwiftExtension */,
|
||||
|
@ -795,6 +788,7 @@
|
|||
5B98114728D6198700CBC605 /* PinyinPhonaConverter */,
|
||||
5B40113828D7050D00A9D4CB /* Shared */,
|
||||
5B40113B28D71C0100A9D4CB /* Uninstaller */,
|
||||
5BC5E01D28DDE4770094E427 /* NotifierUI */,
|
||||
);
|
||||
productName = vChewing;
|
||||
productReference = 6A0D4EA215FC0D2D00ABF4B3 /* vChewing.app */;
|
||||
|
@ -1079,7 +1073,6 @@
|
|||
D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */,
|
||||
5BD0113D2818543900609769 /* KeyHandler_Core.swift in Sources */,
|
||||
5BF56F9A28C39D1800DD6839 /* IMEStateData.swift in Sources */,
|
||||
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */,
|
||||
5B21176C287539BB000443A9 /* ctlInputMethod_HandleStates.swift in Sources */,
|
||||
5BAEFAD028012565001F42C9 /* LMMgr.swift in Sources */,
|
||||
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */,
|
||||
|
@ -1791,6 +1784,10 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = PinyinPhonaConverter;
|
||||
};
|
||||
5BC5E01D28DDE4770094E427 /* NotifierUI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = NotifierUI;
|
||||
};
|
||||
5BDB7A3828D4824A001AC277 /* BookmarkManager */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = BookmarkManager;
|
||||
|
|
Loading…
Reference in New Issue