Split view management out of NJDeviceController. Right now this probably just makes...
[enjoyable.git] / Classes / NJDeviceViewController.m
diff --git a/Classes/NJDeviceViewController.m b/Classes/NJDeviceViewController.m
new file mode 100644 (file)
index 0000000..3d20e65
--- /dev/null
@@ -0,0 +1,181 @@
+//
+//  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