import AppKit import Foundation /// The menu bar item: the app's only permanent UI, and the place to turn the /// wheel off or fall back to picking files by hand. final class MenuBarController: NSObject, NSMenuDelegate { private var statusItem: NSStatusItem? func install() { let item = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) if let button = item.button { let image = NSImage(systemSymbolName: "arrow.triangle.2.circlepath", accessibilityDescription: "Konverter") image?.isTemplate = true button.image = image button.setAccessibilityLabel("Konverter") } let menu = NSMenu() menu.delegate = self item.menu = menu statusItem = item rebuild(menu) } func menuNeedsUpdate(_ menu: NSMenu) { rebuild(menu) } private func rebuild(_ menu: NSMenu) { menu.removeAllItems() let enabled = Settings.shared.enabled let toggle = NSMenuItem( title: enabled ? "Konverter Active" : "Konverter Paused", action: #selector(toggleEnabled), keyEquivalent: "" ) toggle.target = self toggle.state = enabled ? .on : .off menu.addItem(toggle) menu.addItem(.separator()) let convert = NSMenuItem(title: "Konvert Files…", action: #selector(convertFiles), keyEquivalent: "o") convert.target = self menu.addItem(convert) let jobs = NSMenuItem(title: "Show Jobs", action: #selector(showJobs), keyEquivalent: "j") jobs.target = self menu.addItem(jobs) menu.addItem(.separator()) let settings = NSMenuItem(title: "Settings…", action: #selector(showSettings), keyEquivalent: ",") settings.target = self menu.addItem(settings) let about = NSMenuItem(title: "About Konverter", action: #selector(showAbout), keyEquivalent: "") about.target = self menu.addItem(about) menu.addItem(.separator()) let quit = NSMenuItem(title: "Quit Konverter", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q") quit.target = NSApp menu.addItem(quit) } @objc private func toggleEnabled() { Settings.shared.enabled.toggle() if !Settings.shared.enabled { WheelController.shared.cancel() } if let menu = statusItem?.menu { rebuild(menu) } } @objc private func convertFiles() { let panel = NSOpenPanel() panel.canChooseFiles = true panel.canChooseDirectories = true panel.allowsMultipleSelection = true panel.prompt = "Choose" panel.message = "Pick files to convert, then choose an output format" NSApp.activate(ignoringOtherApps: true) guard panel.runModal() == .OK, !panel.urls.isEmpty else { return } // Let the panel close before the menu opens over it. DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { QuickMenu.show(urls: panel.urls, at: NSEvent.mouseLocation) } } @objc private func showJobs() { JobStore.shared.panelVisible = true JobPanelController.shared.show() } @objc private func showSettings() { PreferencesWindowController.shared.show() } @objc private func showAbout() { NSApp.activate(ignoringOtherApps: true) NSApp.orderFrontStandardAboutPanel(options: [ .applicationName: "Konverter", .applicationVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0", .credits: NSAttributedString( string: "Drag a file in Finder, then hold a key.\nShift converts · Command shows tools · Control shows file actions.\nEverything runs on this Mac.", attributes: [.font: NSFont.systemFont(ofSize: 11)] ) ]) } }