Skip to content

Commit

Permalink
🎨 refactor StatusItem into separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardodino committed Mar 30, 2022
1 parent 6c4d75d commit 21b383a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 25 deletions.
4 changes: 4 additions & 0 deletions BeezyLight.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

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

/* Begin PBXFileReference section */
962377FD27F4ECD8002D718F /* StatusItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItem.swift; sourceTree = "<group>"; };
96A53DDC27C572B9002DA809 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
96B8901127F4E78D00C39B4A /* AboutWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindow.swift; sourceTree = "<group>"; };
96C2A1DE27C5632D00768B18 /* BeezyLight.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BeezyLight.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -60,6 +62,7 @@
isa = PBXGroup;
children = (
96C2A1E127C5632D00768B18 /* AppDelegate.swift */,
962377FD27F4ECD8002D718F /* StatusItem.swift */,
96B8901127F4E78D00C39B4A /* AboutWindow.swift */,
96C2A1F327C567C300768B18 /* BlinkStick.swift */,
96D5B44727C57CE300C4FFCA /* Debouncer.swift */,
Expand Down Expand Up @@ -149,6 +152,7 @@
files = (
96C2A1F527C567C300768B18 /* BlinkStick.swift in Sources */,
96C2A1E227C5632D00768B18 /* AppDelegate.swift in Sources */,
962377FE27F4ECD8002D718F /* StatusItem.swift in Sources */,
96D5B44827C57CE300C4FFCA /* Debouncer.swift in Sources */,
96B8901227F4E78D00C39B4A /* AboutWindow.swift in Sources */,
);
Expand Down
30 changes: 5 additions & 25 deletions BeezyLight/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import Cocoa
import SimplyCoreAudio

enum Icon {
static let idle = NSImage(systemSymbolName: "mic", accessibilityDescription: nil)
static let busy = NSImage(systemSymbolName: "mic.fill", accessibilityDescription: nil)
static let error = NSImage(systemSymbolName: "mic.slash", accessibilityDescription: nil)
}

enum State: Equatable {
case idle
case busy
Expand All @@ -18,25 +12,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
private let notificationCenter = NotificationCenter.default
private var simplyCA: SimplyCoreAudio?
private var blinkStick: BlinkStick?
private var statusItem: NSStatusItem?
private var statusItem: StatusItem?
private var state: State = .error

@objc func quit() {
NSApp.terminate(self)
}

@objc func about() {
AboutWindow.show()
}

func applicationDidFinishLaunching(_: Notification) {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)

let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") ?? ""
let menu = NSMenu()
menu.addItem(NSMenuItem(title: "About \(appName)", action: #selector(AppDelegate.about), keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Quit", action: #selector(AppDelegate.quit), keyEquivalent: "q"))
statusItem?.menu = menu
statusItem = StatusItem()
render()

simplyCA = SimplyCoreAudio()
Expand All @@ -53,13 +33,13 @@ extension AppDelegate {
private func render() {
switch state {
case .idle:
statusItem?.button?.image = Icon.idle
statusItem?.setIcon(.idle)
blinkStick?.setColor(r: 0, g: 0, b: 0)
case .busy:
statusItem?.button?.image = Icon.busy
statusItem?.setIcon(.busy)
blinkStick?.setColor(r: 255, g: 0, b: 0)
case .error:
statusItem?.button?.image = Icon.error
statusItem?.setIcon(.error)
blinkStick?.setColor(r: 255, g: 0, b: 255)
}
}
Expand Down
47 changes: 47 additions & 0 deletions BeezyLight/StatusItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Cocoa

fileprivate func createMenu(_ itemCreators: [(_ menuItem: NSMenuItem) -> Void]) -> NSMenu {
let menu = NSMenu()
itemCreators.forEach { createItem in
let item = NSMenuItem()
createItem(item)
menu.addItem(item)
}
return menu
}

class StatusItem {
enum StateIcon {
case idle
case busy
case error

var image: NSImage? {
switch self {
case .idle: return NSImage(systemSymbolName: "mic", accessibilityDescription: nil)
case .busy: return NSImage(systemSymbolName: "mic.fill", accessibilityDescription: nil)
case .error: return NSImage(systemSymbolName: "mic.slash", accessibilityDescription: nil)
}
}
}

private let instance = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)

init() {
instance.menu = createMenu([{
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") ?? ""
$0.title = "About \(appName)"
$0.action = #selector(AboutWindow.show)
$0.target = AboutWindow.shared
}, {
$0.title = "Quit"
$0.keyEquivalent = "q"
$0.action = #selector(NSApp.terminate)
$0.target = NSApp
}])
}

func setIcon(_ icon: StateIcon) {
instance.button?.image = icon.image
}
}

0 comments on commit 21b383a

Please sign in to comment.