// // NJMappingMenuController.m // Enjoyable // // Created by Joe Wreschnig on 3/11/13. // // #import "NJMappingMenuController.h" #import "NJEvents.h" #import "NJMapping.h" #define MAXIMUM_MAPPINGS_IN_MENU 15 @implementation NJMappingMenuController - (id)init { if ((self = [super init])) { NSNotificationCenter *center = NSNotificationCenter.defaultCenter; [center addObserver:self selector:@selector(mappingsListDidChange:) name:NJEventMappingListChanged object:nil]; [center addObserver:self selector:@selector(mappingDidChange:) name:NJEventMappingChanged object:nil]; [center addObserver:self selector:@selector(eventTranslationActivated:) name:NJEventTranslationActivated object:nil]; [center addObserver:self selector:@selector(eventTranslationDeactivated:) name:NJEventTranslationDeactivated object:nil]; } return self; } - (void)dealloc { [NSNotificationCenter.defaultCenter removeObserver:self]; } - (void)_mappingWasChosen:(NSMenuItem *)sender { NJMapping *mapping = sender.representedObject; [self.delegate mappingWasChosen:mapping]; } - (void)_mappingListWasChosen:(NSMenuItem *)sender { [self.delegate mappingListShouldOpen]; } - (void)mappingsListDidChange:(NSNotification *)note { NSArray *mappings = note.userInfo[@"mappings"]; NJMapping *currentMapping = note.userInfo[@"mapping"]; NSMenuItem *toRemove; while (self.menu.numberOfItems > self.firstMappingIndex && (toRemove = [self.menu itemAtIndex:self.firstMappingIndex]) && ([toRemove.representedObject isKindOfClass:NJMapping.class] || toRemove.representedObject == self.class)) [self.menu removeItemAtIndex:self.firstMappingIndex]; int added = 0; NSUInteger index = self.firstMappingIndex; for (NJMapping *mapping in mappings) { NSString *keyEquiv = (++added < 10 && self.hasKeyEquivalents) ? @(added).stringValue : @""; NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:mapping.name action:@selector(_mappingWasChosen:) keyEquivalent:keyEquiv]; item.representedObject = mapping; item.state = mapping == currentMapping; item.target = self; [self.menu insertItem:item atIndex:index++]; if (added == MAXIMUM_MAPPINGS_IN_MENU && mappings.count > MAXIMUM_MAPPINGS_IN_MENU + 1) { NSString *msg = [NSString stringWithFormat:@"(and %lu moreā€¦)", mappings.count - MAXIMUM_MAPPINGS_IN_MENU]; NSMenuItem *end = [[NSMenuItem alloc] initWithTitle:msg action:@selector(_mappingListWasChosen:) keyEquivalent:@""]; // There must be a represented object here so the item gets // removed correctly when the menus are regenerated. end.representedObject = self.class; end.target = self; [self.menu insertItem:end atIndex:index]; break; } } } - (void)mappingDidChange:(NSNotification *)note { NJMapping *mapping = note.userInfo[@"mapping"]; for (NSMenuItem *item in self.menu.itemArray) if ([item.representedObject isKindOfClass:NJMapping.class]) item.state = mapping == item.representedObject; } - (void)eventTranslationActivated:(NSNotification *)note { self.eventTranslationToggle.title = @"Disable"; } - (void)eventTranslationDeactivated:(NSNotification *)note { self.eventTranslationToggle.title = @"Enable"; } @end