Files
openless/Sources/OpenLessApp/MenuBarController.swift
T

114 lines
3.5 KiB
Swift

import AppKit
import OpenLessCore
import OpenLessPersistence
@MainActor
final class MenuBarController {
private let statusItem: NSStatusItem
private let actions: MenuActions
private weak var coordinator: DictationCoordinator?
init(coordinator: DictationCoordinator) {
self.coordinator = coordinator
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button {
if let image = NSImage(systemSymbolName: "mic.circle", accessibilityDescription: "OpenLess") {
image.isTemplate = true
button.image = image
} else {
button.title = "OL"
}
button.toolTip = "OpenLess — 点击菜单选择模式 / 退出"
}
actions = MenuActions(coordinator: coordinator)
statusItem.menu = buildMenu()
}
func refreshMenu() {
statusItem.menu = buildMenu()
}
private func buildMenu() -> NSMenu {
let menu = NSMenu()
let title = NSMenuItem(title: "OpenLess", action: nil, keyEquivalent: "")
title.isEnabled = false
menu.addItem(title)
menu.addItem(.separator())
let toggle = NSMenuItem(title: "开始 / 停止录音", action: #selector(MenuActions.toggleDictation), keyEquivalent: "")
toggle.target = actions
menu.addItem(toggle)
menu.addItem(.separator())
let modeHeader = NSMenuItem(title: "润色模式", action: nil, keyEquivalent: "")
modeHeader.isEnabled = false
menu.addItem(modeHeader)
let currentMode = UserPreferences.shared.polishMode
for mode in PolishMode.allCases {
let item = NSMenuItem(
title: mode.displayName,
action: #selector(MenuActions.selectMode(_:)),
keyEquivalent: ""
)
item.target = actions
item.state = (mode == currentMode) ? .on : .off
item.representedObject = mode.rawValue
menu.addItem(item)
}
menu.addItem(.separator())
let settings = NSMenuItem(title: "打开设置…", action: #selector(MenuActions.openSettings), keyEquivalent: ",")
settings.target = actions
menu.addItem(settings)
let revealLog = NSMenuItem(title: "在 Finder 中显示日志", action: #selector(MenuActions.revealLog), keyEquivalent: "l")
revealLog.target = actions
menu.addItem(revealLog)
menu.addItem(.separator())
let quit = NSMenuItem(
title: "退出 OpenLess",
action: #selector(NSApplication.terminate(_:)),
keyEquivalent: "q"
)
menu.addItem(quit)
return menu
}
}
@MainActor
private final class MenuActions: NSObject {
private weak var coordinator: DictationCoordinator?
init(coordinator: DictationCoordinator) {
self.coordinator = coordinator
}
@objc func selectMode(_ sender: NSMenuItem) {
guard let raw = sender.representedObject as? String,
let mode = PolishMode(rawValue: raw) else { return }
UserPreferences.shared.polishMode = mode
Log.write("切换润色模式 → \(mode.displayName)")
coordinator?.menuBar?.refreshMenu()
}
@objc func openSettings() {
coordinator?.openSettings()
}
@objc func toggleDictation() {
coordinator?.toggleDictationFromMenu()
}
@objc func revealLog() {
NSWorkspace.shared.activateFileViewerSelecting([Log.fileURL])
}
}