--------- Co-authored-by: intelligence <intelligence@debian.local> Co-authored-by: jourintown <jourintown@proton.me> Reviewed-on: #2
60 lines
1.5 KiB
Swift
60 lines
1.5 KiB
Swift
import AppKit
|
|
import SwiftUI
|
|
|
|
struct HotkeyRecorder: NSViewRepresentable {
|
|
@Binding var shortcut: HotkeyShortcut
|
|
|
|
func makeNSView(context: Context) -> HotkeyCaptureView {
|
|
let view = HotkeyCaptureView()
|
|
view.onShortcut = { shortcut = $0 }
|
|
view.stringValue = shortcut.displayName
|
|
return view
|
|
}
|
|
|
|
func updateNSView(_ view: HotkeyCaptureView, context: Context) {
|
|
view.onShortcut = { shortcut = $0 }
|
|
if view.window?.firstResponder !== view {
|
|
view.stringValue = shortcut.displayName
|
|
}
|
|
}
|
|
}
|
|
|
|
final class HotkeyCaptureView: NSTextField {
|
|
var onShortcut: ((HotkeyShortcut) -> Void)?
|
|
|
|
override init(frame frameRect: NSRect) {
|
|
super.init(frame: frameRect)
|
|
isEditable = false
|
|
isSelectable = false
|
|
isBezeled = true
|
|
bezelStyle = .roundedBezel
|
|
alignment = .center
|
|
font = .monospacedSystemFont(ofSize: NSFont.systemFontSize, weight: .medium)
|
|
toolTip = "Click, then press a shortcut"
|
|
}
|
|
|
|
required init?(coder: NSCoder) { nil }
|
|
|
|
override var acceptsFirstResponder: Bool { true }
|
|
|
|
override func mouseDown(with event: NSEvent) {
|
|
window?.makeFirstResponder(self)
|
|
stringValue = "Type shortcut"
|
|
}
|
|
|
|
override func keyDown(with event: NSEvent) {
|
|
guard let shortcut = HotkeyShortcut(event: event) else {
|
|
NSSound.beep()
|
|
return
|
|
}
|
|
stringValue = shortcut.displayName
|
|
onShortcut?(shortcut)
|
|
window?.makeFirstResponder(nil)
|
|
}
|
|
|
|
override func resignFirstResponder() -> Bool {
|
|
needsDisplay = true
|
|
return super.resignFirstResponder()
|
|
}
|
|
}
|