Skip to content

Commit

Permalink
feat: icon is tinted red while listening for a key sequence
Browse files Browse the repository at this point in the history
fix: when Apptivator is disabled all sequences are unregistered
  • Loading branch information
acheronfail committed Jan 23, 2019
1 parent 01b486b commit aae7baf
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 9 deletions.
4 changes: 4 additions & 0 deletions Apptivator.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
15FC8CC8204E2E2C000B5E1E /* APState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15FC8CC7204E2E2C000B5E1E /* APState.swift */; };
B3B4C2C11E25894B009F8E4E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3B4C2C01E25894B009F8E4E /* AppDelegate.swift */; };
B3B4C2C31E25894B009F8E4E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B3B4C2C21E25894B009F8E4E /* Assets.xcassets */; };
BA54C46621F87F480084BB36 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA54C46521F87F480084BB36 /* Extensions.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -91,6 +92,7 @@
B3B4C2C21E25894B009F8E4E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
B3B4C2C51E25894B009F8E4E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/APPopoverViewController.xib; sourceTree = "<group>"; };
B3B4C2C71E25894B009F8E4E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BA54C46521F87F480084BB36 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -188,6 +190,7 @@
B3B4C2C01E25894B009F8E4E /* AppDelegate.swift */,
1537F5E0204C8D860056EE50 /* APAppEntry.swift */,
15FC8CC7204E2E2C000B5E1E /* APState.swift */,
BA54C46521F87F480084BB36 /* Extensions.swift */,
15492102207B53AE00E45BBC /* Util.swift */,
15673D6F20B6140E00542276 /* README.md */,
155D2C02204F61220087478B /* Credits.rtfd */,
Expand Down Expand Up @@ -336,6 +339,7 @@
15F39F3C204CB72D00847CD5 /* APPopoverViewController.swift in Sources */,
15492103207B53AE00E45BBC /* Util.swift in Sources */,
B3B4C2C11E25894B009F8E4E /* AppDelegate.swift in Sources */,
BA54C46621F87F480084BB36 /* Extensions.swift in Sources */,
1561AED2207615AC00C69338 /* UIOverrides.swift in Sources */,
15FC8CC8204E2E2C000B5E1E /* APState.swift in Sources */,
1537F5E1204C8D860056EE50 /* APAppEntry.swift in Sources */,
Expand Down
29 changes: 22 additions & 7 deletions Apptivator/APState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import CleanroomLogger
// Only one instance of this class should be used at a time.
static var shared = APState(atPath: defaultConfigurationPath())

// A reference to the Application's AppDelegate (used to set the menu bar icon).
let appDelegate = NSApp.delegate as! AppDelegate

// Location of our serialised application state.
let savePath: URL

Expand Down Expand Up @@ -41,7 +44,14 @@ import CleanroomLogger
private var _isEnabled = true
var isEnabled: Bool {
get { return _isEnabled && !currentlyRecording }
set { _isEnabled = newValue }
set {
_isEnabled = newValue
if newValue {
registerShortcutsIfEnabled()
} else {
unregisterShortcuts()
}
}
}

// The list of application -> shortcut mappings. Made private because whenever we need to
Expand Down Expand Up @@ -81,7 +91,7 @@ import CleanroomLogger
// Add an entry.
func addEntry(_ entry: APAppEntry) {
entries.append(entry)
registerShortcuts()
registerShortcutsIfEnabled()
}

// In order for an entry to be cleaned up by ARC, there must be no more references to it.
Expand All @@ -94,7 +104,7 @@ import CleanroomLogger
}
shortcutView.shortcutValue = nil
})
registerShortcuts()
registerShortcutsIfEnabled()
}

func sortEntries(comparator: (APAppEntry, APAppEntry) -> Bool) {
Expand All @@ -108,8 +118,10 @@ import CleanroomLogger

// This resets the shortcut state to its initial setting. This should be called whenever a
// an ApplicationEntry updates its sequence.
func registerShortcuts() {
registerShortcuts(atIndex: 0, last: nil)
func registerShortcutsIfEnabled() {
if isEnabled {
registerShortcuts(atIndex: 0, last: nil)
}
}

// Unregister all previously registered application shortcuts. We can't just use
Expand Down Expand Up @@ -164,8 +176,10 @@ import CleanroomLogger
// If this is a sequential shortcut, then start a timer to reset back to the initial state
// if no other shortcuts were hit.
if index > 0 {
appDelegate.setMenuBarIcon(ICON_REC)
let interval = TimeInterval(defaults.float(forKey: "sequentialShortcutDelay"))
sequenceTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: false) { _ in
self.appDelegate.setMenuBarIcon(ICON_ON)
self.sequenceTimer = nil
self.registerShortcuts(atIndex: 0, last: nil)
Log.debug?.message("Resetting shortcut state.")
Expand All @@ -183,6 +197,7 @@ import CleanroomLogger
if i == entry.sequence.count {
entry.apptivate()
registerShortcuts(atIndex: 0, last: nil)
appDelegate.setMenuBarIcon(ICON_ON)
Log.debug?.message("Apptivating \(entry.name).")
} else {
// Advance shortcut state with last shortcut and the number of shortcuts hit.
Expand Down Expand Up @@ -237,7 +252,7 @@ import CleanroomLogger
}
}

registerShortcuts()
registerShortcutsIfEnabled()
}

func loadFromString(_ jsonString: String) throws {
Expand All @@ -249,7 +264,7 @@ import CleanroomLogger
case "darkModeEnabled":
if !mojaveDarkModeSupported() { darkModeEnabled = value.bool ?? false }
case "appIsEnabled":
_isEnabled = value.bool ?? true
isEnabled = value.bool ?? true
case "entries":
entries = APAppEntry.deserialiseList(fromJSON: value)
default:
Expand Down
7 changes: 6 additions & 1 deletion Apptivator/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ let ENABLED_INDICATOR_ON = "\(APP_NAME): on"
let ENABLED_INDICATOR_OFF = "\(APP_NAME): off"
let ICON_ON = setupMenuBarIcon(NSImage(named: NSImage.Name(stringLiteral: "icon-on")))
let ICON_OFF = setupMenuBarIcon(NSImage(named: NSImage.Name(stringLiteral: "icon-off")))
let ICON_REC = setupMenuBarIcon(NSImage(named: NSImage.Name(stringLiteral: "icon-on")))?.tinted(with: NSColor.red)

@NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var popover: NSPopover!
Expand Down Expand Up @@ -75,9 +76,13 @@ let ICON_OFF = setupMenuBarIcon(NSImage(named: NSImage.Name(stringLiteral: "icon
APState.shared.saveToDisk()
}

func setMenuBarIcon(_ image: NSImage?) {
menuBarItem?.image = image
}

func enable(_ flag: Bool) {
APState.shared.isEnabled = flag
menuBarItem?.image = flag ? ICON_ON : ICON_OFF
setMenuBarIcon(flag ? ICON_ON : ICON_OFF)
enabledIndicator.title = flag ? ENABLED_INDICATOR_ON : ENABLED_INDICATOR_OFF
}

Expand Down
19 changes: 19 additions & 0 deletions Apptivator/Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Extensions.swift
// Apptivator
//

// http://homecoffeecode.com/nsimage-tinted-as-easily-as-a-uiimage/
extension NSImage {
func tinted(with tintColor: NSColor) -> NSImage {
guard let cgImage = self.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return self }

return NSImage(size: size, flipped: false) { bounds in
guard let context = NSGraphicsContext.current?.cgContext else { return false }
tintColor.set()
context.clip(to: bounds, mask: cgImage)
context.fill(bounds)
return true
}
}
}
2 changes: 1 addition & 1 deletion Apptivator/UI/APPopoverViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class APPopoverViewController: NSViewController {
self.tableView.selectRowIndexes([], byExtendingSelection: false)
}
sequenceEditor!.beforeRemoved = {
APState.shared.registerShortcuts()
APState.shared.registerShortcutsIfEnabled()
self.addButton.isEnabled = true
self.removeButton.isEnabled = self.tableView.selectedRowIndexes.count > 0
self.reloadView()
Expand Down

0 comments on commit aae7baf

Please sign in to comment.