--- /dev/null
+//
+// NSOutlineView+ItemAccessors.h
+// Enjoyable
+//
+// Created by Joe Wreschnig on 3/16/13.
+//
+//
+
+#import <Cocoa/Cocoa.h>
+
+@interface NSOutlineView (ItemAccessors)
+
+- (void)selectItem:(id)item;
+- (id)selectedItem;
+
+@end
--- /dev/null
+//
+// NSOutlineView+ItemAccessors.m
+// Enjoyable
+//
+// Created by Joe Wreschnig on 3/16/13.
+//
+//
+
+#import "NSOutlineView+ItemAccessors.h"
+
+@implementation NSOutlineView (ItemAccessors)
+
+- (void)selectItem:(id)item {
+ NSInteger row = [self rowForItem:item];
+ if (row >= 0) {
+ [self selectRowIndexes:[[NSIndexSet alloc] initWithIndex:row]
+ byExtendingSelection:NO];
+ } else {
+ [self deselectAll:nil];
+ }
+}
+
+- (id)selectedItem {
+ return self.selectedRow >= 0 ? [self itemAtRow:self.selectedRow] : nil;
+}
+
+@end
return self;
}
+- (BOOL)isEqual:(id)object {
+ return [object isKindOfClass:NJDevice.class]
+ && [[(NJDevice *)object productName] isEqualToString:self.productName]
+ && [(NJDevice *)object index] == self.index;
+}
+
- (NSString *)name {
return [NSString stringWithFormat:@"%@ #%d", _productName, _index];
}
//
#import "NJHIDManager.h"
+#import "NJDeviceViewController.h"
@class NJDevice;
@class NJInput;
@class NJMappingsController;
@class NJOutputController;
+@class NJDeviceViewController;
-@interface NJDeviceController : NSObject <NSOutlineViewDataSource,
- NSOutlineViewDelegate,
+@interface NJDeviceController : NSObject <NJDeviceViewControllerDelegate,
NJHIDManagerDelegate> {
- IBOutlet NSOutlineView *outlineView;
IBOutlet NJOutputController *outputController;
IBOutlet NJMappingsController *mappingsController;
IBOutlet NSButton *simulatingEventsButton;
- IBOutlet NSView *connectDevicePrompt;
- IBOutlet NSView *hidSleepingPrompt;
+ IBOutlet NJDeviceViewController *devicesViewController;
}
@property (nonatomic, readonly) NJInput *selectedInput;
#import "NJOutput.h"
#import "NJOutputController.h"
#import "NJEvents.h"
+#import "NJDeviceViewController.h"
@implementation NJDeviceController {
NJHIDManager *_hidManager;
NSTimer *_continuousOutputsTick;
NSMutableArray *_continousOutputs;
NSMutableArray *_devices;
- NSMutableArray *_expanded;
}
-#define EXPANDED_MEMORY_MAX_SIZE 100
#define NSSTR(e) ((NSString *)CFSTR(e))
- (id)init {
_devices = [[NSMutableArray alloc] initWithCapacity:16];
_continousOutputs = [[NSMutableArray alloc] initWithCapacity:32];
- NSArray *expanded = [NSUserDefaults.standardUserDefaults objectForKey:@"expanded rows"];
- if (![expanded isKindOfClass:NSArray.class])
- expanded = @[];
- _expanded = [[NSMutableArray alloc] initWithCapacity:MAX(16, _expanded.count)];
- [_expanded addObjectsFromArray:expanded];
-
_hidManager = [[NJHIDManager alloc] initWithCriteria:@[
@{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_Joystick) },
]
delegate:self];
- [NSNotificationCenter.defaultCenter
- addObserver:self
- selector:@selector(startHid)
- name:NSApplicationDidFinishLaunchingNotification
- object:nil];
-
// The HID manager uses 5-10ms per second doing basically
// nothing if a noisy device is plugged in (the % of that
// spent in input_callback is negligible, so it's not
[_continuousOutputsTick invalidate];
}
-- (void)expandRecursive:(NJInputPathElement *)pathElement {
- if (pathElement) {
- [self expandRecursive:pathElement.parent];
- [outlineView expandItem:pathElement];
- }
-}
-
- (id)elementForUID:(NSString *)uid {
for (NJDevice *dev in _devices) {
id item = [dev elementForUID:uid];
return nil;
}
-- (void)expandRecursiveByUID:(NSString *)uid {
- [self expandRecursive:[self elementForUID:uid]];
-}
-
- (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;
- [self expandRecursive:handler];
- [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[outlineView rowForItem:handler]]
- byExtendingSelection: NO];
- if (!self.simulatingEvents)
- [outputController focusKey];
+ [devicesViewController expandAndSelectItem:handler];
+ [outputController focusKey];
}
- (void)hidManager:(NJHIDManager *)manager
}
}
-static int findAvailableIndex(NSArray *list, NJDevice *dev) {
- for (int index = 1; ; index++) {
- BOOL available = YES;
- for (NJDevice *used in list) {
- if ([used.productName isEqualToString:dev.productName]
- && used.index == index) {
+- (void)hidManager:(NJHIDManager *)manager deviceAdded:(IOHIDDeviceRef)device {
+ NJDevice *match = [[NJDevice alloc] initWithDevice:device];
+ match.index = 1;
+ BOOL available;
+ do {
+ available = YES;
+ for (NJDevice *used in _devices) {
+ if ([used isEqual:match]) {
+ match.index += 1;
available = NO;
- break;
}
}
- if (available)
- return index;
- }
-}
+ } while (!available);
-- (void)hidManager:(NJHIDManager *)manager deviceAdded:(IOHIDDeviceRef)device {
- NJDevice *match = [[NJDevice alloc] initWithDevice:device];
- match.index = findAvailableIndex(_devices, match);
[_devices addObject:match];
- [outlineView reloadData];
- [self reexpandAll];
- hidSleepingPrompt.hidden = YES;
- connectDevicePrompt.hidden = !!_devices.count;
+ [devicesViewController addedDevice:match atIndex:_devices.count - 1];
}
- (NJDevice *)findDeviceByRef:(IOHIDDeviceRef)device {
NJDevice *match = [self findDeviceByRef:device];
IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
if (match) {
- [_devices removeObject:match];
- [outlineView reloadData];
- connectDevicePrompt.hidden = !!_devices.count;
- hidSleepingPrompt.hidden = YES;
+ NSInteger idx = [_devices indexOfObjectIdenticalTo:match];
+ [_devices removeObjectAtIndex:idx];
+ [devicesViewController removedDevice:match atIndex:idx];
}
- if (_devices.count == 1)
- [outlineView expandItem:_devices[0]];
}
- (void)updateContinuousOutputs:(NSTimer *)timer {
// 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 (!outlineView.window.attachedSheet) {
+ if (!simulatingEventsButton.window.attachedSheet) {
[NSApplication.sharedApplication activateIgnoringOtherApps:YES];
- [outlineView.window makeKeyAndOrderFront:nil];
- [outlineView.window presentError:error
- modalForWindow:outlineView.window
- delegate:nil
- didPresentSelector:nil
- contextInfo:nil];
+ [simulatingEventsButton.window makeKeyAndOrderFront:nil];
+ [simulatingEventsButton.window presentError:error
+ modalForWindow:simulatingEventsButton.window
+ delegate:nil
+ didPresentSelector:nil
+ contextInfo:nil];
}
self.simulatingEvents = NO;
- if (manager.running)
- [self hidManagerDidStart:manager];
- else
- [self hidManagerDidStop:manager];
}
- (void)hidManagerDidStart:(NJHIDManager *)manager {
- hidSleepingPrompt.hidden = YES;
- connectDevicePrompt.hidden = !!_devices.count;
+ [devicesViewController hidStarted];
}
- (void)hidManagerDidStop:(NJHIDManager *)manager {
[_devices removeAllObjects];
- [outlineView reloadData];
- hidSleepingPrompt.hidden = NO;
- connectDevicePrompt.hidden = YES;
+ [devicesViewController hidStopped];
}
- (void)startHid {
}
- (NJInput *)selectedInput {
- NJInputPathElement *item = [outlineView itemAtRow:outlineView.selectedRow];
- return (NJInput *)((!item.children && item.parent) ? item : nil);
-}
-
-- (NSInteger)outlineView:(NSOutlineView *)outlineView
- numberOfChildrenOfItem:(NJInputPathElement *)item {
- return item ? item.children.count : _devices.count;
-}
-
-- (BOOL)outlineView:(NSOutlineView *)outlineView
- isItemExpandable:(NJInputPathElement *)item {
- return item ? [[item children] count] > 0: YES;
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView
- child:(NSInteger)index
- ofItem:(NJInputPathElement *)item {
- return item ? item.children[index] : _devices[index];
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView
-objectValueForTableColumn:(NSTableColumn *)tableColumn
- byItem:(NJInputPathElement *)item {
- return item ? item.name : @"root";
-}
-
-- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
- NJInputPathElement *item = [outlineView itemAtRow:outlineView.selectedRow];
- if (item)
- [NSUserDefaults.standardUserDefaults setObject:item.uid
- forKey:@"selected input"];
- [outputController loadCurrent];
-}
-
-- (BOOL)outlineView:(NSOutlineView *)outlineView
- isGroupItem:(NJInputPathElement *)item {
- return [item isKindOfClass:NJDevice.class];
-}
-
-- (BOOL)outlineView:(NSOutlineView *)outlineView_
- shouldSelectItem:(NJInputPathElement *)item {
- return ![self outlineView:outlineView_ isGroupItem:item];
-}
-
-- (void)outlineViewItemDidExpand:(NSNotification *)notification {
- NJInputPathElement *item = notification.userInfo[@"NSObject"];
- NSString *uid = item.uid;
- if (![_expanded containsObject:uid])
- [_expanded addObject:uid];
- while (_expanded.count > EXPANDED_MEMORY_MAX_SIZE)
- [_expanded removeObjectAtIndex:0];
- [NSUserDefaults.standardUserDefaults setObject:_expanded
- forKey:@"expanded rows"];
-}
-
-- (void)outlineViewItemDidCollapse:(NSNotification *)notification {
- NJInputPathElement *item = notification.userInfo[@"NSObject"];
- [_expanded removeObject:item.uid];
- [NSUserDefaults.standardUserDefaults setObject:_expanded
- forKey:@"expanded rows"];
+ return (NJInput *)devicesViewController.selectedHandler;
}
- (void)setSimulatingEvents:(BOOL)simulatingEvents {
}
}
-- (void)reexpandAll {
- for (NSString *uid in [_expanded copy])
- [self expandRecursiveByUID:uid];
- if (outlineView.selectedRow == -1) {
- NSString *selectedUid = [NSUserDefaults.standardUserDefaults objectForKey:@"selected input"];
- id item = [self elementForUID:selectedUid];
- NSInteger row = [outlineView rowForItem:item];
- if (row >= 0)
- [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
- }
-}
-
- (void)stopHidIfDisabled:(NSNotification *)application {
if (!self.simulatingEvents)
[self stopHid];
self.simulatingEvents = sender.state == NSOnState;
}
+- (void)deviceViewControllerDidSelectNothing:(NJDeviceViewController *)devices {
+ [outputController loadCurrent];
+}
+
+- (void)deviceViewController:(NJDeviceViewController *)devices
+ didSelectBranch:(NJInputPathElement *)handler {
+ [outputController loadCurrent];
+}
+
+- (void)deviceViewController:(NJDeviceViewController *)devices
+ didSelectHandler:(NJInputPathElement *)handler {
+ [outputController loadCurrent];
+}
+
+- (void)deviceViewController:(NJDeviceViewController *)devices
+ didSelectDevice:(NJInputPathElement *)device {
+ [outputController loadCurrent];
+}
+
@end
--- /dev/null
+//
+// NJDeviceViewController.h
+// Enjoyable
+//
+// Created by Joe Wreschnig on 3/16/13.
+//
+//
+
+@class NJDevice;
+@class NJInputPathElement;
+
+@protocol NJDeviceViewControllerDelegate;
+
+@interface NJDeviceViewController : NSObject <NSOutlineViewDataSource,
+ NSOutlineViewDelegate>
+
+@property (nonatomic, strong) IBOutlet NSOutlineView *inputsTree;
+@property (nonatomic, strong) IBOutlet NSView *noDevicesNotice;
+@property (nonatomic, strong) IBOutlet NSView *hidStoppedNotice;
+
+@property (nonatomic, weak) IBOutlet id <NJDeviceViewControllerDelegate> delegate;
+
+@property (nonatomic, copy) NSArray *devices;
+ // Assigning directly will trigger a full reload.
+
+- (void)addedDevice:(NJDevice *)device atIndex:(NSUInteger)idx;
+- (void)removedDevice:(NJDevice *)device atIndex:(NSUInteger)idx;
+ // But using these will animate nicely.
+
+- (void)hidStarted;
+- (void)hidStopped;
+
+- (void)expandAndSelectItem:(NJInputPathElement *)item;
+
+- (NJInputPathElement *)selectedHandler;
+
+@end
+
+@protocol NJDeviceViewControllerDelegate <NSObject>
+
+- (void)deviceViewController:(NJDeviceViewController *)devices
+ didSelectDevice:(NJInputPathElement *)device;
+- (void)deviceViewController:(NJDeviceViewController *)devices
+ didSelectBranch:(NJInputPathElement *)handler;
+- (void)deviceViewController:(NJDeviceViewController *)devices
+ didSelectHandler:(NJInputPathElement *)handler;
+- (void)deviceViewControllerDidSelectNothing:(NJDeviceViewController *)devices;
+
+@end
--- /dev/null
+//
+// NJDeviceViewController.m
+// Enjoyable
+//
+// Created by Joe Wreschnig on 3/16/13.
+//
+//
+
+#import "NJDeviceViewController.h"
+
+#import "NJInputPathElement.h"
+
+@implementation NJDeviceViewController {
+ NSMutableArray *_devices;
+ NSMutableArray *_expanded;
+}
+
+- (id)init {
+ if ((self = [super init])) {
+ NSArray *expanded = [NSUserDefaults.standardUserDefaults objectForKey:@"expanded rows"];
+ if (![expanded isKindOfClass:NSArray.class])
+ expanded = @[];
+ _expanded = [[NSMutableArray alloc] initWithCapacity:MAX(16, _expanded.count)];
+ [_expanded addObjectsFromArray:expanded];
+ _devices = [[NSMutableArray alloc] initWithCapacity:16];
+ }
+ return self;
+}
+
+- (void)expandRecursive:(NJInputPathElement *)pathElement {
+ if (pathElement) {
+ [self expandRecursive:pathElement.parent];
+ [self.inputsTree expandItem:pathElement];
+ }
+}
+
+- (id)elementForUID:(NSString *)uid {
+ for (NJInputPathElement *dev in _devices) {
+ id item = [dev elementForUID:uid];
+ if (item)
+ return item;
+ }
+ return nil;
+}
+
+- (void)expandRecursiveByUID:(NSString *)uid {
+ [self expandRecursive:[self elementForUID:uid]];
+}
+
+- (void)reexpandAll {
+ for (NSString *uid in [_expanded copy])
+ [self expandRecursiveByUID:uid];
+ if (self.inputsTree.selectedRow == -1) {
+ NSString *selectedUid = [NSUserDefaults.standardUserDefaults objectForKey:@"selected input"];
+ id item = [self elementForUID:selectedUid];
+ [self.inputsTree selectItem:item];
+ }
+}
+
+- (void)setDevices:(NSArray *)devices {
+ _devices = [devices mutableCopy];
+ id item = self.inputsTree.selectedItem;
+ [self.inputsTree selectItem:nil];
+ [self.inputsTree reloadData];
+ [self reexpandAll];
+ [self.inputsTree selectItem:item];
+ self.noDevicesNotice.hidden = self.devices.count || !self.hidStoppedNotice.isHidden;
+}
+
+- (void)addedDevice:(NJDevice *)device atIndex:(NSUInteger)idx {
+ [_devices insertObject:device atIndex:idx];
+ [self.inputsTree beginUpdates];
+ [self.inputsTree insertItemsAtIndexes:[[NSIndexSet alloc] initWithIndex:idx]
+ inParent:nil
+ withAnimation:NSTableViewAnimationSlideLeft];
+ [self reexpandAll];
+ [self.inputsTree endUpdates];
+ self.noDevicesNotice.hidden = YES;
+}
+
+- (void)removedDevice:(NJDevice *)device atIndex:(NSUInteger)idx {
+ [_devices removeObjectAtIndex:idx];
+ [self.inputsTree beginUpdates];
+ [self.inputsTree removeItemsAtIndexes:[[NSIndexSet alloc] initWithIndex:idx]
+ inParent:nil
+ withAnimation:NSTableViewAnimationSlideLeft];
+ [self.inputsTree endUpdates];
+ self.noDevicesNotice.hidden = self.devices.count || !self.hidStoppedNotice.isHidden;
+}
+
+- (void)hidStarted {
+ self.noDevicesNotice.hidden = !!self.devices.count;
+ self.hidStoppedNotice.hidden = YES;
+}
+
+- (void)hidStopped {
+ self.hidStoppedNotice.hidden = NO;
+ self.devices = @[];
+}
+
+- (void)expandAndSelectItem:(NJInputPathElement *)item {
+ [self expandRecursive:item];
+ NSInteger row = [self.inputsTree rowForItem:item];
+ if (row >= 0) {
+ [self.inputsTree selectRowIndexes:[[NSIndexSet alloc] initWithIndex:row]
+ byExtendingSelection:NO];
+ [self.inputsTree scrollRowToVisible:row];
+ }
+}
+
+- (NSInteger)outlineView:(NSOutlineView *)outlineView
+ numberOfChildrenOfItem:(NJInputPathElement *)item {
+ return item ? item.children.count : _devices.count;
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView
+ isItemExpandable:(NJInputPathElement *)item {
+ return item ? [[item children] count] > 0: YES;
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView
+ child:(NSInteger)index
+ ofItem:(NJInputPathElement *)item {
+ return item ? item.children[index] : _devices[index];
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView
+objectValueForTableColumn:(NSTableColumn *)tableColumn
+ byItem:(NJInputPathElement *)item {
+ return item ? item.name : @"root";
+}
+
+- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
+ NSOutlineView *outlineView = notification.object;
+ NJInputPathElement *item = outlineView.selectedItem;
+ if (item) {
+ [NSUserDefaults.standardUserDefaults setObject:item.uid
+ forKey:@"selected input"];
+ if (!item.children)
+ [self.delegate deviceViewController:self
+ didSelectHandler:item];
+ else if (!item.parent)
+ [self.delegate deviceViewController:self
+ didSelectDevice:item];
+ else
+ [self.delegate deviceViewController:self
+ didSelectBranch:item];
+ } else {
+ [self.delegate deviceViewControllerDidSelectNothing:self];
+ }
+}
+
+- (void)outlineViewItemDidExpand:(NSNotification *)notification {
+ NSString *uid = [notification.userInfo[@"NSObject"] uid];
+ if (![_expanded containsObject:uid])
+ [_expanded addObject:uid];
+
+}
+
+- (void)outlineViewItemDidCollapse:(NSNotification *)notification {
+ [_expanded removeObject:[notification.userInfo[@"NSObject"] uid]];
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView
+ isGroupItem:(NJInputPathElement *)item {
+ return !item.parent;
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView
+ shouldSelectItem:(NJInputPathElement *)item {
+ return ![self outlineView:outlineView isGroupItem:item];
+}
+
+- (NJInputPathElement *)selectedHandler {
+ NJInputPathElement *element = self.inputsTree.selectedItem;
+ return element.children ? nil : element;
+}
+
+
+
+@end
EE3D897C16EA806E00596D1F /* Status Menu Icon Disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897B16EA806E00596D1F /* Status Menu Icon Disabled@2x.png */; };
EE3D897F16EA817E00596D1F /* Status Menu Icon Disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897D16EA817E00596D1F /* Status Menu Icon Disabled.png */; };
EE3D898016EA817E00596D1F /* Status Menu Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897E16EA817E00596D1F /* Status Menu Icon.png */; };
+ EE52145C16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m in Sources */ = {isa = PBXBuildFile; fileRef = EE52145B16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m */; };
+ EE52145F16F404D500E3C574 /* NJDeviceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EE52145E16F404D500E3C574 /* NJDeviceViewController.m */; };
EE6A122E16E8F46300EDBD32 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = EE6A122D16E8F46300EDBD32 /* Icon.icns */; };
EE8455DD16F0E46B00F32A01 /* NSRunningApplication+LoginItem.m in Sources */ = {isa = PBXBuildFile; fileRef = EE8455DC16F0E46B00F32A01 /* NSRunningApplication+LoginItem.m */; };
EED4CE6E16ED692400C65AA8 /* NJMappingMenuController.m in Sources */ = {isa = PBXBuildFile; fileRef = EED4CE6D16ED692400C65AA8 /* NJMappingMenuController.m */; };
EE3D897B16EA806E00596D1F /* Status Menu Icon Disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon Disabled@2x.png"; path = "Resources/Status Menu Icon Disabled@2x.png"; sourceTree = "<group>"; };
EE3D897D16EA817E00596D1F /* Status Menu Icon Disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon Disabled.png"; path = "Resources/Status Menu Icon Disabled.png"; sourceTree = "<group>"; };
EE3D897E16EA817E00596D1F /* Status Menu Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon.png"; path = "Resources/Status Menu Icon.png"; sourceTree = "<group>"; };
+ EE52145A16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSOutlineView+ItemAccessors.h"; path = "Categories/NSOutlineView+ItemAccessors.h"; sourceTree = "<group>"; };
+ EE52145B16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSOutlineView+ItemAccessors.m"; path = "Categories/NSOutlineView+ItemAccessors.m"; sourceTree = "<group>"; };
+ EE52145D16F404D500E3C574 /* NJDeviceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NJDeviceViewController.h; path = Classes/NJDeviceViewController.h; sourceTree = "<group>"; };
+ EE52145E16F404D500E3C574 /* NJDeviceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NJDeviceViewController.m; path = Classes/NJDeviceViewController.m; sourceTree = "<group>"; };
EE6A122D16E8F46300EDBD32 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = "<group>"; };
EE8455DB16F0E46B00F32A01 /* NSRunningApplication+LoginItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSRunningApplication+LoginItem.h"; path = "Categories/NSRunningApplication+LoginItem.h"; sourceTree = "<group>"; };
EE8455DC16F0E46B00F32A01 /* NSRunningApplication+LoginItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSRunningApplication+LoginItem.m"; path = "Categories/NSRunningApplication+LoginItem.m"; sourceTree = "<group>"; };
EED4CE6D16ED692400C65AA8 /* NJMappingMenuController.m */,
EEE703DA16F089FE002FDD69 /* NJHIDManager.h */,
EEE703DB16F089FE002FDD69 /* NJHIDManager.m */,
+ EE52145D16F404D500E3C574 /* NJDeviceViewController.h */,
+ EE52145E16F404D500E3C574 /* NJDeviceViewController.m */,
);
name = Classes;
sourceTree = "<group>";
EEF17D3216E8E2E100D7DC4D /* NSView+FirstResponder.m */,
EEE73B1416EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.h */,
EEE73B1516EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m */,
+ EE52145A16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.h */,
+ EE52145B16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m */,
);
name = Categories;
sourceTree = "<group>";
EEE703DC16F089FE002FDD69 /* NJHIDManager.m in Sources */,
EEE703DE16F0B3F6002FDD69 /* NJInputPathElement.m in Sources */,
EE8455DD16F0E46B00F32A01 /* NSRunningApplication+LoginItem.m in Sources */,
+ EE52145C16F3E8BD00E3C574 /* NSOutlineView+ItemAccessors.m in Sources */,
+ EE52145F16F404D500E3C574 /* NJDeviceViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>306</string>
+ <string>328</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>NSHumanReadableCopyright</key>
#import "NSString+FixFilename.h"
#import "NSRunningApplication+NJPossibleNames.h"
#import "NSRunningApplication+LoginItem.h"
+#import "NSOutlineView+ItemAccessors.h"
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1080</int>
- <string key="IBDocument.SystemVersion">12C2034</string>
+ <string key="IBDocument.SystemVersion">12D78</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
- <string key="IBDocument.AppKitVersion">1187.34</string>
- <string key="IBDocument.HIToolboxVersion">625.00</string>
+ <string key="IBDocument.AppKitVersion">1187.37</string>
+ <string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">3084</string>
<nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMinSize">{664, 323}</string>
<object class="NSView" key="NSWindowView" id="177223957">
- <nil key="NSNextResponder"/>
+ <reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSCustomView" id="734312853">
<int key="NSvFlags">-2147483374</int>
<string key="NSFrame">{{20, 20}, {194, 283}}</string>
<reference key="NSSuperview" ref="734312853"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="471332453"/>
<string key="NSReuseIdentifierKey">_NS:22</string>
<bool key="NSEnabled">YES</bool>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{20, 20}, {194, 283}}</string>
<reference key="NSSuperview" ref="734312853"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="918286878"/>
<string key="NSReuseIdentifierKey">_NS:22</string>
<bool key="NSEnabled">YES</bool>
<array class="NSMutableArray" key="NSSubviews"/>
<string key="NSFrameSize">{232, 321}</string>
<reference key="NSSuperview" ref="698362889"/>
- <reference key="NSNextKeyView" ref="892486973"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1036252745"/>
<bool key="NSEnabled">YES</bool>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<bool key="NSControlAllowsExpansionToolTips">YES</bool>
</array>
<string key="NSFrame">{{1, 1}, {232, 321}}</string>
<reference key="NSSuperview" ref="364857164"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="365506042"/>
<reference key="NSDocView" ref="365506042"/>
<reference key="NSBGColor" ref="834857663"/>
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{1, 1}, {8, 298}}</string>
<reference key="NSSuperview" ref="364857164"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="12898323"/>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<reference key="NSTarget" ref="364857164"/>
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{-100, -100}, {473, 15}}</string>
<reference key="NSSuperview" ref="364857164"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="698362889"/>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSsFlags">1</int>
</array>
<string key="NSFrameSize">{234, 323}</string>
<reference key="NSSuperview" ref="734312853"/>
- <reference key="NSNextKeyView" ref="698362889"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="892486973"/>
<int key="NSsFlags">150034</int>
<reference key="NSVScroller" ref="1036252745"/>
<reference key="NSHScroller" ref="892486973"/>
</array>
<string key="NSFrameSize">{234, 323}</string>
<reference key="NSSuperview" ref="177223957"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="364857164"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">NSView</string>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{189, 117}, {224, 20}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="385416822"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{343, 31}, {70, 18}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="868379451">
<int key="NSvFlags">265</int>
<string key="NSFrame">{{189, 33}, {150, 20}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="792189805"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{191, 24}, {146, 16}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="20704797"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{189, 70}, {224, 24}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="921829691"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{191, 108}, {220, 16}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="125828224"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{191, 196}, {220, 23}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="194275224"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">NJKeyInputField</string>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{188, 153}, {226, 26}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="875916470"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="74311158">
<int key="NSvFlags">268</int>
<string key="NSFrame">{{24, 20}, {163, 250}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="57697638"/>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSNumRows">6</int>
<int key="NSvFlags">266</int>
<string key="NSFrame">{{9, 286}, {412, 17}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="497528019"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="853503577">
<int key="NSvFlags">10</int>
<string key="NSFrame">{{12, 276}, {406, 5}}</string>
<reference key="NSSuperview" ref="471332453"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="120408205"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
</array>
<string key="NSFrame">{{233, 0}, {431, 323}}</string>
<reference key="NSSuperview" ref="177223957"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="1016088174"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">NSView</string>
</object>
</array>
<string key="NSFrameSize">{664, 323}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="734312853"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<object class="NSCustomObject" id="665704974">
<string key="NSClassName">SUUpdater</string>
</object>
+ <object class="NSCustomObject" id="647344717">
+ <string key="NSClassName">NJDeviceViewController</string>
+ </object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
</object>
<int key="connectionID">826</int>
</object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
- <string key="label">outlineView</string>
- <reference key="source" ref="1007832501"/>
- <reference key="destination" ref="365506042"/>
- </object>
- <int key="connectionID">648</int>
- </object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">connectDevicePrompt</string>
</object>
<int key="connectionID">982</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">devicesViewController</string>
+ <reference key="source" ref="1007832501"/>
+ <reference key="destination" ref="647344717"/>
+ </object>
+ <int key="connectionID">992</int>
+ </object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">mappingsController</string>
<object class="IBOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="365506042"/>
- <reference key="destination" ref="1007832501"/>
+ <reference key="destination" ref="647344717"/>
</object>
- <int key="connectionID">647</int>
+ <int key="connectionID">990</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="365506042"/>
- <reference key="destination" ref="1007832501"/>
+ <reference key="destination" ref="647344717"/>
</object>
- <int key="connectionID">696</int>
+ <int key="connectionID">991</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
</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>
+ <reference key="source" ref="647344717"/>
+ <reference key="destination" ref="918286878"/>
+ </object>
+ <int key="connectionID">987</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">noDevicesNotice</string>
+ <reference key="source" ref="647344717"/>
+ <reference key="destination" ref="12898323"/>
+ </object>
+ <int key="connectionID">988</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">inputsTree</string>
+ <reference key="source" ref="647344717"/>
+ <reference key="destination" ref="365506042"/>
+ </object>
+ <int key="connectionID">989</int>
+ </object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<reference key="object" ref="543930440"/>
<reference key="parent" ref="918286878"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">983</int>
+ <reference key="object" ref="647344717"/>
+ <reference key="parent" ref="0"/>
+ </object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="970.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="974.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="975.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="983.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
- <int key="maxID">982</int>
+ <int key="maxID">992</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<string key="className">NJDeviceController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="actions">
- <string key="NS.key.0">translatingEventsChanged:</string>
+ <string key="NS.key.0">simulatingEventsChanged:</string>
<string key="NS.object.0">NSButton</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
- <string key="NS.key.0">translatingEventsChanged:</string>
+ <string key="NS.key.0">simulatingEventsChanged:</string>
<object class="IBActionInfo" key="NS.object.0">
- <string key="name">translatingEventsChanged:</string>
+ <string key="name">simulatingEventsChanged:</string>
<string key="candidateClassName">NSButton</string>
</object>
</object>
<dictionary class="NSMutableDictionary" key="outlets">
- <string key="connectDevicePrompt">NSView</string>
- <string key="hidSleepingPrompt">NSView</string>
+ <string key="devicesViewController">NJDeviceViewController</string>
<string key="mappingsController">NJMappingsController</string>
- <string key="outlineView">NSOutlineView</string>
<string key="outputController">NJOutputController</string>
- <string key="translatingEventsButton">NSButton</string>
+ <string key="simulatingEventsButton">NSButton</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
- <object class="IBToOneOutletInfo" key="connectDevicePrompt">
- <string key="name">connectDevicePrompt</string>
- <string key="candidateClassName">NSView</string>
- </object>
- <object class="IBToOneOutletInfo" key="hidSleepingPrompt">
- <string key="name">hidSleepingPrompt</string>
- <string key="candidateClassName">NSView</string>
+ <object class="IBToOneOutletInfo" key="devicesViewController">
+ <string key="name">devicesViewController</string>
+ <string key="candidateClassName">NJDeviceViewController</string>
</object>
<object class="IBToOneOutletInfo" key="mappingsController">
<string key="name">mappingsController</string>
<string key="candidateClassName">NJMappingsController</string>
</object>
- <object class="IBToOneOutletInfo" key="outlineView">
- <string key="name">outlineView</string>
- <string key="candidateClassName">NSOutlineView</string>
- </object>
<object class="IBToOneOutletInfo" key="outputController">
<string key="name">outputController</string>
<string key="candidateClassName">NJOutputController</string>
</object>
- <object class="IBToOneOutletInfo" key="translatingEventsButton">
- <string key="name">translatingEventsButton</string>
+ <object class="IBToOneOutletInfo" key="simulatingEventsButton">
+ <string key="name">simulatingEventsButton</string>
<string key="candidateClassName">NSButton</string>
</object>
</dictionary>
<string key="minorKey">./Classes/NJDeviceController.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NJDeviceViewController</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="delegate">id</string>
+ <string key="hidStoppedNotice">NSView</string>
+ <string key="inputsTree">NSOutlineView</string>
+ <string key="noDevicesNotice">NSView</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="delegate">
+ <string key="name">delegate</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="hidStoppedNotice">
+ <string key="name">hidStoppedNotice</string>
+ <string key="candidateClassName">NSView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="inputsTree">
+ <string key="name">inputsTree</string>
+ <string key="candidateClassName">NSOutlineView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="noDevicesNotice">
+ <string key="name">noDevicesNotice</string>
+ <string key="candidateClassName">NSView</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/NJDeviceViewController.h</string>
+ </object>
+ </object>
<object class="IBPartialClassDescription">
<string key="className">NJKeyInputField</string>
<string key="superclassName">NSControl</string>
<string key="superclassName">NSObject</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="delegate">id</string>
- <string key="eventTranslationToggle">NSMenuItem</string>
+ <string key="eventSimulationToggle">NSMenuItem</string>
<string key="menu">NSMenu</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="name">delegate</string>
<string key="candidateClassName">id</string>
</object>
- <object class="IBToOneOutletInfo" key="eventTranslationToggle">
- <string key="name">eventTranslationToggle</string>
+ <object class="IBToOneOutletInfo" key="eventSimulationToggle">
+ <string key="name">eventSimulationToggle</string>
<string key="candidateClassName">NSMenuItem</string>
</object>
<object class="IBToOneOutletInfo" key="menu">