Skip to content

Commit 21b383a

Browse files
committed
🎨 refactor StatusItem into separate class
1 parent 6c4d75d commit 21b383a

File tree

3 files changed

+56
-25
lines changed

3 files changed

+56
-25
lines changed

BeezyLight.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
962377FE27F4ECD8002D718F /* StatusItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962377FD27F4ECD8002D718F /* StatusItem.swift */; };
1011
96B8901227F4E78D00C39B4A /* AboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B8901127F4E78D00C39B4A /* AboutWindow.swift */; };
1112
96C2A1E227C5632D00768B18 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C2A1E127C5632D00768B18 /* AppDelegate.swift */; };
1213
96C2A1E627C5632E00768B18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96C2A1E527C5632E00768B18 /* Assets.xcassets */; };
@@ -17,6 +18,7 @@
1718
/* End PBXBuildFile section */
1819

1920
/* Begin PBXFileReference section */
21+
962377FD27F4ECD8002D718F /* StatusItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItem.swift; sourceTree = "<group>"; };
2022
96A53DDC27C572B9002DA809 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
2123
96B8901127F4E78D00C39B4A /* AboutWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindow.swift; sourceTree = "<group>"; };
2224
96C2A1DE27C5632D00768B18 /* BeezyLight.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BeezyLight.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -60,6 +62,7 @@
6062
isa = PBXGroup;
6163
children = (
6264
96C2A1E127C5632D00768B18 /* AppDelegate.swift */,
65+
962377FD27F4ECD8002D718F /* StatusItem.swift */,
6366
96B8901127F4E78D00C39B4A /* AboutWindow.swift */,
6467
96C2A1F327C567C300768B18 /* BlinkStick.swift */,
6568
96D5B44727C57CE300C4FFCA /* Debouncer.swift */,
@@ -149,6 +152,7 @@
149152
files = (
150153
96C2A1F527C567C300768B18 /* BlinkStick.swift in Sources */,
151154
96C2A1E227C5632D00768B18 /* AppDelegate.swift in Sources */,
155+
962377FE27F4ECD8002D718F /* StatusItem.swift in Sources */,
152156
96D5B44827C57CE300C4FFCA /* Debouncer.swift in Sources */,
153157
96B8901227F4E78D00C39B4A /* AboutWindow.swift in Sources */,
154158
);

BeezyLight/AppDelegate.swift

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import Cocoa
22
import SimplyCoreAudio
33

4-
enum Icon {
5-
static let idle = NSImage(systemSymbolName: "mic", accessibilityDescription: nil)
6-
static let busy = NSImage(systemSymbolName: "mic.fill", accessibilityDescription: nil)
7-
static let error = NSImage(systemSymbolName: "mic.slash", accessibilityDescription: nil)
8-
}
9-
104
enum State: Equatable {
115
case idle
126
case busy
@@ -18,25 +12,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
1812
private let notificationCenter = NotificationCenter.default
1913
private var simplyCA: SimplyCoreAudio?
2014
private var blinkStick: BlinkStick?
21-
private var statusItem: NSStatusItem?
15+
private var statusItem: StatusItem?
2216
private var state: State = .error
2317

24-
@objc func quit() {
25-
NSApp.terminate(self)
26-
}
27-
28-
@objc func about() {
29-
AboutWindow.show()
30-
}
31-
3218
func applicationDidFinishLaunching(_: Notification) {
33-
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
34-
35-
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") ?? ""
36-
let menu = NSMenu()
37-
menu.addItem(NSMenuItem(title: "About \(appName)", action: #selector(AppDelegate.about), keyEquivalent: ""))
38-
menu.addItem(NSMenuItem(title: "Quit", action: #selector(AppDelegate.quit), keyEquivalent: "q"))
39-
statusItem?.menu = menu
19+
statusItem = StatusItem()
4020
render()
4121

4222
simplyCA = SimplyCoreAudio()
@@ -53,13 +33,13 @@ extension AppDelegate {
5333
private func render() {
5434
switch state {
5535
case .idle:
56-
statusItem?.button?.image = Icon.idle
36+
statusItem?.setIcon(.idle)
5737
blinkStick?.setColor(r: 0, g: 0, b: 0)
5838
case .busy:
59-
statusItem?.button?.image = Icon.busy
39+
statusItem?.setIcon(.busy)
6040
blinkStick?.setColor(r: 255, g: 0, b: 0)
6141
case .error:
62-
statusItem?.button?.image = Icon.error
42+
statusItem?.setIcon(.error)
6343
blinkStick?.setColor(r: 255, g: 0, b: 255)
6444
}
6545
}

BeezyLight/StatusItem.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import Cocoa
2+
3+
fileprivate func createMenu(_ itemCreators: [(_ menuItem: NSMenuItem) -> Void]) -> NSMenu {
4+
let menu = NSMenu()
5+
itemCreators.forEach { createItem in
6+
let item = NSMenuItem()
7+
createItem(item)
8+
menu.addItem(item)
9+
}
10+
return menu
11+
}
12+
13+
class StatusItem {
14+
enum StateIcon {
15+
case idle
16+
case busy
17+
case error
18+
19+
var image: NSImage? {
20+
switch self {
21+
case .idle: return NSImage(systemSymbolName: "mic", accessibilityDescription: nil)
22+
case .busy: return NSImage(systemSymbolName: "mic.fill", accessibilityDescription: nil)
23+
case .error: return NSImage(systemSymbolName: "mic.slash", accessibilityDescription: nil)
24+
}
25+
}
26+
}
27+
28+
private let instance = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
29+
30+
init() {
31+
instance.menu = createMenu([{
32+
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") ?? ""
33+
$0.title = "About \(appName)"
34+
$0.action = #selector(AboutWindow.show)
35+
$0.target = AboutWindow.shared
36+
}, {
37+
$0.title = "Quit"
38+
$0.keyEquivalent = "q"
39+
$0.action = #selector(NSApp.terminate)
40+
$0.target = NSApp
41+
}])
42+
}
43+
44+
func setIcon(_ icon: StateIcon) {
45+
instance.button?.image = icon.image
46+
}
47+
}

0 commit comments

Comments
 (0)