Add pod MASShortcut 2.3.6
This commit is contained in:
615
Pods/MASShortcut/Framework/MASShortcutView.m
generated
Normal file
615
Pods/MASShortcut/Framework/MASShortcutView.m
generated
Normal file
@ -0,0 +1,615 @@
|
||||
#import "MASShortcutView.h"
|
||||
#import "MASShortcutValidator.h"
|
||||
#import "MASLocalization.h"
|
||||
|
||||
NSString *const MASShortcutBinding = @"shortcutValue";
|
||||
|
||||
static const CGFloat MASHintButtonWidth = 23;
|
||||
static const CGFloat MASButtonFontSize = 11;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface MASShortcutView () // Private accessors
|
||||
|
||||
@property (nonatomic, getter = isHinting) BOOL hinting;
|
||||
@property (nonatomic, copy) NSString *shortcutPlaceholder;
|
||||
@property (nonatomic, assign) BOOL showsDeleteButton;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation MASShortcutView {
|
||||
NSButtonCell *_shortcutCell;
|
||||
NSInteger _shortcutToolTipTag;
|
||||
NSInteger _hintToolTipTag;
|
||||
NSTrackingArea *_hintArea;
|
||||
BOOL _acceptsFirstResponder;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (Class)shortcutCellClass
|
||||
{
|
||||
return [NSButtonCell class];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frameRect
|
||||
{
|
||||
self = [super initWithFrame:frameRect];
|
||||
if (self) {
|
||||
[self commonInit];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)coder
|
||||
{
|
||||
self = [super initWithCoder:coder];
|
||||
if (self) {
|
||||
[self commonInit];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)commonInit
|
||||
{
|
||||
_shortcutCell = [[[self.class shortcutCellClass] alloc] init];
|
||||
_shortcutCell.buttonType = NSPushOnPushOffButton;
|
||||
_shortcutCell.font = [[NSFontManager sharedFontManager] convertFont:_shortcutCell.font toSize:MASButtonFontSize];
|
||||
_shortcutValidator = [MASShortcutValidator sharedValidator];
|
||||
_enabled = YES;
|
||||
_showsDeleteButton = YES;
|
||||
_acceptsFirstResponder = NO;
|
||||
[self resetShortcutCellStyle];
|
||||
}
|
||||
|
||||
- (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)setStyle:(MASShortcutViewStyle)newStyle
|
||||
{
|
||||
if (_style != newStyle) {
|
||||
_style = newStyle;
|
||||
[self resetShortcutCellStyle];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)resetShortcutCellStyle
|
||||
{
|
||||
switch (_style) {
|
||||
case MASShortcutViewStyleDefault: {
|
||||
_shortcutCell.bezelStyle = NSRoundRectBezelStyle;
|
||||
break;
|
||||
}
|
||||
case MASShortcutViewStyleTexturedRect: {
|
||||
_shortcutCell.bezelStyle = NSTexturedRoundedBezelStyle;
|
||||
break;
|
||||
}
|
||||
case MASShortcutViewStyleRounded: {
|
||||
_shortcutCell.bezelStyle = NSRoundedBezelStyle;
|
||||
break;
|
||||
}
|
||||
case MASShortcutViewStyleFlat: {
|
||||
self.wantsLayer = YES;
|
||||
_shortcutCell.backgroundColor = [NSColor clearColor];
|
||||
_shortcutCell.bordered = NO;
|
||||
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;
|
||||
|
||||
// Only care about changes in state
|
||||
if (flag == _recording) return;
|
||||
|
||||
_recording = flag;
|
||||
self.shortcutPlaceholder = nil;
|
||||
[self resetToolTips];
|
||||
[self activateEventMonitoring:_recording];
|
||||
[self activateResignObserver:_recording];
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
// Give VoiceOver users feedback on the result. Requires at least 10.9 to run.
|
||||
// We’re silencing the “tautological compare” warning here so that if someone
|
||||
// takes the naked source files and compiles them with -Wall, the following
|
||||
// NSAccessibilityPriorityKey comparison doesn’t cause a warning. See:
|
||||
// https://github.com/shpakovski/MASShortcut/issues/76
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
if (_recording == NO && (&NSAccessibilityPriorityKey != NULL)) {
|
||||
NSString* msg = _shortcutValue ?
|
||||
MASLocalizedString(@"Shortcut set", @"VoiceOver: Shortcut set") :
|
||||
MASLocalizedString(@"Shortcut cleared", @"VoiceOver: Shortcut cleared");
|
||||
NSDictionary *announcementInfo = @{
|
||||
NSAccessibilityAnnouncementKey : msg,
|
||||
NSAccessibilityPriorityKey : @(NSAccessibilityPriorityHigh),
|
||||
};
|
||||
NSAccessibilityPostNotificationWithUserInfo(self, NSAccessibilityAnnouncementRequestedNotification, announcementInfo);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
- (void)setShortcutValue:(MASShortcut *)shortcutValue
|
||||
{
|
||||
_shortcutValue = shortcutValue;
|
||||
[self resetToolTips];
|
||||
[self setNeedsDisplay:YES];
|
||||
[self propagateValue:shortcutValue forBinding:MASShortcutBinding];
|
||||
|
||||
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 (_style) {
|
||||
case MASShortcutViewStyleDefault: {
|
||||
[_shortcutCell drawWithFrame:frame inView:self];
|
||||
break;
|
||||
}
|
||||
case MASShortcutViewStyleTexturedRect: {
|
||||
[_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self];
|
||||
break;
|
||||
}
|
||||
case MASShortcutViewStyleRounded: {
|
||||
[_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self];
|
||||
break;
|
||||
}
|
||||
case MASShortcutViewStyleFlat: {
|
||||
[_shortcutCell drawWithFrame:frame inView:self];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)dirtyRect
|
||||
{
|
||||
if (self.shortcutValue) {
|
||||
NSString *buttonTitle;
|
||||
if (self.recording) {
|
||||
buttonTitle = NSStringFromMASKeyCode(kMASShortcutGlyphEscape);
|
||||
} else if (self.showsDeleteButton) {
|
||||
buttonTitle = NSStringFromMASKeyCode(kMASShortcutGlyphClear);
|
||||
}
|
||||
if (buttonTitle != nil) {
|
||||
[self drawInRect:self.bounds withTitle:buttonTitle alignment:NSRightTextAlignment state:NSOffState];
|
||||
}
|
||||
CGRect shortcutRect;
|
||||
[self getShortcutRect:&shortcutRect hintRect:NULL];
|
||||
NSString *title = (self.recording
|
||||
? (_hinting
|
||||
? MASLocalizedString(@"Use Old Shortcut", @"Cancel action button for non-empty shortcut in recording state")
|
||||
: (self.shortcutPlaceholder.length > 0
|
||||
? self.shortcutPlaceholder
|
||||
: MASLocalizedString(@"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:NSStringFromMASKeyCode(kMASShortcutGlyphEscape) alignment:NSRightTextAlignment state:NSOffState];
|
||||
|
||||
CGRect shortcutRect;
|
||||
[self getShortcutRect:&shortcutRect hintRect:NULL];
|
||||
NSString *title = (_hinting
|
||||
? MASLocalizedString(@"Cancel", @"Cancel action button in recording state")
|
||||
: (self.shortcutPlaceholder.length > 0
|
||||
? self.shortcutPlaceholder
|
||||
: MASLocalizedString(@"Type Shortcut", @"Empty shortcut button in recording state")));
|
||||
[self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:NSOnState];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self drawInRect:self.bounds withTitle:MASLocalizedString(@"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 = MASHintButtonWidth;
|
||||
switch (self.style) {
|
||||
case MASShortcutViewStyleTexturedRect: hintButtonWidth += 2.0; break;
|
||||
case MASShortcutViewStyleRounded: hintButtonWidth += 3.0; break;
|
||||
case MASShortcutViewStyleFlat: hintButtonWidth -= 8.0 - (_shortcutCell.font.pointSize - MASButtonFontSize); 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 MASLocalizedString(@"Click to record new shortcut", @"Tooltip for non-empty shortcut button");
|
||||
}
|
||||
else if (data == kUserDataHint) {
|
||||
return MASLocalizedString(@"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) {
|
||||
__unsafe_unretained MASShortcutView *weakSelf = self;
|
||||
NSEventMask eventMask = (NSKeyDownMask | NSFlagsChangedMask);
|
||||
eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) {
|
||||
|
||||
// Create a shortcut from the event
|
||||
MASShortcut *shortcut = [MASShortcut shortcutWithEvent:event];
|
||||
|
||||
// Tab key must pass through.
|
||||
if (shortcut.keyCode == kVK_Tab){
|
||||
return event;
|
||||
}
|
||||
|
||||
// If the shortcut is a plain Delete or Backspace, clear the current shortcut and cancel recording
|
||||
if (!shortcut.modifierFlags && ((shortcut.keyCode == kVK_Delete) || (shortcut.keyCode == kVK_ForwardDelete))) {
|
||||
weakSelf.shortcutValue = nil;
|
||||
weakSelf.recording = NO;
|
||||
event = nil;
|
||||
}
|
||||
|
||||
// If the shortcut is a plain Esc, cancel recording
|
||||
else if (!shortcut.modifierFlags && shortcut.keyCode == kVK_Escape) {
|
||||
weakSelf.recording = NO;
|
||||
event = nil;
|
||||
}
|
||||
|
||||
// If the shortcut is Cmd-W or Cmd-Q, cancel recording and pass the event through
|
||||
else if ((shortcut.modifierFlags == NSCommandKeyMask) && (shortcut.keyCode == kVK_ANSI_W || shortcut.keyCode == kVK_ANSI_Q)) {
|
||||
weakSelf.recording = NO;
|
||||
}
|
||||
|
||||
else {
|
||||
// Verify possible shortcut
|
||||
if (shortcut.keyCodeString.length > 0) {
|
||||
if ([_shortcutValidator isShortcutValid:shortcut]) {
|
||||
// Verify that shortcut is not used
|
||||
NSString *explanation = nil;
|
||||
if ([_shortcutValidator isShortcutAlreadyTakenBySystem:shortcut explanation:&explanation]) {
|
||||
// Prevent cancel of recording when Alert window is key
|
||||
[weakSelf activateResignObserver:NO];
|
||||
[weakSelf activateEventMonitoring:NO];
|
||||
NSString *format = MASLocalizedString(@"The key combination %@ cannot be used",
|
||||
@"Title for alert when shortcut is already used");
|
||||
NSAlert* alert = [[NSAlert alloc]init];
|
||||
alert.alertStyle = NSCriticalAlertStyle;
|
||||
alert.informativeText = explanation;
|
||||
alert.messageText = [NSString stringWithFormat:format, shortcut];
|
||||
[alert addButtonWithTitle:MASLocalizedString(@"OK", @"Alert button when shortcut is already used")];
|
||||
|
||||
[alert runModal];
|
||||
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) {
|
||||
__unsafe_unretained MASShortcutView *weakSelf = self;
|
||||
observer = [notificationCenter addObserverForName:NSWindowDidResignKeyNotification object:self.window
|
||||
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
|
||||
weakSelf.recording = NO;
|
||||
}];
|
||||
}
|
||||
else {
|
||||
[notificationCenter removeObserver:observer];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Bindings
|
||||
|
||||
// http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/
|
||||
-(void) propagateValue:(id)value forBinding:(NSString*)binding
|
||||
{
|
||||
NSParameterAssert(binding != nil);
|
||||
|
||||
//WARNING: bindingInfo contains NSNull, so it must be accounted for
|
||||
NSDictionary* bindingInfo = [self infoForBinding:binding];
|
||||
if(!bindingInfo)
|
||||
return; //there is no binding
|
||||
|
||||
//apply the value transformer, if one has been set
|
||||
NSDictionary* bindingOptions = [bindingInfo objectForKey:NSOptionsKey];
|
||||
if(bindingOptions){
|
||||
NSValueTransformer* transformer = [bindingOptions valueForKey:NSValueTransformerBindingOption];
|
||||
if(!transformer || (id)transformer == [NSNull null]){
|
||||
NSString* transformerName = [bindingOptions valueForKey:NSValueTransformerNameBindingOption];
|
||||
if(transformerName && (id)transformerName != [NSNull null]){
|
||||
transformer = [NSValueTransformer valueTransformerForName:transformerName];
|
||||
}
|
||||
}
|
||||
|
||||
if(transformer && (id)transformer != [NSNull null]){
|
||||
if([[transformer class] allowsReverseTransformation]){
|
||||
value = [transformer reverseTransformedValue:value];
|
||||
} else {
|
||||
NSLog(@"WARNING: binding \"%@\" has value transformer, but it doesn't allow reverse transformations in %s", binding, __PRETTY_FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
id boundObject = [bindingInfo objectForKey:NSObservedObjectKey];
|
||||
if(!boundObject || boundObject == [NSNull null]){
|
||||
NSLog(@"ERROR: NSObservedObjectKey was nil for binding \"%@\" in %s", binding, __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString* boundKeyPath = [bindingInfo objectForKey:NSObservedKeyPathKey];
|
||||
if(!boundKeyPath || (id)boundKeyPath == [NSNull null]){
|
||||
NSLog(@"ERROR: NSObservedKeyPathKey was nil for binding \"%@\" in %s", binding, __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
[boundObject setValue:value forKeyPath:boundKeyPath];
|
||||
}
|
||||
|
||||
#pragma mark - Accessibility
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityHelp
|
||||
{
|
||||
return MASLocalizedString(@"To record a new shortcut, click this button, and then type the"
|
||||
@" new shortcut, or press delete to clear an existing shortcut.",
|
||||
@"VoiceOver shortcut help");
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
NSString* title = _shortcutValue.description ?: @"Empty";
|
||||
title = [title stringByAppendingFormat:@" %@", MASLocalizedString(@"keyboard shortcut", @"VoiceOver title")];
|
||||
return title;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformPress
|
||||
{
|
||||
if (self.isRecording == NO) {
|
||||
self.recording = YES;
|
||||
return YES;
|
||||
}
|
||||
else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityButtonRole;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return _acceptsFirstResponder;
|
||||
}
|
||||
|
||||
- (void)setAcceptsFirstResponder:(BOOL)value
|
||||
{
|
||||
_acceptsFirstResponder = value;
|
||||
}
|
||||
|
||||
- (BOOL)becomeFirstResponder
|
||||
{
|
||||
[self setNeedsDisplay:YES];
|
||||
return [super becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (BOOL)resignFirstResponder
|
||||
{
|
||||
[self setNeedsDisplay:YES];
|
||||
return [super resignFirstResponder];
|
||||
}
|
||||
|
||||
- (void)drawFocusRingMask
|
||||
{
|
||||
[_shortcutCell drawFocusRingMaskWithFrame:[self bounds] inView:self];
|
||||
}
|
||||
|
||||
- (NSRect)focusRingMaskBounds
|
||||
{
|
||||
return [self bounds];
|
||||
}
|
||||
|
||||
@end
|
Reference in New Issue
Block a user