Skip to content

Commit

Permalink
Merge pull request #110 from Kentzo/develop
Browse files Browse the repository at this point in the history
3.1
  • Loading branch information
Kentzo committed Oct 18, 2019
2 parents 061f5ca + 2772797 commit 8e2b5a5
Show file tree
Hide file tree
Showing 47 changed files with 1,126 additions and 371 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ profile
*.moved-aside
timeline.xctimeline

## Ignore incredibly annoying .DS_Store files
# Carthage
ShortcutRecorder.framework.zip
Carthage/

# Ignore incredibly annoying .DS_Store files
.DS_Store
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ osx_image: xcode10.3
before_install:
- brew update
- brew outdated carthage || brew upgrade carthage
- gem install cocoapods -v '>= 1.8'
- pod --version
script:
- xcodebuild -verbose -project ShortcutRecorder.xcodeproj -scheme ShortcutRecorder.framework -destination 'platform=macOS' build test
- sed "s# s\.source.*# s\.source = \{ \:git => '$(pwd)' \}#" ShortcutRecorder.podspec > /tmp/ShortcutRecorder.podspec
Expand Down
17 changes: 17 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
3.1 (2019-10-19)
---

Improvements:

- Added support for key up events in Shortcut Monitors
- Style can now customize no-value labels and tooltips
- Reviewed and fixed translations to match modern Apple vocabulary
- New and shorter label for the control when there is no value
- New tooltip for the clean button
- New tooltip for the cancel button when there no value: "use old shortcut" does not make sense if there is no old shortcut

Fixes:

- Fix various errors and edge cases in Shortcut Monitors
- Fix undefined behavior warning due to a missing `nullable` in the `-[SRRecorderControl propagateValue:forKey:] definition
- Fix incorrect intrinsic width of the control (was visible only after certain style customizations)
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ let targetAction = ShortcutAction(shortcut: shortcut, target: nil, action: #sele
⌥⇧⌘A and ⌃⇧⌘B will be globally overridden until you terminate the Playground
*/
let globalMonitor = GlobalShortcutMonitor.shared
globalMonitor.addShortcutAction(action)
globalMonitor.addShortcutAction(autoupdatingAction)
globalMonitor.addAction(action, forKeyEvent: .down)
globalMonitor.addAction(autoupdatingAction, forKeyEvent: .down)
/*:
`LocalShortcutMonitor` organizes actions into a collection that can later by used for event dispatch e.g.
in the subclasses of `NSResponder` such as `NSView` and `NSViewController`. It's a convenient alternative
Expand Down
18 changes: 15 additions & 3 deletions Inspector/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import ShortcutRecorder

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, ShortcutActionTarget {
var bindingsInspector: NSWindowController!
var layoutInspector: NSWindowController!

let purrSound = NSSound(named: "Purr")!

override func awakeFromNib() {
Expand Down Expand Up @@ -46,13 +49,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, ShortcutActionTarget {

func showWindows() {
let s = NSStoryboard(name: "Main", bundle: nil)
let layoutInspector = s.instantiateController(withIdentifier: "LayoutInspector") as! NSWindowController
let bindingsInspector = s.instantiateController(withIdentifier: "BindingsInspector") as! NSWindowController

layoutInspector = s.instantiateController(withIdentifier: "LayoutInspector") as? NSWindowController
bindingsInspector = s.instantiateController(withIdentifier: "BindingsInspector") as? NSWindowController

let layoutWindow = layoutInspector.window!
let bindingsWindow = bindingsInspector.window!

// The Window submenu alraedy lists all available windows.
// The Window submenu already lists all available windows.
layoutWindow.isExcludedFromWindowsMenu = true
bindingsWindow.isExcludedFromWindowsMenu = true

Expand All @@ -74,6 +78,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, ShortcutActionTarget {
bindingsWindow.setFrameAutosaveName("SRBindingsInspector")
}

@IBAction func showBindingsInspector(_ sender: Any) {
bindingsInspector.showWindow(sender)
}

@IBAction func showLayoutInspector(_ sender: Any) {
layoutInspector.showWindow(sender)
}

func applicationDidFinishLaunching(_ notification: Notification) {
showWindows()
}
Expand Down
60 changes: 30 additions & 30 deletions Inspector/LayoutInspectorController.xib

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Inspector/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15400" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15400"/>
</dependencies>
<scenes>
<!--Window Controller-->
Expand Down Expand Up @@ -133,14 +133,14 @@
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="6Of-6M-fTi">
<items>
<menuItem title="Bindings" keyEquivalent="1" id="2qY-rK-6sD">
<menuItem title="Bindings" tag="1" keyEquivalent="1" id="2qY-rK-6sD">
<connections>
<segue destination="Cfg-6J-0Ka" kind="show" id="9al-81-MHy"/>
<action selector="showBindingsInspector:" target="Wsw-a9-b4o" id="bkv-oW-7Re"/>
</connections>
</menuItem>
<menuItem title="Layout" keyEquivalent="2" id="Ojw-ek-jdx" userLabel="Layout">
<menuItem title="Layout" tag="2" keyEquivalent="2" id="Ojw-ek-jdx" userLabel="Layout">
<connections>
<segue destination="WGQ-I6-9sj" kind="show" id="Hdq-El-fs4"/>
<action selector="showLayoutInspector:" target="Wsw-a9-b4o" id="DAQ-o0-IaF"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="6Pk-IW-yqa"/>
Expand Down
4 changes: 2 additions & 2 deletions Library/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<string>3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>3.0</string>
<string>3.1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019 ShortcutRecorder attributors</string>
</dict>
Expand Down
2 changes: 1 addition & 1 deletion Library/SRCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ NSBundle * SRBundle(void);
Convenience method to get localized string from the framework bundle.
*/
NS_SWIFT_NAME(shortcutRecorderLocalizedString(forKey:))
NSString * SRLoc(NSString * _Nullable aKey);
NSString * SRLoc(NSString * _Nullable aKey) __attribute__((annotate("returns_localized_nsstring")));


/*!
Expand Down
30 changes: 3 additions & 27 deletions Library/SRCommon.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,40 +42,16 @@
static NSBundle *Bundle = nil;
dispatch_once(&onceToken, ^{
Bundle = [NSBundle bundleWithIdentifier:@"com.kulakov.ShortcutRecorder"];

if (!Bundle)
{
// Could be a CocoaPods framework with embedded resources bundle.
// Look up "use_frameworks!" and "resources_bundle" in CocoaPods documentation.
Bundle = [NSBundle bundleWithIdentifier:@"org.cocoapods.ShortcutRecorder"];

if (!Bundle)
{
Class c = NSClassFromString(@"SRRecorderControl");

if (c)
{
Bundle = [NSBundle bundleForClass:c];
}
}

if (Bundle)
{
Bundle = [NSBundle bundleWithPath:[Bundle pathForResource:@"ShortcutRecorder" ofType:@"bundle"]];
}
}
});

if (!Bundle)
if (Bundle)
return Bundle;
else
{
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:@"Unable to find bundle with resources."
userInfo:nil];
}
else
{
return Bundle;
}
}


Expand Down
4 changes: 2 additions & 2 deletions Library/SRRecorderControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ IB_DESIGNABLE
@seealso http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/
*/
- (void)propagateValue:(id)aValue forBinding:(NSString *)aBinding;
- (void)propagateValue:(nullable id)aValue forBinding:(NSString *)aBinding;

#pragma mark Drawing

Expand All @@ -293,7 +293,7 @@ IB_DESIGNABLE
/*!
Returns label to be displayed by the receiver.
*/
@property (readonly) NSString *drawingLabel;
@property (readonly) NSString *drawingLabel __attribute__((annotate("returns_localized_nsstring")));

/*!
Attirbutes for the drawingLabel.
Expand Down
31 changes: 22 additions & 9 deletions Library/SRRecorderControl.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ @implementation SRRecorderControl

_SRRecorderControlButtonTag _mouseTrackingButtonTag;
NSToolTipTag _cancelButtonToolTipTag;
NSToolTipTag _clearButtonToolTipTag;

SRShortcut *_objectValue;

Expand Down Expand Up @@ -76,6 +77,7 @@ - (void)initInternalState
_requiredModifierFlags = 0;
_mouseTrackingButtonTag = _SRRecorderControlInvalidButtonTag;
_cancelButtonToolTipTag = NSIntegerMax;
_clearButtonToolTipTag = NSIntegerMax;
_pausesGlobalShortcutMonitorWhileRecording = YES;

_notifyStyle = [NSInvocation invocationWithMethodSignature:[SRRecorderControlStyle instanceMethodSignatureForSelector:@selector(recorderControlAppearanceDidChange:)]];
Expand All @@ -93,8 +95,6 @@ - (void)initInternalState
forOrientation:NSLayoutConstraintOrientationHorizontal];
[self setContentCompressionResistancePriority:NSLayoutPriorityRequired
forOrientation:NSLayoutConstraintOrientationVertical];

self.toolTip = SRLoc(@"Click to record shortcut");
}

- (void)dealloc
Expand Down Expand Up @@ -305,6 +305,11 @@ - (void)_setStyle:(SRRecorderControlStyle *)newStyle
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:&_SRStyleAppearanceObservingContext];
}

if (self.isRecording)
self.toolTip = _SRIfRespondsGet(self.style, recordingTooltip, SRLoc(@"Type shortcut"));
else
self.toolTip = _SRIfRespondsGet(self.style, normalTooltip, SRLoc(@"Click to record shortcut"));
}

- (NSBezierPath *)focusRingShape
Expand Down Expand Up @@ -395,14 +400,14 @@ - (NSString *)drawingLabel
label = self.stringValue;

if (!label.length)
label = SRLoc(@"Type shortcut");
label = _SRIfRespondsGet(self.style, noValueRecordingLabel, SRLoc(@"Type shortcut"));
}
else
{
label = self.stringValue;

if (!label.length)
label = SRLoc(@"Click to record shortcut");
label = _SRIfRespondsGet(self.style, noValueNormalLabel, SRLoc(@"Record Shortcut"));
}

return label;
Expand Down Expand Up @@ -481,7 +486,7 @@ - (BOOL)beginRecording

[self updateActiveConstraints];
[self updateTrackingAreas];
self.toolTip = SRLoc(@"Type shortcut");
self.toolTip = _SRIfRespondsGet(self.style, recordingTooltip, SRLoc(@"Type shortcut"));

if (self.pausesGlobalShortcutMonitorWhileRecording)
[SRGlobalShortcutMonitor.sharedMonitor pause];
Expand Down Expand Up @@ -554,7 +559,7 @@ - (void)endRecordingWithObjectValue:(SRShortcut *)anObjectValue

[self updateActiveConstraints];
[self updateTrackingAreas];
self.toolTip = SRLoc(@"Click to record shortcut");
self.toolTip = _SRIfRespondsGet(self.style, normalTooltip, SRLoc(@"Click to record shortcut"));
self.needsDisplay = YES;

if (self.pausesGlobalShortcutMonitorWhileRecording)
Expand Down Expand Up @@ -1015,7 +1020,9 @@ - (void)prepareForInterfaceBuilder
- (NSString *)view:(NSView *)aView stringForToolTip:(NSToolTipTag)aTag point:(NSPoint)aPoint userData:(void *)aData
{
if (aTag == _cancelButtonToolTipTag)
return SRLoc(@"Use old shortcut");
return _SRIfRespondsGet(self.style, cancelButtonTooltip, _objectValue != nil ? SRLoc(@"Use old shortcut") : SRLoc(@"Cancel recording"));
else if (aTag == _clearButtonToolTipTag)
return _SRIfRespondsGet(self.style, clearButtonTooltip, SRLoc(@"Delete current shortcut"));
else
return [super view:aView stringForToolTip:aTag point:aPoint userData:aData];
}
Expand Down Expand Up @@ -1149,6 +1156,7 @@ - (NSUserInterfaceLayoutDirection)userInterfaceLayoutDirection
if (currentValue)
return currentValue.integerValue;

// If there is no style yet, return macOS's default value.
if (!_isLazilyInitializingStyle && [self.style respondsToSelector:@selector(preferredComponents)])
{
__auto_type layoutDirection = self.style.preferredComponents.layoutDirection;
Expand Down Expand Up @@ -1276,6 +1284,12 @@ - (void)updateTrackingAreas
_cancelButtonToolTipTag = NSIntegerMax;
}

if (_clearButtonToolTipTag != NSIntegerMax)
{
[self removeToolTip:_clearButtonToolTipTag];
_clearButtonToolTipTag = NSIntegerMax;
}

if (self.isRecording)
{
if (!NSIsEmptyRect(cancelButtonFrame))
Expand All @@ -1297,6 +1311,7 @@ - (void)updateTrackingAreas
owner:self
userInfo:nil];
[self addTrackingArea:_clearButtonTrackingArea];
_clearButtonToolTipTag = [self addToolTipRect:_clearButtonTrackingArea.rect owner:self userData:NULL];
}
}

Expand All @@ -1317,8 +1332,6 @@ - (void)prepareForReuse

- (void)viewWillMoveToWindow:(NSWindow *)aWindow
{
// We want control to end recording whenever window resigns first responder status.
// Otherwise we could end up with "dangling" recording.
if (self.window)
{
[NSNotificationCenter.defaultCenter removeObserver:self
Expand Down
16 changes: 16 additions & 0 deletions Library/SRRecorderControlStyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ extern NSAttributedStringKey const SRMinimalDrawableWidthAttributeName;

/*!
Components of the style that describe visual appearance.
The control may be in one of the following states:
- Normal: the control is enabled but unpressed
- Pressed: the control is enabled and pressed
- Recording: the control is enabled and recording
- Disabled: the control is disabled
*/
NS_SWIFT_NAME(RecorderControlStyle.Components)
@interface SRRecorderControlStyleComponents: NSObject <NSCopying>
Expand Down Expand Up @@ -302,6 +308,16 @@ NS_SWIFT_NAME(RecorderControlStyling)
@property (readonly) NSImage *clearButton;
@property (readonly) NSImage *clearButtonPressed;

@property (readonly) NSString *noValueNormalLabel;
@property (readonly) NSString *noValueDisableLabel;
@property (readonly) NSString *noValueRecordingLabel;

@property (readonly) NSString *normalTooltip;
@property (readonly) NSString *disabledTooltip;
@property (readonly) NSString *recordingTooltip;
@property (readonly) NSString *cancelButtonTooltip;
@property (readonly) NSString *clearButtonTooltip;

/*!
Corner radius of the focus ring.
Expand Down
Loading

0 comments on commit 8e2b5a5

Please sign in to comment.