hudini/Sources/HUDini/HUDPanel.swift
johnfrum1234 cee343dd96 Initial commit: HUDini — classic volume HUD for macOS
Menu bar utility that shows a centered HUD overlay with volume bars
when system volume changes. CoreAudio monitoring, auto-fade, works
on all spaces and fullscreen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:28:41 +02:00

68 lines
2.1 KiB
Swift

import Cocoa
import SwiftUI
class HUDPanel {
private var panel: NSPanel?
private var hideTimer: Timer?
private let hudSize = NSSize(width: 200, height: 200)
func show(volume: Float, isMuted: Bool) {
hideTimer?.invalidate()
if panel == nil {
createPanel()
}
guard let panel = panel else { return }
// Update content
let hostingView = NSHostingView(rootView: HUDView(volume: volume, isMuted: isMuted))
hostingView.frame = NSRect(origin: .zero, size: hudSize)
panel.contentView = hostingView
// Center on main screen
if let screen = NSScreen.main {
let screenFrame = screen.visibleFrame
let x = screenFrame.midX - hudSize.width / 2
let y = screenFrame.midY - hudSize.height / 2
panel.setFrameOrigin(NSPoint(x: x, y: y))
}
// Show
panel.alphaValue = 1.0
panel.orderFrontRegardless()
// Auto-hide after 1.5s
hideTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] _ in
self?.fadeOut()
}
}
private func createPanel() {
let panel = NSPanel(
contentRect: NSRect(origin: .zero, size: hudSize),
styleMask: [.borderless, .nonactivatingPanel],
backing: .buffered,
defer: false
)
panel.level = .floating
panel.isOpaque = false
panel.backgroundColor = .clear
panel.hasShadow = true
panel.hidesOnDeactivate = false
panel.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary, .ignoresCycle]
panel.isMovableByWindowBackground = false
panel.ignoresMouseEvents = true
self.panel = panel
}
private func fadeOut() {
guard let panel = panel else { return }
NSAnimationContext.runAnimationGroup({ context in
context.duration = 0.4
panel.animator().alphaValue = 0.0
}, completionHandler: { [weak self] in
self?.panel?.orderOut(nil)
})
}
}