From 0bc6bfcffe3319a339e28e64a81600a85382d61e Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Tue, 12 Mar 2013 14:38:17 +0100 Subject: [PATCH] Allow Command+Click to enter a raw key code. --- Classes/NJKeyInputField.h | 2 +- Classes/NJKeyInputField.m | 65 ++++++++++++++++++-- Info.plist | 2 +- Resources/English.lproj/Localizable.strings | Bin 6426 -> 6904 bytes 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/Classes/NJKeyInputField.h b/Classes/NJKeyInputField.h index c17fdaa..c32e16c 100644 --- a/Classes/NJKeyInputField.h +++ b/Classes/NJKeyInputField.h @@ -11,7 +11,7 @@ extern const CGKeyCode NJKeyInputFieldEmpty; @protocol NJKeyInputFieldDelegate; -@interface NJKeyInputField : NSControl +@interface NJKeyInputField : NSControl // An NJKeyInputField is a NSTextField-like widget that receives // exactly one key press, and displays the name of that key, then // resigns its first responder status. It can also inform a diff --git a/Classes/NJKeyInputField.m b/Classes/NJKeyInputField.m index 4e5513a..02896a8 100644 --- a/Classes/NJKeyInputField.m +++ b/Classes/NJKeyInputField.m @@ -19,6 +19,7 @@ const CGKeyCode NJKeyInputFieldEmpty = kVK_MAX; @implementation NJKeyInputField { NSTextField *field; + NSImageView *warning; } - (id)initWithFrame:(NSRect)frameRect { @@ -27,7 +28,21 @@ const CGKeyCode NJKeyInputFieldEmpty = kVK_MAX; field.alignment = NSCenterTextAlignment; field.editable = NO; field.selectable = NO; + field.delegate = self; [self addSubview:field]; + + warning = [[NSImageView alloc] init]; + warning.image = [NSImage imageNamed:@"NSInvalidDataFreestanding"]; + CGSize imgSize = warning.image.size; + CGRect bounds = self.bounds; + warning.frame = CGRectMake(bounds.size.width - (imgSize.width + 4), + (bounds.size.height - imgSize.height) / 2, + imgSize.width, imgSize.height); + + warning.toolTip = NSLocalizedString(@"invalid key code", + @"shown when the user types an invalid key code"); + warning.hidden = YES; + [self addSubview:warning]; } return self; } @@ -220,12 +235,51 @@ const CGKeyCode NJKeyInputFieldEmpty = kVK_MAX; [self resignIfFirstResponder]; } } + +static BOOL isValidKeyCode(long code) { + return code < 0xFFFF && code >= 0; +} + +- (void)controlTextDidChange:(NSNotification *)obj { + char *error = NULL; + long code = strtol(field.stringValue.UTF8String, &error, 16); + warning.hidden = (isValidKeyCode(code) && !*error) || !field.stringValue.length; +} + +- (void)controlTextDidEndEditing:(NSNotification *)obj { + [field.cell setPlaceholderString:@""]; + field.editable = NO; + field.selectable = NO; + warning.hidden = YES; + char *error = NULL; + const char *s = field.stringValue.UTF8String; + long code = strtol(s, &error, 16); + if (!*error && isValidKeyCode(code) && field.stringValue.length) { + self.keyCode = code; + [self.delegate keyInputField:self didChangeKey:self.keyCode]; + } else { + self.keyCode = self.keyCode; + } +} + - (void)mouseDown:(NSEvent *)theEvent { - if (self.window.firstResponder == self) - [self.window makeFirstResponder:nil]; - else if (self.acceptsFirstResponder) - [self.window makeFirstResponder:self]; + if (self.isEnabled) { + if (theEvent.modifierFlags & NSCommandKeyMask) { + field.editable = YES; + field.selectable = YES; + field.stringValue = @""; + [field.cell setPlaceholderString: + NSLocalizedString(@"enter key code", + @"shown when user must enter a key code to map to")]; + [self.window makeFirstResponder:field]; + } else { + if (self.window.firstResponder == self) + [self.window makeFirstResponder:nil]; + else if (self.acceptsFirstResponder) + [self.window makeFirstResponder:self]; + } + } } - (void)flagsChanged:(NSEvent *)theEvent { @@ -235,7 +289,8 @@ const CGKeyCode NJKeyInputFieldEmpty = kVK_MAX; // user type these virtual keys. However, there is no actual event // for modifier key up - so detect it by checking to see if any // modifiers are still down. - if (!(theEvent.modifierFlags & NSDeviceIndependentModifierFlagsMask)) { + if (!field.isEditable + && !(theEvent.modifierFlags & NSDeviceIndependentModifierFlagsMask)) { self.keyCode = theEvent.keyCode; [self.delegate keyInputField:self didChangeKey:_keyCode]; } diff --git a/Info.plist b/Info.plist index 9bb0e57..c72bc22 100644 --- a/Info.plist +++ b/Info.plist @@ -46,7 +46,7 @@ CFBundleSignature ???? CFBundleVersion - 184 + 185 LSApplicationCategoryType public.app-category.utilities NSHumanReadableCopyright diff --git a/Resources/English.lproj/Localizable.strings b/Resources/English.lproj/Localizable.strings index b1dda717ff5c028e3d1578f8c9a40ce5975234ab..91f6bf7891c9bc9ec5f3a6f4583ff453c7a321fb 100644 GIT binary patch delta 441 zcmah_y9&ZU5F867D2lxZM?g>um4Ky%g%9u_g!n*%#)Kqlto(>{mVSZY@7VYkmd>4` zQ3MIMnZ3Q4-Pwb2Yo7Yay^lE@Y_Wo1oMWoc8a|Q7I~x)QM6wb*Z%yV4;vN5E@+ZWC zRfo}r3HOy%QAZm32Rp{>Dyq)sEgl`6zfH=Ns$s?>&_Dz4+I00{~Zl2J8R; -- 2.20.1