App delegate now controls communication between device / mapping controllers and...
[enjoyable.git] / Classes / NJDeviceViewController.m
1 //
2 // NJDeviceViewController.m
3 // Enjoyable
4 //
5 // Created by Joe Wreschnig on 3/16/13.
6 //
7 //
8
9 #import "NJDeviceViewController.h"
10
11 #import "NJInputPathElement.h"
12
13 @implementation NJDeviceViewController {
14 NSMutableArray *_expanded;
15 }
16
17 - (id)init {
18 if ((self = [super init])) {
19 NSArray *expanded = [NSUserDefaults.standardUserDefaults objectForKey:@"expanded rows"];
20 if (![expanded isKindOfClass:NSArray.class])
21 expanded = @[];
22 _expanded = [[NSMutableArray alloc] initWithCapacity:MAX(16, _expanded.count)];
23 [_expanded addObjectsFromArray:expanded];
24 }
25 return self;
26 }
27
28 - (void)expandRecursive:(NJInputPathElement *)pathElement {
29 if (pathElement) {
30 [self expandRecursive:pathElement.parent];
31 [self.inputsTree expandItem:pathElement];
32 }
33 }
34
35 - (void)expandRecursiveByUID:(NSString *)uid {
36 [self expandRecursive:[self.delegate deviceViewController:self elementForUID:uid]];
37 }
38
39 - (void)reexpandAll {
40 for (NSString *uid in [_expanded copy])
41 [self expandRecursiveByUID:uid];
42 if (self.inputsTree.selectedRow == -1) {
43 NSString *selectedUid = [NSUserDefaults.standardUserDefaults objectForKey:@"selected input"];
44 id item = [self.delegate deviceViewController:self elementForUID:selectedUid];
45 [self.inputsTree selectItem:item];
46 }
47 }
48
49 - (void)addedDevice:(NJDevice *)device atIndex:(NSUInteger)idx {
50 [self.inputsTree beginUpdates];
51 [self.inputsTree insertItemsAtIndexes:[[NSIndexSet alloc] initWithIndex:idx]
52 inParent:nil
53 withAnimation:NSTableViewAnimationEffectFade];
54 [self reexpandAll];
55 [self.inputsTree endUpdates];
56 self.noDevicesNotice.hidden = YES;
57 }
58
59 - (void)removedDeviceAtIndex:(NSUInteger)idx {
60 BOOL anyDevices = !![self.delegate numberOfDevicesInDeviceList:self];
61 [self.inputsTree beginUpdates];
62 [self.inputsTree removeItemsAtIndexes:[[NSIndexSet alloc] initWithIndex:idx]
63 inParent:nil
64 withAnimation:NSTableViewAnimationEffectFade];
65 [self.inputsTree endUpdates];
66 self.noDevicesNotice.hidden = anyDevices || !self.hidStoppedNotice.isHidden;
67 }
68
69 - (void)hidStarted {
70 self.noDevicesNotice.hidden = !![self.delegate numberOfDevicesInDeviceList:self];
71 self.hidStoppedNotice.hidden = YES;
72 }
73
74 - (void)hidStopped {
75 self.noDevicesNotice.hidden = YES;
76 self.hidStoppedNotice.hidden = NO;
77 [self.inputsTree reloadData];
78 }
79
80 - (void)expandAndSelectItem:(NJInputPathElement *)item {
81 [self expandRecursive:item];
82 NSInteger row = [self.inputsTree rowForItem:item];
83 if (row >= 0) {
84 [self.inputsTree selectRowIndexes:[[NSIndexSet alloc] initWithIndex:row]
85 byExtendingSelection:NO];
86 [self.inputsTree scrollRowToVisible:row];
87 }
88 }
89
90 - (NSInteger)outlineView:(NSOutlineView *)outlineView
91 numberOfChildrenOfItem:(NJInputPathElement *)item {
92 if (item)
93 return item.children.count;
94 else
95 return [self.delegate numberOfDevicesInDeviceList:self];
96
97 }
98
99 - (BOOL)outlineView:(NSOutlineView *)outlineView
100 isItemExpandable:(NJInputPathElement *)item {
101 return item ? item.children.count > 0: YES;
102 }
103
104 - (id)outlineView:(NSOutlineView *)outlineView
105 child:(NSInteger)index
106 ofItem:(NJInputPathElement *)item {
107 if (item)
108 return item.children[index];
109 else
110 return [self.delegate deviceViewController:self deviceForIndex:index];
111 }
112
113 - (id)outlineView:(NSOutlineView *)outlineView
114 objectValueForTableColumn:(NSTableColumn *)tableColumn
115 byItem:(NJInputPathElement *)item {
116 return item ? item.name : @"root";
117 }
118
119 - (void)outlineViewSelectionDidChange:(NSNotification *)notification {
120 NSOutlineView *outlineView = notification.object;
121 NJInputPathElement *item = outlineView.selectedItem;
122 if (item) {
123 [NSUserDefaults.standardUserDefaults setObject:item.uid
124 forKey:@"selected input"];
125 if (!item.children)
126 [self.delegate deviceViewController:self
127 didSelectHandler:item];
128 else if (!item.parent)
129 [self.delegate deviceViewController:self
130 didSelectDevice:item];
131 else
132 [self.delegate deviceViewController:self
133 didSelectBranch:item];
134 } else {
135 [self.delegate deviceViewControllerDidSelectNothing:self];
136 }
137 }
138
139 - (void)outlineViewItemDidExpand:(NSNotification *)notification {
140 NSString *uid = [notification.userInfo[@"NSObject"] uid];
141 if (![_expanded containsObject:uid]) {
142 [_expanded addObject:uid];
143 [NSUserDefaults.standardUserDefaults setObject:_expanded forKey:@"expanded rows"];
144 }
145 }
146
147 - (void)outlineViewItemDidCollapse:(NSNotification *)notification {
148 [_expanded removeObject:[notification.userInfo[@"NSObject"] uid]];
149 [NSUserDefaults.standardUserDefaults setObject:_expanded forKey:@"expanded rows"];
150 }
151
152 - (BOOL)outlineView:(NSOutlineView *)outlineView
153 isGroupItem:(NJInputPathElement *)item {
154 return !item.parent;
155 }
156
157 - (BOOL)outlineView:(NSOutlineView *)outlineView
158 shouldSelectItem:(NJInputPathElement *)item {
159 return ![self outlineView:outlineView isGroupItem:item];
160 }
161
162 - (NJInput *)selectedHandler {
163 NJInputPathElement *element = self.inputsTree.selectedItem;
164 return element.children ? nil : (NJInput *)element;
165 }
166
167 @end