blob: fd8d307a14dc3167d0963b3117c8bbe44db882b5 (
plain)
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
95
96
97
98
99
100
101
102
103
|
#import "AppDelegate.h"
static NSString *const MASCustomShortcutKey = @"customShortcut";
static NSString *const MASCustomShortcutEnabledKey = @"customShortcutEnabled";
static NSString *const MASHardcodedShortcutEnabledKey = @"hardcodedShortcutEnabled";
static void *MASObservingContext = &MASObservingContext;
@interface AppDelegate ()
@property(strong) IBOutlet MASShortcutView *customShortcutView;
@property(strong) IBOutlet NSTextField *feedbackTextField;
@end
@implementation AppDelegate
- (void) awakeFromNib
{
[super awakeFromNib];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Register default values to be used for the first app start
[defaults registerDefaults:@{
MASHardcodedShortcutEnabledKey : @YES,
MASCustomShortcutEnabledKey : @YES,
}];
// Bind the shortcut recorder view’s value to user defaults.
// Run “defaults read com.shpakovski.mac.Demo” to see what’s stored
// in user defaults.
[_customShortcutView setAssociatedUserDefaultsKey:MASCustomShortcutKey];
// Enable or disable the recorder view according to the first checkbox state
[_customShortcutView bind:@"enabled" toObject:defaults
withKeyPath:MASCustomShortcutEnabledKey options:nil];
// Watch user defaults for changes in the checkbox states
[defaults addObserver:self forKeyPath:MASCustomShortcutEnabledKey
options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew
context:MASObservingContext];
[defaults addObserver:self forKeyPath:MASHardcodedShortcutEnabledKey
options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew
context:MASObservingContext];
}
- (void) playShortcutFeedback
{
[[NSSound soundNamed:@"Ping"] play];
[_feedbackTextField setStringValue:@"Shortcut pressed!"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_feedbackTextField setStringValue:@""];
});
}
// Handle changes in user defaults. We have to check keyPath here to see which of the
// two checkboxes was changed. This is not very elegant, in practice you could use something
// like https://github.com/facebook/KVOController with a nicer API.
- (void) observeValueForKeyPath: (NSString*) keyPath ofObject: (id) object change: (NSDictionary*) change context: (void*) context
{
if (context != MASObservingContext) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
BOOL newValue = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
if ([keyPath isEqualToString:MASCustomShortcutEnabledKey]) {
[self setCustomShortcutEnabled:newValue];
} else if ([keyPath isEqualToString:MASHardcodedShortcutEnabledKey]) {
[self setHardcodedShortcutEnabled:newValue];
}
}
- (void) setCustomShortcutEnabled: (BOOL) enabled
{
if (enabled) {
[[MASShortcutBinder sharedBinder] bindShortcutWithDefaultsKey:MASCustomShortcutKey toAction:^{
[self playShortcutFeedback];
}];
} else {
[[MASShortcutBinder sharedBinder] breakBindingWithDefaultsKey:MASCustomShortcutKey];
}
}
- (void) setHardcodedShortcutEnabled: (BOOL) enabled
{
MASShortcut *shortcut = [MASShortcut shortcutWithKeyCode:kVK_ANSI_Keypad2 modifierFlags:NSCommandKeyMask];
if (enabled) {
[[MASShortcutMonitor sharedMonitor] registerShortcut:shortcut withAction:^{
[self playShortcutFeedback];
}];
} else {
[[MASShortcutMonitor sharedMonitor] unregisterShortcut:shortcut];
}
}
#pragma mark NSApplicationDelegate
- (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication*) sender
{
return YES;
}
@end
|