X-Git-Url: https://git.yukkurigames.com/?p=enjoyable.git;a=blobdiff_plain;f=Classes%2FNJMappingsController.m;h=ad257cfb8b269028d62d85bc6d4882108b7706f8;hp=ea8137f8465e8c781b9402b53294cf293d6d31e3;hb=dacfcc6b0bf3bfebc89b5e6e8266da9eb36177cd;hpb=0064c1fbff36795885a9724081af2a17d83c20a3 diff --git a/Classes/NJMappingsController.m b/Classes/NJMappingsController.m index ea8137f..ad257cf 100644 --- a/Classes/NJMappingsController.m +++ b/Classes/NJMappingsController.m @@ -10,22 +10,20 @@ #import "NJMapping.h" #import "NJMappingsController.h" #import "NJOutput.h" -#import "NJOutputController.h" #import "NJEvents.h" #define PB_ROW @"com.yukkurigames.Enjoyable.MappingRow" @implementation NJMappingsController { NSMutableArray *_mappings; - NJMapping *manualMapping; - NSString *draggingName; + NJMapping *_manualMapping; } - (id)init { if ((self = [super init])) { _mappings = [[NSMutableArray alloc] init]; _currentMapping = [[NJMapping alloc] initWithName:@"(default)"]; - manualMapping = _currentMapping; + _manualMapping = _currentMapping; [_mappings addObject:_currentMapping]; } return self; @@ -50,11 +48,12 @@ - (void)mappingsChanged { [self save]; [tableView reloadData]; - popoverActivate.title = _currentMapping.name; [self updateInterfaceForCurrentMapping]; [NSNotificationCenter.defaultCenter postNotificationName:NJEventMappingListChanged - object:_mappings]; + object:self + userInfo:@{ @"mappings": _mappings, + @"mapping": _currentMapping }]; } - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state @@ -65,26 +64,34 @@ count:len]; } -- (void)activateMappingForProcess:(NSString *)processName { - if ([manualMapping.name.lowercaseString isEqualToString:@"@application"]) { - manualMapping.name = processName; - [self mappingsChanged]; - } else { - NJMapping *oldMapping = manualMapping; - NJMapping *newMapping = self[processName]; - if (!newMapping) - newMapping = oldMapping; - if (newMapping != _currentMapping) - [self activateMapping:newMapping]; - manualMapping = oldMapping; +- (void)activateMappingForProcess:(NSRunningApplication *)app { + NJMapping *oldMapping = _manualMapping; + NSArray *names = app.possibleMappingNames; + BOOL found = NO; + for (NSString *name in names) { + NJMapping *mapping = self[name]; + if (mapping) { + [self activateMapping:mapping]; + found = YES; + break; + } + } + + if (!found) { + [self activateMapping:oldMapping]; + if ([oldMapping.name.lowercaseString isEqualToString:@"@application"]) { + oldMapping.name = app.bestMappingName; + [self mappingsChanged]; + } } + _manualMapping = oldMapping; } - (void)updateInterfaceForCurrentMapping { NSUInteger selected = [_mappings indexOfObject:_currentMapping]; - [removeButton setEnabled:selected != 0]; - [moveDown setEnabled:selected && selected != _mappings.count - 1]; - [moveUp setEnabled:selected > 1]; + removeButton.enabled = selected != 0; + moveUp.enabled = selected > 1; + moveDown.enabled = selected && selected != _mappings.count - 1; popoverActivate.title = _currentMapping.name; [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:selected] byExtendingSelection:NO]; [NSUserDefaults.standardUserDefaults setInteger:selected forKey:@"selected"]; @@ -92,16 +99,17 @@ - (void)activateMapping:(NJMapping *)mapping { if (!mapping) - mapping = manualMapping; + mapping = _manualMapping; if (mapping == _currentMapping) return; NSLog(@"Switching to mapping %@.", mapping.name); - manualMapping = mapping; + _manualMapping = mapping; _currentMapping = mapping; [self updateInterfaceForCurrentMapping]; - [outputController loadCurrent]; - [NSNotificationCenter.defaultCenter postNotificationName:NJEventMappingChanged - object:_currentMapping]; + [NSNotificationCenter.defaultCenter + postNotificationName:NJEventMappingChanged + object:self + userInfo:@{ @"mapping": _currentMapping }]; } - (IBAction)addPressed:(id)sender { @@ -163,21 +171,19 @@ - (void)loadAllFrom:(NSArray *)storedMappings andActivate:(NSUInteger)selected { NSMutableArray* newMappings = [[NSMutableArray alloc] initWithCapacity:storedMappings.count]; - // have to do two passes in case mapping1 refers to mapping2 via a NJOutputMapping + // Requires two passes to deal with inter-mapping references. First make + // an empty mapping for each serialized mapping. Then, deserialize the + // data pointing to the empty mappings. Then merge that data back into + // its equivalent empty one, which is the one we finally use. for (NSDictionary *storedMapping in storedMappings) { NJMapping *mapping = [[NJMapping alloc] initWithName:storedMapping[@"name"]]; [newMappings addObject:mapping]; } for (unsigned i = 0; i < storedMappings.count; ++i) { - NSDictionary *entries = storedMappings[i][@"entries"]; - NJMapping *mapping = newMappings[i]; - for (id key in entries) { - NJOutput *output = [NJOutput outputDeserialize:entries[key] - withMappings:newMappings]; - if (output) - mapping.entries[key] = output; - } + NJMapping *realMapping = [[NJMapping alloc] initWithSerialization:storedMappings[i] + mappings:newMappings]; + [newMappings[i] mergeEntriesFrom:realMapping]; } if (newMappings.count) { @@ -189,37 +195,6 @@ } } -- (NJMapping *)mappingWithURL:(NSURL *)url error:(NSError **)error { - NSInputStream *stream = [NSInputStream inputStreamWithURL:url]; - [stream open]; - NSDictionary *serialization = !*error - ? [NSJSONSerialization JSONObjectWithStream:stream options:0 error:error] - : nil; - [stream close]; - - if (!([serialization isKindOfClass:NSDictionary.class] - && [serialization[@"name"] isKindOfClass:NSString.class] - && [serialization[@"entries"] isKindOfClass:NSDictionary.class])) { - *error = [NSError errorWithDomain:@"Enjoyable" - code:0 - description:@"This isn't a valid mapping file."]; - return nil; - } - - NSDictionary *entries = serialization[@"entries"]; - NJMapping *mapping = [[NJMapping alloc] initWithName:serialization[@"name"]]; - for (id key in entries) { - NSDictionary *value = entries[key]; - if ([key isKindOfClass:NSString.class]) { - NJOutput *output = [NJOutput outputDeserialize:value - withMappings:_mappings]; - if (output) - mapping.entries[key] = output; - } - } - return mapping; -} - - (void)addMappingWithContentsOfURL:(NSURL *)url { NSWindow *window = popoverActivate.window; NSError *error; @@ -228,15 +203,8 @@ error:&error]; if (mapping && !error) { - BOOL conflict = NO; NJMapping *mergeInto = self[mapping.name]; - for (id key in mapping.entries) { - if (mergeInto.entries[key] - && ![mergeInto.entries[key] isEqual:mapping.entries[key]]) { - conflict = YES; - break; - } - } + BOOL conflict = [mergeInto hasConflictWith:mapping]; if (conflict) { NSAlert *conflictAlert = [[NSAlert alloc] init]; @@ -257,7 +225,7 @@ } if (mergeInto) { - [mergeInto.entries addEntriesFromDictionary:mapping.entries]; + [mergeInto mergeEntriesFrom:mapping]; mapping = mergeInto; } else { [_mappings addObject:mapping]; @@ -333,19 +301,13 @@ } - (IBAction)moveUpPressed:(id)sender { - NSUInteger idx = [_mappings indexOfObject:_currentMapping]; - if (idx > 1 && idx != NSNotFound) { - [_mappings exchangeObjectAtIndex:idx withObjectAtIndex:idx - 1]; + if ([_mappings moveFirstwards:_currentMapping upTo:1]) [self mappingsChanged]; - } } - (IBAction)moveDownPressed:(id)sender { - NSUInteger idx = [_mappings indexOfObject:_currentMapping]; - if (idx < _mappings.count - 1) { - [_mappings exchangeObjectAtIndex:idx withObjectAtIndex:idx + 1]; + if ([_mappings moveLastwards:_currentMapping]) [self mappingsChanged]; - } } - (BOOL)tableView:(NSTableView *)tableView_