2 // EnjoyableApplicationDelegate.m
5 // Created by Sam McCall on 4/05/09.
8 #import "EnjoyableApplicationDelegate.h"
11 #import "NJMappingsController.h"
12 #import "NJDeviceController.h"
13 #import "NJOutputController.h"
16 @implementation EnjoyableApplicationDelegate
18 - (void)didSwitchApplication:(NSNotification *)note {
19 NSRunningApplication *activeApp = note.userInfo[NSWorkspaceApplicationKey];
20 NSString *name = activeApp.localizedName;
22 name = activeApp.bundleIdentifier;
23 if (name && ![name isEqualToString:NSRunningApplication.currentApplication.localizedName])
24 [self.mappingsController activateMappingForProcess:name];
27 - (void)applicationDidFinishLaunching:(NSNotification *)notification {
28 [NSNotificationCenter.defaultCenter
30 selector:@selector(mappingDidChange:)
31 name:NJEventMappingChanged
33 [NSNotificationCenter.defaultCenter
35 selector:@selector(mappingListDidChange:)
36 name:NJEventMappingListChanged
38 [NSNotificationCenter.defaultCenter
40 selector:@selector(eventTranslationActivated:)
41 name:NJEventTranslationActivated
43 [NSNotificationCenter.defaultCenter
45 selector:@selector(eventTranslationDeactivated:)
46 name:NJEventTranslationDeactivated
49 [self.inputController setup];
50 [self.mappingsController load];
53 - (void)applicationDidBecomeActive:(NSNotification *)notification {
54 [window makeKeyAndOrderFront:nil];
57 - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication
58 hasVisibleWindows:(BOOL)flag {
59 [window makeKeyAndOrderFront:nil];
63 - (void)eventTranslationActivated:(NSNotification *)note {
64 [NSProcessInfo.processInfo disableAutomaticTermination:@"Input translation is active."];
65 [NSWorkspace.sharedWorkspace.notificationCenter
67 selector:@selector(didSwitchApplication:)
68 name:NSWorkspaceDidActivateApplicationNotification
70 NSLog(@"Listening for application changes.");
73 - (void)eventTranslationDeactivated:(NSNotification *)note {
74 [NSProcessInfo.processInfo enableAutomaticTermination:@"Input translation is active."];
75 [NSWorkspace.sharedWorkspace.notificationCenter
77 name:NSWorkspaceDidActivateApplicationNotification
79 NSLog(@"Ignoring application changes.");
82 - (void)mappingListDidChange:(NSNotification *)note {
83 NSArray *mappings = note.object;
84 while (dockMenuBase.lastItem.representedObject)
85 [dockMenuBase removeLastItem];
87 for (NJMapping *mapping in mappings) {
88 NSString *keyEquiv = ++added < 10 ? @(added).stringValue : @"";
89 NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:mapping.name
90 action:@selector(chooseMapping:)
91 keyEquivalent:keyEquiv];
92 item.representedObject = mapping;
93 item.state = mapping == self.mappingsController.currentMapping;
94 [dockMenuBase addItem:item];
98 - (void)mappingDidChange:(NSNotification *)note {
99 NJMapping *current = note.object;
100 for (NSMenuItem *item in dockMenuBase.itemArray)
101 if (item.representedObject)
102 item.state = item.representedObject == current;
105 - (void)chooseMapping:(NSMenuItem *)sender {
106 NJMapping *chosen = sender.representedObject;
107 [self.mappingsController activateMapping:chosen];
110 #define OUTPUT_PANE_MIN_WIDTH 390
111 #define INPUT_PANE_MIN_WIDTH 160
113 - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex {
114 return INPUT_PANE_MIN_WIDTH;
117 - (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)offset {
118 return proposedMax - OUTPUT_PANE_MIN_WIDTH;
121 - (void)splitView:(NSSplitView *)splitView resizeSubviewsWithOldSize:(NSSize)oldSize {
122 NSView *inputView = splitView.subviews[0];
123 NSView *outputView = splitView.subviews[1];
124 if (outputView.frame.size.width < OUTPUT_PANE_MIN_WIDTH) {
125 NSSize frameSize = splitView.frame.size;
126 CGFloat inputWidth = frameSize.width - OUTPUT_PANE_MIN_WIDTH - splitView.dividerThickness;
127 inputView.frame = NSMakeRect(inputWidth, frameSize.height,
128 inputView.frame.size.width,
129 inputView.frame.size.height);
130 outputView.frame = NSMakeRect(inputWidth + splitView.dividerThickness,
132 OUTPUT_PANE_MIN_WIDTH,
135 [splitView adjustSubviews];
138 - (NSMenu *)applicationDockMenu:(NSApplication *)sender {
139 NSMenu *menu = [[NSMenu alloc] init];
141 for (NJMapping *mapping in self.mappingsController) {
142 NSString *keyEquiv = ++added < 10 ? @(added).stringValue : @"";
143 NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:mapping.name
144 action:@selector(chooseMapping:)
145 keyEquivalent:keyEquiv];
146 item.representedObject = mapping;
147 item.state = mapping == self.mappingsController.currentMapping;
153 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
154 NSURL *url = [NSURL fileURLWithPath:filename];
155 [self.mappingsController addMappingWithContentsOfURL:url];