aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Shpakovski2012-09-19 13:16:23 +0300
committerVadim Shpakovski2012-09-19 13:16:23 +0300
commitcbc369c71a79f613ffbc3dbad91086f047d3c221 (patch)
treeb02e8d839ba1183aa6d06657e77f5a3e829e033b
parent4099b62587959708bd02d1c49ec1c8fa39448cf4 (diff)
downloadMASShortcut-cbc369c71a79f613ffbc3dbad91086f047d3c221.tar.bz2
Removes ARC to support 32-bit.
-rw-r--r--MASShortcut+Monitoring.m7
-rw-r--r--MASShortcut+UserDefaults.h8
-rw-r--r--MASShortcut+UserDefaults.m87
-rw-r--r--MASShortcut.m10
-rw-r--r--MASShortcutView+UserDefaults.h7
-rw-r--r--MASShortcutView+UserDefaults.m128
-rw-r--r--MASShortcutView.h17
-rw-r--r--MASShortcutView.m428
8 files changed, 9 insertions, 683 deletions
diff --git a/MASShortcut+Monitoring.m b/MASShortcut+Monitoring.m
index 1460f6b..51787c2 100644
--- a/MASShortcut+Monitoring.m
+++ b/MASShortcut+Monitoring.m
@@ -25,7 +25,7 @@ void InstallHotkeyWithShortcut(MASShortcut *shortcut, UInt32 *outCarbonHotKeyID,
+ (id)addGlobalHotkeyMonitorWithShortcut:(MASShortcut *)shortcut handler:(void (^)())handler
{
NSString *monitor = [NSString stringWithFormat:@"%p: %@", shortcut, shortcut.description];
- MASShortcutHotKey *hotKey = [[MASShortcutHotKey alloc] initWithShortcut:shortcut handler:handler];
+ MASShortcutHotKey *hotKey = [[[MASShortcutHotKey alloc] initWithShortcut:shortcut handler:handler] autorelease];
[MASRegisteredHotKeys() setObject:hotKey forKey:monitor];
return monitor;
}
@@ -57,7 +57,7 @@ void InstallHotkeyWithShortcut(MASShortcut *shortcut, UInt32 *outCarbonHotKeyID,
{
self = [super init];
if (self) {
- _shortcut = shortcut;
+ _shortcut = [shortcut retain];
_handler = [handler copy];
InstallHotkeyWithShortcut(shortcut, &_carbonHotKeyID, &_carbonHotKey);
}
@@ -67,6 +67,7 @@ void InstallHotkeyWithShortcut(MASShortcut *shortcut, UInt32 *outCarbonHotKeyID,
- (void)dealloc
{
[self uninstallExisitingHotKey];
+ [super dealloc];
}
- (void)uninstallExisitingHotKey
@@ -86,7 +87,7 @@ NSMutableDictionary *MASRegisteredHotKeys()
static NSMutableDictionary *shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
- shared = [NSMutableDictionary dictionary];
+ shared = [[NSMutableDictionary alloc] init];
});
return shared;
}
diff --git a/MASShortcut+UserDefaults.h b/MASShortcut+UserDefaults.h
deleted file mode 100644
index 0c7f14e..0000000
--- a/MASShortcut+UserDefaults.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#import "MASShortcut.h"
-
-@interface MASShortcut (UserDefaults)
-
-+ (void)registerGlobalShortcutWithUserDefaultsKey:(NSString *)userDefaultsKey handler:(void (^)())handler;
-+ (void)unregisterGlobalShortcutWithUserDefaultsKey:(NSString *)userDefaultsKey;
-
-@end
diff --git a/MASShortcut+UserDefaults.m b/MASShortcut+UserDefaults.m
deleted file mode 100644
index 3bdbab9..0000000
--- a/MASShortcut+UserDefaults.m
+++ /dev/null
@@ -1,87 +0,0 @@
-#import "MASShortcut+UserDefaults.h"
-#import "MASShortcut+Monitoring.h"
-
-@interface MASShortcutUserDefaultsHotKey : NSObject
-
-@property (nonatomic, readonly) NSString *userDefaultsKey;
-@property (nonatomic, copy) void (^handler)();
-@property (nonatomic, weak) id monitor;
-
-- (id)initWithUserDefaultsKey:(NSString *)userDefaultsKey handler:(void (^)())handler;
-
-@end
-
-#pragma mark -
-
-@implementation MASShortcut (UserDefaults)
-
-+ (NSMutableDictionary *)registeredUserDefaultsHotKeys
-{
- static NSMutableDictionary *shared = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- shared = [NSMutableDictionary dictionary];
- });
- return shared;
-}
-
-+ (void)registerGlobalShortcutWithUserDefaultsKey:(NSString *)userDefaultsKey handler:(void (^)())handler;
-{
- MASShortcutUserDefaultsHotKey *hotKey = [[MASShortcutUserDefaultsHotKey alloc] initWithUserDefaultsKey:userDefaultsKey handler:handler];
- [[self registeredUserDefaultsHotKeys] setObject:hotKey forKey:userDefaultsKey];
-}
-
-+ (void)unregisterGlobalShortcutWithUserDefaultsKey:(NSString *)userDefaultsKey
-{
- NSMutableDictionary *registeredHotKeys = [self registeredUserDefaultsHotKeys];
- [registeredHotKeys removeObjectForKey:userDefaultsKey];
-}
-
-@end
-
-#pragma mark -
-
-@implementation MASShortcutUserDefaultsHotKey
-
-@synthesize monitor = _monitor;
-@synthesize handler = _handler;
-@synthesize userDefaultsKey = _userDefaultsKey;
-
-#pragma mark -
-
-- (id)initWithUserDefaultsKey:(NSString *)userDefaultsKey handler:(void (^)())handler
-{
- self = [super init];
- if (self) {
- _userDefaultsKey = userDefaultsKey.copy;
- _handler = [handler copy];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDefaultsDidChange:)
- name:NSUserDefaultsDidChangeNotification object:[NSUserDefaults standardUserDefaults]];
- [self installHotKeyFromUserDefaults];
- }
- return self;
-}
-
-- (void)dealloc
-{
- [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:[NSUserDefaults standardUserDefaults]];
- [MASShortcut removeGlobalHotkeyMonitor:self.monitor];
-}
-
-#pragma mark -
-
-- (void)userDefaultsDidChange:(NSNotification *)note
-{
- [MASShortcut removeGlobalHotkeyMonitor:self.monitor];
- [self installHotKeyFromUserDefaults];
-}
-
-- (void)installHotKeyFromUserDefaults
-{
- NSData *data = [[NSUserDefaults standardUserDefaults] dataForKey:_userDefaultsKey];
- MASShortcut *shortcut = [MASShortcut shortcutWithData:data];
- if (shortcut == nil) return;
- self.monitor = [MASShortcut addGlobalHotkeyMonitorWithShortcut:shortcut handler:self.handler];
-}
-
-@end
diff --git a/MASShortcut.m b/MASShortcut.m
index ca5a1ae..5bb039d 100644
--- a/MASShortcut.m
+++ b/MASShortcut.m
@@ -42,12 +42,12 @@ NSString *const kMASShortcutModifierFlags = @"ModifierFlags";
+ (MASShortcut *)shortcutWithKeyCode:(NSUInteger)code modifierFlags:(NSUInteger)flags
{
- return [[self alloc] initWithKeyCode:code modifierFlags:flags];
+ return [[[self alloc] initWithKeyCode:code modifierFlags:flags] autorelease];
}
+ (MASShortcut *)shortcutWithEvent:(NSEvent *)event
{
- return [[self alloc] initWithKeyCode:event.keyCode modifierFlags:event.modifierFlags];
+ return [[[self alloc] initWithKeyCode:event.keyCode modifierFlags:event.modifierFlags] autorelease];
}
+ (MASShortcut *)shortcutWithData:(NSData *)data
@@ -195,7 +195,7 @@ NSString *const kMASShortcutModifierFlags = @"ModifierFlags";
if (keystroke.length) {
static NSMutableCharacterSet *validChars = nil;
if (validChars == nil) {
- validChars = [[NSMutableCharacterSet alloc] init];
+ validChars = [[[NSMutableCharacterSet alloc] init] autorelease];
[validChars formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]];
[validChars formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]];
[validChars formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]];
@@ -286,8 +286,8 @@ NSString *const kMASShortcutModifierFlags = @"ModifierFlags";
CFNumberRef code = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyCode);
CFNumberRef flags = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyModifiers);
- if (([(__bridge NSNumber *)code unsignedIntegerValue] == self.keyCode) &&
- ([(__bridge NSNumber *)flags unsignedIntegerValue] == self.carbonFlags)) {
+ if (([(NSNumber *)code unsignedIntegerValue] == self.keyCode) &&
+ ([(NSNumber *)flags unsignedIntegerValue] == self.carbonFlags)) {
if (outError) {
NSString *description = NSLocalizedString(@"This combination cannot be used used because it is already used by a system-wide "
diff --git a/MASShortcutView+UserDefaults.h b/MASShortcutView+UserDefaults.h
deleted file mode 100644
index 05d3c5b..0000000
--- a/MASShortcutView+UserDefaults.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#import "MASShortcutView.h"
-
-@interface MASShortcutView (UserDefaults)
-
-@property (nonatomic, copy) NSString *associatedUserDefaultsKey;
-
-@end
diff --git a/MASShortcutView+UserDefaults.m b/MASShortcutView+UserDefaults.m
deleted file mode 100644
index 42a2379..0000000
--- a/MASShortcutView+UserDefaults.m
+++ /dev/null
@@ -1,128 +0,0 @@
-#import "MASShortcutView+UserDefaults.h"
-#import "MASShortcut.h"
-#import <objc/runtime.h>
-
-@interface MASShortcutDefaultsObserver : NSObject
-
-@property (nonatomic, readonly) NSString *userDefaultsKey;
-@property (nonatomic, readonly, weak) MASShortcutView *shortcutView;
-
-- (id)initWithShortcutView:(MASShortcutView *)shortcutView userDefaultsKey:(NSString *)userDefaultsKey;
-
-@end
-
-#pragma mark -
-
-@implementation MASShortcutView (UserDefaults)
-
-void *kDefaultsObserver = &kDefaultsObserver;
-
-- (NSString *)associatedUserDefaultsKey
-{
- MASShortcutDefaultsObserver *defaultsObserver = objc_getAssociatedObject(self, kDefaultsObserver);
- return defaultsObserver.userDefaultsKey;
-}
-
-- (void)setAssociatedUserDefaultsKey:(NSString *)associatedUserDefaultsKey
-{
- // First, stop observing previous shortcut view
- objc_setAssociatedObject(self, kDefaultsObserver, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-
- // Next, start observing current shortcut view
- MASShortcutDefaultsObserver *defaultsObserver = [[MASShortcutDefaultsObserver alloc] initWithShortcutView:self userDefaultsKey:associatedUserDefaultsKey];
- objc_setAssociatedObject(self, kDefaultsObserver, defaultsObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-}
-
-@end
-
-#pragma mark -
-
-@implementation MASShortcutDefaultsObserver {
- MASShortcut *_originalShortcut;
- BOOL _internalPreferenceChange;
- BOOL _internalShortcutChange;
-}
-
-@synthesize userDefaultsKey = _userDefaultsKey;
-@synthesize shortcutView = _shortcutView;
-
-#pragma mark -
-
-- (id)initWithShortcutView:(MASShortcutView *)shortcutView userDefaultsKey:(NSString *)userDefaultsKey
-{
- self = [super init];
- if (self) {
- _originalShortcut = shortcutView.shortcutValue;
- _shortcutView = shortcutView;
- _userDefaultsKey = userDefaultsKey.copy;
- [self startObservingShortcutView];
- }
- return self;
-}
-
-- (void)dealloc
-{
- // __weak _shortcutView is not yet deallocated because it refers MASShortcutDefaultsObserver
- [self stopObservingShortcutView];
-}
-
-#pragma mark -
-
-void *kShortcutValueObserver = &kShortcutValueObserver;
-
-- (void)startObservingShortcutView
-{
- // Read initial shortcut value from user preferences
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSData *data = [defaults dataForKey:_userDefaultsKey];
- _shortcutView.shortcutValue = [MASShortcut shortcutWithData:data];
-
- // Observe user preferences to update shortcut value when it changed
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDefaultsDidChange:) name:NSUserDefaultsDidChangeNotification object:defaults];
-
- // Observe the keyboard shortcut that user inputs by hand
- [_shortcutView addObserver:self forKeyPath:@"shortcutValue" options:0 context:kShortcutValueObserver];
-}
-
-- (void)userDefaultsDidChange:(NSNotification *)note
-{
- // Ignore notifications posted from -[self observeValueForKeyPath:]
- if (_internalPreferenceChange) return;
-
- _internalShortcutChange = YES;
- NSData *data = [note.object dataForKey:_userDefaultsKey];
- _shortcutView.shortcutValue = [MASShortcut shortcutWithData:data];
- _internalShortcutChange = NO;
-}
-
-- (void)stopObservingShortcutView
-{
- // Stop observing keyboard hotkeys entered by user in the shortcut view
- [_shortcutView removeObserver:self forKeyPath:@"shortcutValue" context:kShortcutValueObserver];
-
- // Stop observing user preferences
- [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:[NSUserDefaults standardUserDefaults]];
-
- // Restore original hotkey in the shortcut view
- _shortcutView.shortcutValue = _originalShortcut;
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
-{
- if (context == kShortcutValueObserver) {
- if (_internalShortcutChange) return;
- MASShortcut *shortcut = [object valueForKey:keyPath];
- _internalPreferenceChange = YES;
-
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults setObject:(shortcut.data ?: [NSKeyedArchiver archivedDataWithRootObject:nil]) forKey:_userDefaultsKey];
- [defaults synchronize];
-
- _internalPreferenceChange = NO;
- }
- else {
- [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
- }
-}
-
-@end
diff --git a/MASShortcutView.h b/MASShortcutView.h
deleted file mode 100644
index 5259123..0000000
--- a/MASShortcutView.h
+++ /dev/null
@@ -1,17 +0,0 @@
-@class MASShortcut;
-
-typedef enum {
- MASShortcutViewAppearanceDefault = 0, // Height = 19 px
- MASShortcutViewAppearanceTexturedRect, // Height = 25 px
- MASShortcutViewAppearanceRounded // Height = 43 px
-} MASShortcutViewAppearance;
-
-@interface MASShortcutView : NSView
-
-@property (nonatomic, strong) MASShortcut *shortcutValue;
-@property (nonatomic, getter = isRecording) BOOL recording;
-@property (nonatomic, getter = isEnabled) BOOL enabled;
-@property (nonatomic, copy) void (^shortcutValueChange)(MASShortcutView *sender);
-@property (nonatomic) MASShortcutViewAppearance appearance;
-
-@end
diff --git a/MASShortcutView.m b/MASShortcutView.m
deleted file mode 100644
index 27e6ae7..0000000
--- a/MASShortcutView.m
+++ /dev/null
@@ -1,428 +0,0 @@
-#import "MASShortcutView.h"
-#import "MASShortcut.h"
-
-#define HINT_BUTTON_WIDTH 23.0
-#define BUTTON_FONT_SIZE 11.0
-#define SEGMENT_CHROME_WIDTH 6.0
-
-#pragma mark -
-
-@interface MASShortcutView () // Private accessors
-
-@property (nonatomic, getter = isHinting) BOOL hinting;
-@property (nonatomic, copy) NSString *shortcutPlaceholder;
-
-@end
-
-#pragma mark -
-
-@implementation MASShortcutView {
- NSButtonCell *_shortcutCell;
- NSInteger _shortcutToolTipTag;
- NSInteger _hintToolTipTag;
- NSTrackingArea *_hintArea;
-}
-
-@synthesize enabled = _enabled;
-@synthesize hinting = _hinting;
-@synthesize shortcutValue = _shortcutValue;
-@synthesize shortcutPlaceholder = _shortcutPlaceholder;
-@synthesize shortcutValueChange = _shortcutValueChange;
-@synthesize recording = _recording;
-
-#pragma mark -
-
-- (id)initWithFrame:(CGRect)frameRect
-{
- self = [super initWithFrame:frameRect];
- if (self) {
- _shortcutCell = [[NSButtonCell alloc] init];
- _shortcutCell.buttonType = NSPushOnPushOffButton;
- _shortcutCell.font = [[NSFontManager sharedFontManager] convertFont:_shortcutCell.font toSize:BUTTON_FONT_SIZE];
- _enabled = YES;
- [self resetShortcutCellStyle];
- }
- return self;
-}
-
-- (void)dealloc
-{
- [self activateEventMonitoring:NO];
- [self activateResignObserver:NO];
-}
-
-#pragma mark - Public accessors
-
-- (void)setEnabled:(BOOL)flag
-{
- if (_enabled != flag) {
- _enabled = flag;
- [self updateTrackingAreas];
- self.recording = NO;
- [self setNeedsDisplay:YES];
- }
-}
-
-- (void)setAppearance:(MASShortcutViewAppearance)appearance
-{
- if (_appearance != appearance) {
- _appearance = appearance;
- [self resetShortcutCellStyle];
- [self setNeedsDisplay:YES];
- }
-}
-
-- (void)resetShortcutCellStyle
-{
- switch (_appearance) {
- case MASShortcutViewAppearanceDefault: {
- _shortcutCell.bezelStyle = NSRoundRectBezelStyle;
- break;
- }
- case MASShortcutViewAppearanceTexturedRect: {
- _shortcutCell.bezelStyle = NSTexturedRoundedBezelStyle;
- break;
- }
- case MASShortcutViewAppearanceRounded: {
- _shortcutCell.bezelStyle = NSRoundedBezelStyle;
- break;
- }
- }
-}
-
-- (void)setRecording:(BOOL)flag
-{
- // Only one recorder can be active at the moment
- static MASShortcutView *currentRecorder = nil;
- if (flag && (currentRecorder != self)) {
- currentRecorder.recording = NO;
- currentRecorder = flag ? self : nil;
- }
-
- // Only enabled view supports recording
- if (flag && !self.enabled) return;
-
- if (_recording != flag) {
- _recording = flag;
- self.shortcutPlaceholder = nil;
- [self resetToolTips];
- [self activateEventMonitoring:_recording];
- [self activateResignObserver:_recording];
- [self setNeedsDisplay:YES];
- }
-}
-
-- (void)setShortcutValue:(MASShortcut *)shortcutValue
-{
- _shortcutValue = shortcutValue;
- [self resetToolTips];
- [self setNeedsDisplay:YES];
-
- if (self.shortcutValueChange) {
- self.shortcutValueChange(self);
- }
-}
-
-- (void)setShortcutPlaceholder:(NSString *)shortcutPlaceholder
-{
- _shortcutPlaceholder = shortcutPlaceholder.copy;
- [self setNeedsDisplay:YES];
-}
-
-#pragma mark - Drawing
-
-- (BOOL)isFlipped
-{
- return YES;
-}
-
-- (void)drawInRect:(CGRect)frame withTitle:(NSString *)title alignment:(NSTextAlignment)alignment state:(NSInteger)state
-{
- _shortcutCell.title = title;
- _shortcutCell.alignment = alignment;
- _shortcutCell.state = state;
- _shortcutCell.enabled = self.enabled;
-
- switch (_appearance) {
- case MASShortcutViewAppearanceDefault: {
- [_shortcutCell drawWithFrame:frame inView:self];
- break;
- }
- case MASShortcutViewAppearanceTexturedRect: {
- [_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self];
- break;
- }
- case MASShortcutViewAppearanceRounded: {
- [_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self];
- break;
- }
- }
-}
-
-- (void)drawRect:(CGRect)dirtyRect
-{
- if (self.shortcutValue) {
- [self drawInRect:self.bounds withTitle:MASShortcutChar(self.recording ? kMASShortcutGlyphEscape : kMASShortcutGlyphDeleteLeft)
- alignment:NSRightTextAlignment state:NSOffState];
-
- CGRect shortcutRect;
- [self getShortcutRect:&shortcutRect hintRect:NULL];
- NSString *title = (self.recording
- ? (_hinting
- ? NSLocalizedString(@"Use Old Shortuct", @"Cancel action button for non-empty shortcut in recording state")
- : (self.shortcutPlaceholder.length > 0
- ? self.shortcutPlaceholder
- : NSLocalizedString(@"Type New Shortcut", @"Non-empty shortcut button in recording state")))
- : _shortcutValue ? _shortcutValue.description : @"");
- [self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:self.isRecording ? NSOnState : NSOffState];
- }
- else {
- if (self.recording)
- {
- [self drawInRect:self.bounds withTitle:MASShortcutChar(kMASShortcutGlyphEscape) alignment:NSRightTextAlignment state:NSOffState];
-
- CGRect shortcutRect;
- [self getShortcutRect:&shortcutRect hintRect:NULL];
- NSString *title = (_hinting
- ? NSLocalizedString(@"Cancel", @"Cancel action button in recording state")
- : (self.shortcutPlaceholder.length > 0
- ? self.shortcutPlaceholder
- : NSLocalizedString(@"Type Shortcut", @"Empty shortcut button in recording state")));
- [self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:NSOnState];
- }
- else
- {
- [self drawInRect:self.bounds withTitle:NSLocalizedString(@"Record Shortcut", @"Empty shortcut button in normal state")
- alignment:NSCenterTextAlignment state:NSOffState];
- }
- }
-}
-
-#pragma mark - Mouse handling
-
-- (void)getShortcutRect:(CGRect *)shortcutRectRef hintRect:(CGRect *)hintRectRef
-{
- CGRect shortcutRect, hintRect;
- CGFloat hintButtonWidth = HINT_BUTTON_WIDTH;
- switch (self.appearance) {
- case MASShortcutViewAppearanceTexturedRect: hintButtonWidth += 2.0; break;
- case MASShortcutViewAppearanceRounded: hintButtonWidth += 3.0; break;
- default: break;
- }
- CGRectDivide(self.bounds, &hintRect, &shortcutRect, hintButtonWidth, CGRectMaxXEdge);
- if (shortcutRectRef) *shortcutRectRef = shortcutRect;
- if (hintRectRef) *hintRectRef = hintRect;
-}
-
-- (BOOL)locationInShortcutRect:(CGPoint)location
-{
- CGRect shortcutRect;
- [self getShortcutRect:&shortcutRect hintRect:NULL];
- return CGRectContainsPoint(shortcutRect, [self convertPoint:location fromView:nil]);
-}
-
-- (BOOL)locationInHintRect:(CGPoint)location
-{
- CGRect hintRect;
- [self getShortcutRect:NULL hintRect:&hintRect];
- return CGRectContainsPoint(hintRect, [self convertPoint:location fromView:nil]);
-}
-
-- (void)mouseDown:(NSEvent *)event
-{
- if (self.enabled) {
- if (self.shortcutValue) {
- if (self.recording) {
- if ([self locationInHintRect:event.locationInWindow]) {
- self.recording = NO;
- }
- }
- else {
- if ([self locationInShortcutRect:event.locationInWindow]) {
- self.recording = YES;
- }
- else {
- self.shortcutValue = nil;
- }
- }
- }
- else {
- if (self.recording) {
- if ([self locationInHintRect:event.locationInWindow]) {
- self.recording = NO;
- }
- }
- else {
- self.recording = YES;
- }
- }
- }
- else {
- [super mouseDown:event];
- }
-}
-
-#pragma mark - Handling mouse over
-
-- (void)updateTrackingAreas
-{
- [super updateTrackingAreas];
-
- if (_hintArea) {
- [self removeTrackingArea:_hintArea];
- _hintArea = nil;
- }
-
- // Forbid hinting if view is disabled
- if (!self.enabled) return;
-
- CGRect hintRect;
- [self getShortcutRect:NULL hintRect:&hintRect];
- NSTrackingAreaOptions options = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingAssumeInside);
- _hintArea = [[NSTrackingArea alloc] initWithRect:hintRect options:options owner:self userInfo:nil];
- [self addTrackingArea:_hintArea];
-}
-
-- (void)setHinting:(BOOL)flag
-{
- if (_hinting != flag) {
- _hinting = flag;
- [self setNeedsDisplay:YES];
- }
-}
-
-- (void)mouseEntered:(NSEvent *)event
-{
- self.hinting = YES;
-}
-
-- (void)mouseExited:(NSEvent *)event
-{
- self.hinting = NO;
-}
-
-void *kUserDataShortcut = &kUserDataShortcut;
-void *kUserDataHint = &kUserDataHint;
-
-- (void)resetToolTips
-{
- if (_shortcutToolTipTag) {
- [self removeToolTip:_shortcutToolTipTag], _shortcutToolTipTag = 0;
- }
- if (_hintToolTipTag) {
- [self removeToolTip:_hintToolTipTag], _hintToolTipTag = 0;
- }
-
- if ((self.shortcutValue == nil) || self.recording || !self.enabled) return;
-
- CGRect shortcutRect, hintRect;
- [self getShortcutRect:&shortcutRect hintRect:&hintRect];
- _shortcutToolTipTag = [self addToolTipRect:shortcutRect owner:self userData:kUserDataShortcut];
- _hintToolTipTag = [self addToolTipRect:hintRect owner:self userData:kUserDataHint];
-}
-
-- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(CGPoint)point userData:(void *)data
-{
- if (data == kUserDataShortcut) {
- return NSLocalizedString(@"Click to record new shortcut", @"Tooltip for non-empty shortcut button");
- }
- else if (data == kUserDataHint) {
- return NSLocalizedString(@"Delete shortcut", @"Tooltip for hint button near the non-empty shortcut");
- }
- return nil;
-}
-
-#pragma mark - Event monitoring
-
-- (void)activateEventMonitoring:(BOOL)shouldActivate
-{
- static BOOL isActive = NO;
- if (isActive == shouldActivate) return;
- isActive = shouldActivate;
-
- static id eventMonitor = nil;
- if (shouldActivate) {
- __weak MASShortcutView *weakSelf = self;
- NSEventMask eventMask = (NSKeyDownMask | NSFlagsChangedMask);
- eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) {
-
- MASShortcut *shortcut = [MASShortcut shortcutWithEvent:event];
- if ((shortcut.keyCode == kVK_Delete) || (shortcut.keyCode == kVK_ForwardDelete)) {
- // Delete shortcut
- weakSelf.shortcutValue = nil;
- weakSelf.recording = NO;
- event = nil;
- }
- else if (shortcut.keyCode == kVK_Escape) {
- // Cancel recording
- weakSelf.recording = NO;
- event = nil;
- }
- else if (shortcut.shouldBypass) {
- // Command + W, Command + Q, ESC should deactivate recorder
- weakSelf.recording = NO;
- }
- else {
- // Verify possible shortcut
- if (shortcut.keyCodeString.length > 0) {
- if (shortcut.valid) {
- // Verify that shortcut is not used
- NSError *error = nil;
- if ([shortcut isTakenError:&error]) {
- // Prevent cancel of recording when Alert window is key
- [weakSelf activateResignObserver:NO];
- [weakSelf activateEventMonitoring:NO];
- NSString *format = NSLocalizedString(@"The key combination %@ cannot be used",
- @"Title for alert when shortcut is already used");
- NSRunCriticalAlertPanel([NSString stringWithFormat:format, shortcut], error.localizedDescription,
- NSLocalizedString(@"OK", @"Alert button when shortcut is already used"),
- nil, nil);
- weakSelf.shortcutPlaceholder = nil;
- [weakSelf activateResignObserver:YES];
- [weakSelf activateEventMonitoring:YES];
- }
- else {
- weakSelf.shortcutValue = shortcut;
- weakSelf.recording = NO;
- }
- }
- else {
- // Key press with or without SHIFT is not valid input
- NSBeep();
- }
- }
- else {
- // User is playing with modifier keys
- weakSelf.shortcutPlaceholder = shortcut.modifierFlagsString;
- }
- event = nil;
- }
- return event;
- }];
- }
- else {
- [NSEvent removeMonitor:eventMonitor];
- }
-}
-
-- (void)activateResignObserver:(BOOL)shouldActivate
-{
- static BOOL isActive = NO;
- if (isActive == shouldActivate) return;
- isActive = shouldActivate;
-
- static id observer = nil;
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
- if (shouldActivate) {
- __weak MASShortcutView *weakSelf = self;
- observer = [notificationCenter addObserverForName:NSWindowDidResignKeyNotification object:self.window
- queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
- weakSelf.recording = NO;
- }];
- }
- else {
- [notificationCenter removeObserver:observer];
- }
-}
-
-@end