diff options
Diffstat (limited to 'Demo')
| -rw-r--r-- | Demo/AppDelegate.m | 89 | ||||
| -rw-r--r-- | Demo/MainMenu.xib | 58 | 
2 files changed, 125 insertions, 22 deletions
| 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 @@          </menu>          <window title="Demo" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="DemoWindow" animationBehavior="default" id="371">              <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> -            <rect key="contentRect" x="335" y="390" width="290" height="171"/> +            <rect key="contentRect" x="335" y="390" width="385" height="129"/>              <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>              <view key="contentView" id="372"> -                <rect key="frame" x="0.0" y="0.0" width="290" height="171"/> +                <rect key="frame" x="0.0" y="0.0" width="385" height="129"/>                  <autoresizingMask key="autoresizingMask"/>                  <subviews>                      <customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="536" customClass="MASShortcutView"> -                        <rect key="frame" x="20" y="102" width="250" height="19"/> +                        <rect key="frame" x="142" y="90" width="158" height="19"/>                      </customView>                      <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PG0-jh-Onh"> -                        <rect key="frame" x="18" y="134" width="119" height="17"/> -                        <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Record a shortcut:" id="85u-1A-n7H"> +                        <rect key="frame" x="18" y="92" width="111" height="17"/> +                        <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Custom shortcut:" id="85u-1A-n7H">                              <font key="font" metaFont="system"/>                              <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>                              <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>                          </textFieldCell>                      </textField> -                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ieo-bz-mir"> -                        <rect key="frame" x="18" y="23" width="254" height="68"/> -                        <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" id="WDe-Rt-e8p"> +                    <button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zCi-ki-Uuh"> +                        <rect key="frame" x="140" y="63" width="169" height="18"/> +                        <buttonCell key="cell" type="check" title="Enable custom shortcut" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Y47-p3-sDa"> +                            <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> +                            <font key="font" metaFont="system"/> +                        </buttonCell> +                        <connections> +                            <binding destination="rCO-Ve-DT5" name="value" keyPath="values.customShortcutEnabled" id="VjS-3V-VdA"/> +                        </connections> +                    </button> +                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KnS-ut-phz"> +                        <rect key="frame" x="18" y="65" width="111" height="17"/> +                        <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Options:" id="cUE-gA-heG"> +                            <font key="font" metaFont="system"/> +                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> +                            <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> +                        </textFieldCell> +                    </textField> +                    <button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F4r-KM-wn9"> +                        <rect key="frame" x="140" y="43" width="227" height="18"/> +                        <buttonCell key="cell" type="check" title="Enable hard-coded shortcut (⌘2)" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="7gv-jN-44g"> +                            <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> +                            <font key="font" metaFont="system"/> +                        </buttonCell> +                        <connections> +                            <binding destination="rCO-Ve-DT5" name="value" keyPath="values.hardcodedShortcutEnabled" id="dlZ-si-HeN"/> +                        </connections> +                    </button> +                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9fB-XS-8pK"> +                        <rect key="frame" x="18" y="20" width="111" height="17"/> +                        <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Feedback:" id="Zbz-mV-NDc">                              <font key="font" metaFont="system"/> -                            <string key="title">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.</string>                              <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>                              <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>                          </textFieldCell>                      </textField> +                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Aso-dH-W8I"> +                        <rect key="frame" x="140" y="20" width="211" height="17"/> +                        <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" placeholderString="Press a shortcut to see feedback" id="Ckx-v7-e6x"> +                            <font key="font" metaFont="system"/> +                            <color key="textColor" red="1" green="0.14901961389999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/> +                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> +                        </textFieldCell> +                    </textField>                  </subviews>              </view> -            <point key="canvasLocation" x="297" y="335.5"/> +            <point key="canvasLocation" x="348.5" y="367.5"/>          </window>          <customObject id="494" customClass="AppDelegate">              <connections> -                <outlet property="shortcutView" destination="536" id="548"/> +                <outlet property="customShortcutView" destination="536" id="aO6-hh-1vm"/> +                <outlet property="feedbackTextField" destination="Aso-dH-W8I" id="hk8-xL-ieC"/>                  <outlet property="window" destination="371" id="532"/>              </connections>          </customObject> | 
