From f63c21e11cfad4fb8408effae2efb07164ad5760 Mon Sep 17 00:00:00 2001 From: Tomáš Znamenáček Date: Fri, 9 Jan 2015 10:51:08 +0100 Subject: Expanded demo functionality (preparing for 2.0.0, see #54). Mostly back to the previous version with enable/disable checkboxes & one settable and one hard-coded shortcut. I have tried to come up with a nicer pattern to watch the enabled/disabled checkboxes, but without external dependencies like Facebook’s KVOController I didn’t come up with anything better than plain old KVO. --- Demo/AppDelegate.m | 89 +++++++++++++++++++++++++++++++++++++++++++++++------- Demo/MainMenu.xib | 58 ++++++++++++++++++++++++++++------- 2 files changed, 125 insertions(+), 22 deletions(-) (limited to 'Demo') diff --git a/Demo/AppDelegate.m b/Demo/AppDelegate.m index 5c1c3f7..fd8d307 100644 --- a/Demo/AppDelegate.m +++ b/Demo/AppDelegate.m @@ -1,7 +1,14 @@ #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 (nonatomic, assign) IBOutlet MASShortcutView *shortcutView; +@property(strong) IBOutlet MASShortcutView *customShortcutView; +@property(strong) IBOutlet NSTextField *feedbackTextField; @end @implementation AppDelegate @@ -10,20 +17,80 @@ { [super awakeFromNib]; - static NSString *const ShortcutKey = @"customShortcut"; + 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. - [_shortcutView setAssociatedUserDefaultsKey:ShortcutKey]; - - // Play a ping sound when the shortcut stored in user defaults is pressed. - // Note that when the shortcut stored in user defaults changes, you don’t have - // to update anything: the old shortcut will automatically stop working and - // the sound will play after pressing the new one. - [[MASShortcutBinder sharedBinder] bindShortcutWithDefaultsKey:ShortcutKey toAction:^{ - [[NSSound soundNamed:@"Ping"] play]; - }]; + [_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 diff --git a/Demo/MainMenu.xib b/Demo/MainMenu.xib index 488dea2..3d99587 100644 --- a/Demo/MainMenu.xib +++ b/Demo/MainMenu.xib @@ -649,39 +649,75 @@ - + - + - + - - + + - - - + + + + + + + + + + + + + - After recording a shortcut, press it to play a sound. Notice that the shortcut is played even when the demo app is not in the foreground. + + + + + + + + - + - + + -- cgit v1.2.3