69 lines
2.1 KiB
Swift
69 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)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|