diff --git a/keycastr/NSUserDefaults+Utility.h b/keycastr/NSUserDefaults+Utility.h index 34fd909..3057b46 100644 --- a/keycastr/NSUserDefaults+Utility.h +++ b/keycastr/NSUserDefaults+Utility.h @@ -35,5 +35,6 @@ -(void) setImage:(NSImage*)anImage forKey:(NSString*)aKey; -(NSImage*) imageForKey:(NSString*)aKey; +- (void)removeObjectsWithPrefix:(NSString *)prefix; @end diff --git a/keycastr/NSUserDefaults+Utility.m b/keycastr/NSUserDefaults+Utility.m index fb090d3..a025c04 100644 --- a/keycastr/NSUserDefaults+Utility.m +++ b/keycastr/NSUserDefaults+Utility.m @@ -69,4 +69,18 @@ return theImage; } +- (void)removeObjectsWithPrefix:(NSString *)prefix { + NSDictionary *all = + [self dictionaryRepresentation]; + + for (NSString *key in all) { + if ([key hasPrefix:prefix]) { + [self removeObjectForKey:key]; + } + } + + // Refresh state for cocoa bindings + [[NSUserDefaultsController sharedUserDefaultsController] revert:nil]; +} + @end diff --git a/keycastr/Svelte.xib b/keycastr/Svelte.xib index f107d65..328eea2 100644 --- a/keycastr/Svelte.xib +++ b/keycastr/Svelte.xib @@ -1,6 +1,7 @@ + @@ -13,11 +14,69 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KCColorValueTransformer + + + + + + + + + + + + + + + + + + + + + + KCColorValueTransformer + + + + + + + + + + + + + + + + + + + + + + KCColorValueTransformer + + + + + + + + + + + + + + + + + + + + + + KCColorValueTransformer + + + + + + + + + + + + + + + + + + + + + + KCColorValueTransformer + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/keycastr/SvelteVisualizer.m b/keycastr/SvelteVisualizer.m index 6bb035a..b019073 100644 --- a/keycastr/SvelteVisualizer.m +++ b/keycastr/SvelteVisualizer.m @@ -32,6 +32,7 @@ #import "KCKeycastrEvent.h" #import "KCKeystroke.h" #import "KCMouseEvent.h" +#import "NSUserDefaults+Utility.h" @implementation SvelteVisualizerFactory @@ -59,19 +60,35 @@ -(void) drawRect:(NSRect)rect { + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + NSRect frame = [self frame]; [[NSColor clearColor] setFill]; NSRectFill(frame); + + BOOL shift = [ud boolForKey:@"svelte.display.shift"]; + BOOL control = [ud boolForKey:@"svelte.display.control"]; + BOOL option = [ud boolForKey:@"svelte.display.option"]; + BOOL command = [ud boolForKey:@"svelte.display.command"]; - float oneQuarter = floorf(frame.size.width / 4); + int segmentCount = shift + control + option + command; + float oneSegment = floorf(frame.size.width / segmentCount); - [[NSColor colorWithCalibratedWhite:0 alpha:0.85] setFill]; + CGFloat rectHeight = segmentCount ? 100 : 70; + CGFloat rectY = segmentCount ? 0 : 30; + NSRect drawRect = NSMakeRect(frame.origin.x, rectY, frame.size.width, rectHeight); + + [[ud colorForKey:@"svelte.backgroundColor"] setFill]; NSBezierPath* bp = [NSBezierPath bezierPath]; - [bp appendRoundedRect:frame radius:16]; - [bp appendBezierPathWithRect:NSMakeRect(0,30,frame.size.width,1)]; - [bp appendBezierPathWithRect:NSMakeRect(oneQuarter*1,0,1,30)]; - [bp appendBezierPathWithRect:NSMakeRect(oneQuarter*2,0,1,30)]; - [bp appendBezierPathWithRect:NSMakeRect(oneQuarter*3,0,1,30)]; + [bp appendRoundedRect:drawRect radius:16]; + + if (segmentCount) { + [bp appendBezierPathWithRect:NSMakeRect(0,30,frame.size.width,1)]; + for (int i = 1; i < segmentCount; i++) { + [bp appendBezierPathWithRect:NSMakeRect(oneSegment*i,0,1,30)]; + } + } + [bp fill]; NSMutableParagraphStyle* ps = [[NSMutableParagraphStyle alloc] init]; @@ -82,7 +99,7 @@ NSString* altKeyString = [NSString stringWithUTF8String:"\xe2\x8c\xa5\x01"]; NSString* commandKeyString = [NSString stringWithUTF8String:"\xe2\x8c\x98\x01"]; NSShadow* shadow = [[NSShadow alloc] init]; - [shadow setShadowColor:[NSColor blackColor]]; + [shadow setShadowColor:[ud colorForKey:@"svelte.textShadowColor"]]; [shadow setShadowBlurRadius:2]; [shadow setShadowOffset:NSMakeSize(2,-2)]; @@ -93,38 +110,54 @@ shadow, NSShadowAttributeName, ps, NSParagraphStyleAttributeName, nil]; + + NSColor *inactiveModColor = [ud colorForKey:@"svelte.inactiveModifierColor"]; + NSColor *activeModColor = [ud colorForKey:@"svelte.activeModifierColor"]; + + NSMutableArray *drawModifiers = [@[] mutableCopy]; - if (_flags & NSEventModifierFlagShift) - [attr setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; - else - [attr setObject:[NSColor colorWithCalibratedWhite:1 alpha:0.5] forKey:NSForegroundColorAttributeName]; - size = [shiftKeyString sizeWithAttributes:attr]; - [shiftKeyString drawInRect:NSMakeRect(0,(30 - size.height) / 2.0,oneQuarter,size.height) withAttributes:attr]; + if (shift) { + NSMutableDictionary *tmpAttr = [attr mutableCopy]; + tmpAttr[NSForegroundColorAttributeName] = (_flags & NSEventModifierFlagShift) ? activeModColor : inactiveModColor; + + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:shiftKeyString attributes:tmpAttr]; + [drawModifiers addObject:attrString]; + } - if (_flags & NSEventModifierFlagControl) - [attr setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; - else - [attr setObject:[NSColor colorWithCalibratedWhite:1 alpha:0.5] forKey:NSForegroundColorAttributeName]; - size = [controlKeyString sizeWithAttributes:attr]; - [controlKeyString drawInRect:NSMakeRect(oneQuarter,(30 - size.height) / 2.0,oneQuarter,size.height) withAttributes:attr]; + if (control) { + NSMutableDictionary *tmpAttr = [attr mutableCopy]; + tmpAttr[NSForegroundColorAttributeName] = (_flags & NSEventModifierFlagControl) ? activeModColor : inactiveModColor; + + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:controlKeyString attributes:tmpAttr]; + [drawModifiers addObject:attrString]; + } - if (_flags & NSEventModifierFlagOption) - [attr setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; - else - [attr setObject:[NSColor colorWithCalibratedWhite:1 alpha:0.5] forKey:NSForegroundColorAttributeName]; - size = [altKeyString sizeWithAttributes:attr]; - [altKeyString drawInRect:NSMakeRect(oneQuarter*2,(30 - size.height) / 2.0,oneQuarter,size.height) withAttributes:attr]; + if (option) { + NSMutableDictionary *tmpAttr = [attr mutableCopy]; + tmpAttr[NSForegroundColorAttributeName] = (_flags & NSEventModifierFlagOption) ? activeModColor : inactiveModColor; + + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:altKeyString attributes:tmpAttr]; + [drawModifiers addObject:attrString]; + } - if (_flags & NSEventModifierFlagCommand) - [attr setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; - else - [attr setObject:[NSColor colorWithCalibratedWhite:1 alpha:0.5] forKey:NSForegroundColorAttributeName]; - size = [commandKeyString sizeWithAttributes:attr]; - [commandKeyString drawInRect:NSMakeRect(oneQuarter*3,(30 - size.height) / 2.0,oneQuarter,size.height) withAttributes:attr]; - + if (command) { + NSMutableDictionary *tmpAttr = [attr mutableCopy]; + tmpAttr[NSForegroundColorAttributeName] = (_flags & NSEventModifierFlagCommand) ? activeModColor : inactiveModColor; + + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:commandKeyString attributes:tmpAttr]; + [drawModifiers addObject:attrString]; + } + + for (int i = 0; i < [drawModifiers count]; i++) { + NSAttributedString *modifierString = drawModifiers[i]; + NSSize size = [modifierString.string sizeWithAttributes:attr]; + + [modifierString drawInRect:NSMakeRect(oneSegment*i,(30 - size.height) / 2.0,oneSegment,size.height)]; + } + if (_displayedString != nil) { - [attr setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; + [attr setObject:[ud colorForKey:@"svelte.textColor"] forKey:NSForegroundColorAttributeName]; float fontSize = 48; [attr setObject:[NSFont systemFontOfSize:fontSize] forKey:NSFontAttributeName]; @@ -259,8 +292,40 @@ [_visualizerView noteFlagsChanged:flags]; } +- (IBAction)resetPreferences:(id)sender { + [[NSUserDefaults standardUserDefaults] removeObjectsWithPrefix:@"svelte."]; +} + + (NSDictionary *)visualizerDefaults { - return @{ @"svelte.displayAll": @YES }; + return @{ + @"svelte.display.shift" : @YES, + @"svelte.display.control" : @YES, + @"svelte.display.option" : @YES, + @"svelte.display.command" : @YES, + @"svelte.displayAll" : @YES, + @"svelte.backgroundColor" : [NSKeyedArchiver + archivedDataWithRootObject:[NSColor colorWithCalibratedWhite:0 + alpha:0.85] + requiringSecureCoding:NO + error:NULL], + @"svelte.textColor" : + [NSKeyedArchiver archivedDataWithRootObject:[NSColor whiteColor] + requiringSecureCoding:NO + error:NULL], + @"svelte.textShadowColor" : + [NSKeyedArchiver archivedDataWithRootObject:[NSColor blackColor] + requiringSecureCoding:NO + error:NULL], + @"svelte.inactiveModifierColor" : [NSKeyedArchiver + archivedDataWithRootObject:[NSColor colorWithCalibratedWhite:1 + alpha:0.5] + requiringSecureCoding:NO + error:NULL], + @"svelte.activeModifierColor" : + [NSKeyedArchiver archivedDataWithRootObject:[NSColor whiteColor] + requiringSecureCoding:NO + error:NULL], + }; } @end