-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathNESMenuButtonView.swift
More file actions
94 lines (76 loc) · 3.16 KB
/
NESMenuButtonView.swift
File metadata and controls
94 lines (76 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import SwiftUI
import Cocoa
import Logger
struct NESMenuButtonView: NSViewRepresentable {
let menuController: NESMenuController
var fontSize: CGFloat
var buttonImage: NSImage? {
NSImage(
systemSymbolName: "arrow.right.to.line",
accessibilityDescription: "Next Edit Suggestion Menu"
)
}
var buttonFont: NSFont {
NSFont.systemFont(ofSize: fontSize, weight: .medium)
}
func makeNSView(context: Context) -> NSButton {
let button = NSButton(frame: .zero)
button.title = ""
button.bezelStyle = .shadowlessSquare
button.isBordered = false
button.imageScaling = .scaleProportionallyDown
button.contentTintColor = .white
button.imagePosition = .imageOnly
button.focusRingType = .none
button.target = context.coordinator
button.action = #selector(Coordinator.buttonClicked)
button.font = buttonFont
let baseConfig = NSImage.SymbolConfiguration(pointSize: fontSize, weight: .regular)
let colorConfig = NSImage.SymbolConfiguration(hierarchicalColor: NSColor.white)
button.image = buttonImage?
.withSymbolConfiguration(baseConfig)?
.withSymbolConfiguration(colorConfig)
context.coordinator.setupMenu(for: button)
return button
}
func updateNSView(_ nsView: NSButton, context: Context) {
nsView.font = buttonFont
if let image = buttonImage {
let base = NSImage.SymbolConfiguration(pointSize: fontSize, weight: .regular)
let tinted = NSImage.SymbolConfiguration(hierarchicalColor: .white)
nsView.image = image.withSymbolConfiguration(base)?.withSymbolConfiguration(tinted)
}
}
func makeCoordinator() -> Coordinator {
Coordinator(menuController: menuController)
}
class Coordinator: NSObject {
let menuController: NESMenuController
private weak var button: NSButton?
init(menuController: NESMenuController) {
self.menuController = menuController
super.init()
}
func setupMenu(for button: NSButton) {
self.button = button
}
@objc func buttonClicked(_ sender: NSButton) {
let menu = menuController.createMenu()
showMenu(menu, for: sender)
}
private func showMenu(_ menu: NSMenu, for button: NSButton) {
// Ensure the button is still in a window before showing the menu
guard let window = button.window else {
return
}
// Ensure menu is properly positioned and shown
let location = NSPoint(x: 0, y: button.bounds.height + 5)
let originalLevel = window.level
window.level = NSWindow.Level(rawValue: NSWindow.Level.popUpMenu.rawValue + 1)
defer { window.level = originalLevel }
menu.popUp(positioning: nil, at: location, in: button)
}
@objc func menuDidClose(_ menu: NSMenu) { }
@objc func menuWillOpen(_ menu: NSMenu) { }
}
}