App delegate now controls communication between device / mapping controllers and...
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 20 Mar 2013 19:02:35 +0000 (20:02 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 20 Mar 2013 19:02:35 +0000 (20:02 +0100)
Classes/EnjoyableApplicationDelegate.h
Classes/EnjoyableApplicationDelegate.m
Classes/NJDeviceController.h
Classes/NJDeviceController.m
Classes/NJDeviceViewController.h
Classes/NJDeviceViewController.m
Classes/NJMappingsController.m
Classes/NJOutputController.h
Classes/NJOutputController.m
Info.plist
Resources/English.lproj/MainMenu.xib

index dbc17eefb50d61e35474c1084b03d4079c1f4569..52869f21abcb952eb050a919ae052a114da99a85 100644 (file)
 
 #import "NJMappingMenuController.h"
 #import "NJMappingsViewController.h"
+#import "NJDeviceViewController.h"
+#import "NJOutputController.h"
+#import "NJDeviceController.h"
 
 @interface EnjoyableApplicationDelegate : NSObject <NSApplicationDelegate,
+                                                    NJDeviceControllerDelegate,
+                                                    NJDeviceViewControllerDelegate,
                                                     NJMappingsViewControllerDelegate,
                                                     NJMappingMenuDelegate,
                                                     NSWindowDelegate> {
 }
 
 @property (nonatomic, strong) IBOutlet NJMappingsController *mappingsController;
+@property (nonatomic, strong) IBOutlet NJDeviceController *deviceController;
+@property (nonatomic, strong) IBOutlet NJOutputController *outputController;
 @property (nonatomic, strong) IBOutlet NJMappingsViewController *mvc;
+@property (nonatomic, strong) IBOutlet NJDeviceViewController *dvc;
 
 - (IBAction)restoreToForeground:(id)sender;
 - (IBAction)importMappingClicked:(id)sender;
index bf2a336bc54eec76ce2e1dcfe974d6595c1ed94b..ca641f7bb137b2aeaefec3942eb52b90ec3bd638 100644 (file)
     [self.mappingsController activateMapping:self.mappingsController[idx]];
 }
 
+- (id)deviceViewController:(NJDeviceViewController *)dvc
+             elementForUID:(NSString *)uid {
+    return self.deviceController[uid];
+}
+
+- (void)deviceViewControllerDidSelectNothing:(NJDeviceViewController *)dvc {
+    [self.outputController loadInput:dvc.selectedHandler];
+}
+
+- (void)deviceViewController:(NJDeviceViewController *)dvc
+             didSelectBranch:(NJInputPathElement *)handler {
+    [self.outputController loadInput:dvc.selectedHandler];
+}
+
+- (void)deviceViewController:(NJDeviceViewController *)dvc
+            didSelectHandler:(NJInputPathElement *)handler {
+    [self.outputController loadInput:dvc.selectedHandler];
+}
+
+- (void)deviceViewController:(NJDeviceViewController *)dvc
+             didSelectDevice:(NJInputPathElement *)device {
+    [self.outputController loadInput:dvc.selectedHandler];
+}
+
+- (void)deviceController:(NJDeviceController *)dc
+            didAddDevice:(NJDevice *)device {
+    [self.dvc addedDevice:device atIndex:dc.count - 1];
+}
+
+- (void)deviceController:(NJDeviceController *)dc
+  didRemoveDeviceAtIndex:(NSInteger)idx {
+    [self.dvc removedDeviceAtIndex:idx];
+}
+
+- (void)deviceControllerDidStartHID:(NJDeviceController *)dc {
+    [self.dvc hidStarted];
+}
+
+- (void)deviceControllerDidStopHID:(NJDeviceController *)dc {
+    [self.dvc hidStopped];
+}
+
+- (void)deviceController:(NJDeviceController *)dc didInput:(NJInput *)input {
+    [self.outputController loadInput:input];
+    [self.outputController focusKey];
+}
+
+- (void)deviceController:(NJDeviceController *)dc didError:(NSError *)error {
+    // Since the error shows the window, it can trigger another attempt
+    // to re-open the HID manager, which will also probably fail and error,
+    // so don't bother repeating ourselves.
+    if (!window.attachedSheet) {
+        [NSApplication.sharedApplication activateIgnoringOtherApps:YES];
+        [window makeKeyAndOrderFront:nil];
+        [window presentError:error
+              modalForWindow:window
+                    delegate:nil
+          didPresentSelector:nil
+                 contextInfo:nil];
+    }
+}
+
+- (NSInteger)numberOfDevicesInDeviceList:(NJDeviceViewController *)dvc {
+    return self.deviceController.count;
+}
+
+- (NJDevice *)deviceViewController:(NJDeviceViewController *)dvc
+                    deviceForIndex:(NSUInteger)idx {
+    return self.deviceController[idx];
+}
+
 @end
index 29b8b3876318ce7e90f16cf19230a07fe84f88ac..3691d59bcd38d04b53df1b39902cf72247c4ba27 100644 (file)
 
 @class NJInput;
 @class NJMappingsController;
-@class NJOutputController;
 
-@interface NJDeviceController : NSObject <NJDeviceViewControllerDelegate,
-                                          NJHIDManagerDelegate> {
-    IBOutlet NJOutputController *outputController;
+@protocol NJDeviceControllerDelegate;
+
+@interface NJDeviceController : NSObject <NJHIDManagerDelegate> {
     IBOutlet NJMappingsController *mappingsController;
     IBOutlet NSButton *simulatingEventsButton;
-    IBOutlet NJDeviceViewController *devicesViewController;
 }
 
-@property (nonatomic, readonly) NJInput *selectedInput;
+@property (nonatomic, weak) IBOutlet id <NJDeviceControllerDelegate> delegate;
+
 @property (nonatomic, assign) NSPoint mouseLoc;
 @property (nonatomic, assign) BOOL simulatingEvents;
 
 - (IBAction)simulatingEventsChanged:(NSButton *)sender;
 
+- (NJDevice *)objectAtIndexedSubscript:(NSUInteger)idx;
+- (NJInputPathElement *)objectForKeyedSubscript:(NSString *)uid;
+- (NSUInteger)count;
+
+@end
+
+@protocol NJDeviceControllerDelegate
+
+- (void)deviceController:(NJDeviceController *)dc didAddDevice:(NJDevice *)device;
+- (void)deviceController:(NJDeviceController *)dc didRemoveDeviceAtIndex:(NSInteger)idx;
+- (void)deviceController:(NJDeviceController *)dc didInput:(NJInput *)input;
+- (void)deviceControllerDidStartHID:(NJDeviceController *)dc;
+- (void)deviceControllerDidStopHID:(NJDeviceController *)dc;
+- (void)deviceController:(NJDeviceController *)dc didError:(NSError *)error;
+
 @end
index bdd1bbf9e0c21f382f861c97bf9ec95c0877b3e7..23a0932d497f21119a16ddf9e93965d9699f8fd9 100644 (file)
@@ -12,7 +12,6 @@
 #import "NJDevice.h"
 #import "NJInput.h"
 #import "NJOutput.h"
-#import "NJOutputController.h"
 #import "NJEvents.h"
 #import "NJDeviceViewController.h"
 
     [_continuousOutputsTick invalidate];
 }
 
+- (NJDevice *)objectAtIndexedSubscript:(NSUInteger)idx {
+    return idx < _devices.count ? _devices[idx] : nil;
+}
+
+- (NSUInteger)count {
+    return _devices.count;
+}
+
 - (void)addRunningOutput:(NJOutput *)output {
     // Axis events will trigger every small movement, don't keep
     // re-adding them or they trigger multiple times each time.
     if (!handler)
         return;
     
-    [devicesViewController expandAndSelectItem:handler];
-    [outputController focusKey];
+    [self.delegate deviceController:self didInput:handler];
 }
 
 - (void)hidManager:(NJHIDManager *)manager
 
 - (void)hidManager:(NJHIDManager *)manager deviceAdded:(IOHIDDeviceRef)device {
     NJDevice *match = [[NJDevice alloc] initWithDevice:device];
-    [devicesViewController beginUpdates];
     [self addDevice:match];
-    [devicesViewController addedDevice:match atIndex:_devices.count - 1];
-    [devicesViewController endUpdates];
+    [self.delegate deviceController:self didAddDevice:match];
 }
 
 - (NJDevice *)findDeviceByRef:(IOHIDDeviceRef)device {
 
 - (void)hidManager:(NJHIDManager *)manager deviceRemoved:(IOHIDDeviceRef)device {
     NJDevice *match = [self findDeviceByRef:device];
-    IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
     if (match) {
         NSInteger idx = [_devices indexOfObjectIdenticalTo:match];
-        [devicesViewController beginUpdates];
         [_devices removeObjectAtIndex:idx];
-        [devicesViewController removedDevice:match atIndex:idx];
-        [devicesViewController endUpdates];
+        [self.delegate deviceController:self didRemoveDeviceAtIndex:idx];
     }
 }
 
 }
 
 - (void)hidManager:(NJHIDManager *)manager didError:(NSError *)error {
-    // Since the error shows the window, it can trigger another attempt
-    // to re-open the HID manager, which will also probably fail and error,
-    // so don't bother repeating ourselves.
-    if (!simulatingEventsButton.window.attachedSheet) {
-        [NSApplication.sharedApplication activateIgnoringOtherApps:YES];
-        [simulatingEventsButton.window makeKeyAndOrderFront:nil];
-        [simulatingEventsButton.window presentError:error
-                                     modalForWindow:simulatingEventsButton.window
-                                           delegate:nil
-                                 didPresentSelector:nil
-                                        contextInfo:nil];
-    }
+    [self.delegate deviceController:self didError:error];
     self.simulatingEvents = NO;
 }
 
 - (void)hidManagerDidStart:(NJHIDManager *)manager {
-    [devicesViewController hidStarted];
+    [self.delegate deviceControllerDidStartHID:self];
 }
 
 - (void)hidManagerDidStop:(NJHIDManager *)manager {
     [_devices removeAllObjects];
-    [devicesViewController hidStopped];
+    [self.delegate deviceControllerDidStopHID:self];
 }
 
 - (void)startHid {
     [_hidManager stop];
 }
 
-- (NJInput *)selectedInput {
-    return (NJInput *)devicesViewController.selectedHandler;
-}
-
 - (void)setSimulatingEvents:(BOOL)simulatingEvents {
     if (simulatingEvents != _simulatingEvents) {
         _simulatingEvents = simulatingEvents;
     return _devices[idx];
 }
 
-- (id)deviceViewController:(NJDeviceViewController *)dvc
-             elementForUID:(NSString *)uid {
+- (NJInputPathElement *)objectForKeyedSubscript:(NSString *)uid {
     for (NJDevice *dev in _devices) {
         id item = [dev elementForUID:uid];
         if (item)
     return nil;
 }
 
-- (void)deviceViewControllerDidSelectNothing:(NJDeviceViewController *)dvc {
-    [outputController loadCurrent];
-}
-
-- (void)deviceViewController:(NJDeviceViewController *)dvc
-             didSelectBranch:(NJInputPathElement *)handler {
-    [outputController loadCurrent];
-}
-
-- (void)deviceViewController:(NJDeviceViewController *)dvc
-            didSelectHandler:(NJInputPathElement *)handler {
-    [outputController loadCurrent];
-}
-
-- (void)deviceViewController:(NJDeviceViewController *)dvc
-             didSelectDevice:(NJInputPathElement *)device {
-    [outputController loadCurrent];
-}
-
 @end
index 6935322c568537fed615de25e30445f346d0beaa..0a16e477f0954d59d26f1d406433a581a58fa61a 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 @class NJDevice;
+@class NJInput;
 @class NJInputPathElement;
 
 @protocol NJDeviceViewControllerDelegate;
 @property (nonatomic, weak) IBOutlet id <NJDeviceViewControllerDelegate> delegate;
 
 - (void)addedDevice:(NJDevice *)device atIndex:(NSUInteger)idx;
-- (void)removedDevice:(NJDevice *)device atIndex:(NSUInteger)idx;
-    // But using these will animate nicely.
+- (void)removedDeviceAtIndex:(NSUInteger)idx;
 
 - (void)hidStarted;
 - (void)hidStopped;
 
-- (void)beginUpdates;
-- (void)endUpdates;
-
 - (void)expandAndSelectItem:(NJInputPathElement *)item;
 
-- (NJInputPathElement *)selectedHandler;
+- (NJInput *)selectedHandler;
 
 @end
 
index 5d0bf6abe72593530525f63d3de7abb73a0d0ade..8b36a0ee0c692ba086aef91f6b7251829daa0e1b 100644 (file)
     [self expandRecursive:[self.delegate deviceViewController:self elementForUID:uid]];
 }
 
-- (void)beginUpdates {
-    [self.inputsTree beginUpdates];
-}
-
-- (void)endUpdates {
-    [self.inputsTree endUpdates];
-}
-
 - (void)reexpandAll {
     for (NSString *uid in [_expanded copy])
         [self expandRecursiveByUID:uid];
 }
 
 - (void)addedDevice:(NJDevice *)device atIndex:(NSUInteger)idx {
+    [self.inputsTree beginUpdates];
     [self.inputsTree insertItemsAtIndexes:[[NSIndexSet alloc] initWithIndex:idx]
                                   inParent:nil
                              withAnimation:NSTableViewAnimationEffectFade];
     [self reexpandAll];
+    [self.inputsTree endUpdates];
     self.noDevicesNotice.hidden = YES;
 }
 
-- (void)removedDevice:(NJDevice *)device atIndex:(NSUInteger)idx {
+- (void)removedDeviceAtIndex:(NSUInteger)idx {
     BOOL anyDevices = !![self.delegate numberOfDevicesInDeviceList:self];
+    [self.inputsTree beginUpdates];
     [self.inputsTree removeItemsAtIndexes:[[NSIndexSet alloc] initWithIndex:idx]
                                   inParent:nil
                              withAnimation:NSTableViewAnimationEffectFade];
+    [self.inputsTree endUpdates];
     self.noDevicesNotice.hidden = anyDevices || !self.hidStoppedNotice.isHidden;
 }
 
@@ -163,11 +159,9 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn
     return ![self outlineView:outlineView isGroupItem:item];
 }
 
-- (NJInputPathElement *)selectedHandler {
+- (NJInput *)selectedHandler {
     NJInputPathElement *element = self.inputsTree.selectedItem;
-    return element.children ? nil : element;
+    return element.children ? nil : (NJInput *)element;
 }
 
-
-
 @end
index 760b41bac53546659cd28f346ef07b318e94cde0..44a9c43e1eb2819e20f050350d9b8de4434907ad 100644 (file)
     _manualMapping = oldMapping;
 }
 
+- (void)activateMappingForcibly:(NJMapping *)mapping {
+    NSLog(@"Switching to mapping %@.", mapping.name);
+    _currentMapping = mapping;
+    NSUInteger idx = [self indexOfMapping:_currentMapping];
+    [NSNotificationCenter.defaultCenter
+     postNotificationName:NJEventMappingChanged
+                  object:self
+                userInfo:@{ NJMappingKey : _currentMapping,
+                            NJMappingIndexKey: @(idx) }];
+}
+
 - (void)activateMapping:(NJMapping *)mapping {
     if (!mapping)
         mapping = _manualMapping;
     if (mapping == _currentMapping)
         return;
-    NSLog(@"Switching to mapping %@.", mapping.name);
     _manualMapping = mapping;
-    _currentMapping = mapping;
-    NSUInteger idx = [self indexOfMapping:_currentMapping];
-    [NSNotificationCenter.defaultCenter
-         postNotificationName:NJEventMappingChanged
-                       object:self
-                     userInfo:@{ NJMappingKey : _currentMapping,
-                                 NJMappingIndexKey: @(idx) }];
+    [self activateMappingForcibly:mapping];
 }
 
 - (void)save {
 - (void)mergeMapping:(NJMapping *)mapping intoMapping:(NJMapping *)existing {
     [existing mergeEntriesFrom:mapping];
     [self mappingsChanged];
-    if (existing == _currentMapping) {
-        // FIXME: Hack to trigger updates in the rest of the UI.
-        _currentMapping = nil;
-        NJMapping *manual = _manualMapping;
-        [self activateMapping:existing];
-        _manualMapping = manual;
-    }
+    if (existing == _currentMapping)
+        [self activateMappingForcibly:mapping];
 }
 
 - (void)renameMapping:(NJMapping *)mapping to:(NSString *)name {
     mapping.name = name;
     [self mappingsChanged];
-    if (mapping == _currentMapping) {
-        // FIXME: Hack to trigger updates in the rest of the UI.
-        _currentMapping = nil;
-        NJMapping *manual = _manualMapping;
-        [self activateMapping:mapping];
-        _manualMapping = manual;        
-    }
+    if (mapping == _currentMapping)
+        [self activateMappingForcibly:mapping];
 }
 
 - (void)addMapping:(NJMapping *)mapping {
index 3974e2e2132c16b696b14d092161257273164384..c18275fefa12dc2f2fbf170c059b98dc0dc91321 100644 (file)
@@ -11,7 +11,7 @@
 @class NJMappingsController;
 @class NJDeviceController;
 @class NJOutput;
-@class NJOutputMouseMove;
+@class NJInput;
 
 @interface NJOutputController : NSObject <NJKeyInputFieldDelegate> {
     IBOutlet NJKeyInputField *keyInput;
     IBOutlet NSTextField *title;
     IBOutlet NSPopUpButton *mappingPopup;
     IBOutlet NJMappingsController *mappingsController;
-    IBOutlet NJDeviceController *inputController;
     IBOutlet NSButton *smoothCheck;
     IBOutlet NSButton *unknownMapping;
 }
 
 @property (assign) BOOL enabled;
 
-- (void)loadCurrent;
+- (void)loadInput:(NJInput *)input;
 - (IBAction)radioChanged:(id)sender;
 - (IBAction)mdirChanged:(id)sender;
 - (IBAction)mbtnChanged:(id)sender;
index 5235837ff107e94544aff561ad1f8e86646c5e65..1567fee7507534ddced90980e439a0afba122ebf 100644 (file)
@@ -20,7 +20,9 @@
 #import "NJOutputMouseMove.h"
 #import "NJOutputMouseScroll.h"
 
-@implementation NJOutputController
+@implementation NJOutputController {
+    NJInput *_input;
+}
 
 - (id)init {
     if ((self = [super init])) {
 }
 
 - (NJOutput *)currentOutput {
-    return mappingsController.currentMapping[inputController.selectedInput];
+    return mappingsController.currentMapping[_input];
 }
 
 - (NJOutput *)makeOutput {
 
 - (void)commit {
     [self cleanUpInterface];
-    mappingsController.currentMapping[inputController.selectedInput] = [self makeOutput];
+    mappingsController.currentMapping[_input] = [self makeOutput];
     [mappingsController save];
 }
 
     [self cleanUpInterface];
 }
 
-- (void)loadCurrent {
-    [self loadOutput:self.currentOutput forInput:inputController.selectedInput];
+- (void)loadInput:(NJInput *)input {
+    _input = input;
+    [self loadOutput:self.currentOutput forInput:input];
 }
 
 - (void)focusKey {
 }
 
 - (void)mappingDidChange:(NSNotification *)note {
-    [self loadCurrent];
+    [self loadInput:_input];
 }
 
 @end
index 4a78c2b994e217ed64edcb343444d823f84b1dee..fa16792fc1418903c61f544cfca085007928b108 100644 (file)
@@ -46,7 +46,7 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>526</string>
+       <string>535</string>
        <key>LSApplicationCategoryType</key>
        <string>public.app-category.utilities</string>
        <key>NSHumanReadableCopyright</key>
index 7cd0972cabde9e08a8c6152eb2e3ccc2865e7380..bbb398e11be93adb0711ddd54827ca9828208d11 100644 (file)
@@ -1695,11 +1695,11 @@ aW5nLg</string>
                                </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
-                                               <string key="label">devicesViewController</string>
+                                               <string key="label">delegate</string>
                                                <reference key="source" ref="1007832501"/>
-                                               <reference key="destination" ref="647344717"/>
+                                               <reference key="destination" ref="207406104"/>
                                        </object>
-                                       <int key="connectionID">992</int>
+                                       <int key="connectionID">1029</int>
                                </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
@@ -1765,6 +1765,30 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">1024</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">dvc</string>
+                                               <reference key="source" ref="207406104"/>
+                                               <reference key="destination" ref="647344717"/>
+                                       </object>
+                                       <int key="connectionID">1025</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">deviceController</string>
+                                               <reference key="source" ref="207406104"/>
+                                               <reference key="destination" ref="1007832501"/>
+                                       </object>
+                                       <int key="connectionID">1026</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">outputController</string>
+                                               <reference key="source" ref="207406104"/>
+                                               <reference key="destination" ref="801536542"/>
+                                       </object>
+                                       <int key="connectionID">1027</int>
+                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBActionConnection" key="connection">
                                                <string key="label">performClick:</string>
@@ -1797,14 +1821,6 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">821</int>
                                </object>
-                               <object class="IBConnectionRecord">
-                                       <object class="IBOutletConnection" key="connection">
-                                               <string key="label">inputController</string>
-                                               <reference key="source" ref="801536542"/>
-                                               <reference key="destination" ref="1007832501"/>
-                                       </object>
-                                       <int key="connectionID">828</int>
-                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
                                                <string key="label">mouseDirSelect</string>
@@ -2085,14 +2101,6 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">969</int>
                                </object>
-                               <object class="IBConnectionRecord">
-                                       <object class="IBOutletConnection" key="connection">
-                                               <string key="label">delegate</string>
-                                               <reference key="source" ref="647344717"/>
-                                               <reference key="destination" ref="1007832501"/>
-                                       </object>
-                                       <int key="connectionID">984</int>
-                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
                                                <string key="label">hidStoppedNotice</string>
@@ -2117,6 +2125,14 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">989</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">delegate</string>
+                                               <reference key="source" ref="647344717"/>
+                                               <reference key="destination" ref="207406104"/>
+                                       </object>
+                                       <int key="connectionID">1028</int>
+                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
                                                <string key="label">view</string>
@@ -3328,7 +3344,7 @@ aW5nLg</string>
                        <nil key="activeLocalization"/>
                        <dictionary class="NSMutableDictionary" key="localizations"/>
                        <nil key="sourceID"/>
-                       <int key="maxID">1024</int>
+                       <int key="maxID">1029</int>
                </object>
                <object class="IBClassDescriber" key="IBDocument.Classes"/>
                <int key="IBDocument.localizationMode">0</int>