Remember expanded rows between activations / device insertion.
[enjoyable.git] / Classes / NJDeviceController.m
index 2849838..a1e5868 100644 (file)
     NSTimer *_continuousOutputsTick;
     NSMutableArray *_continousOutputs;
     NSMutableArray *_devices;
+    NSMutableArray *_expanded;
 }
 
+#define EXPANDED_MEMORY_MAX_SIZE 100
+
 - (id)init {
     if ((self = [super 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];
+
         [NSNotificationCenter.defaultCenter
              addObserver:self
              selector:@selector(applicationDidFinishLaunching:)
     }
 }
 
+- (void)expandRecursiveByUID:(NSString *)uid {
+    for (NJDevice *dev in _devices) {
+        id item = [dev elementForUID:uid];
+        if (item)
+            [self expandRecursive:item];
+    }
+}
+
 - (void)addRunningOutput:(NJOutput *)output {
     // Axis events will trigger every small movement, don't keep
     // re-adding them or they trigger multiple times each time.
@@ -139,6 +157,7 @@ static int findAvailableIndex(NSArray *list, NJDevice *dev) {
     dev.index = findAvailableIndex(_devices, dev);
     [_devices addObject:dev];
     [outlineView reloadData];
+    [self reexpandAll];
     connectDevicePrompt.hidden = !!_devices.count;
 }
 
@@ -202,13 +221,13 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD
     IOHIDManagerSetDeviceMatchingMultiple(_hidManager, (__bridge CFArrayRef)criteria);
     IOReturn ret = IOHIDManagerOpen(_hidManager, kIOHIDOptionsTypeNone);
     if (ret != kIOReturnSuccess) {
-        [[NSAlert alertWithMessageText:@"Input devices are unavailable"
+        [[NSAlert alertWithMessageText:NSLocalizedString(@"input devices unavailable",
+                                                         @"error title when devices can't be read")
                          defaultButton:nil
                        alternateButton:nil
                            otherButton:nil
-             informativeTextWithFormat:@"Error 0x%08x occured trying to access your devices. "
-                                       @"Input may not be correctly detected or mapped.",
-                                       ret]
+             informativeTextWithFormat:NSLocalizedString(@"input error 0x%08x occurred",
+                                                         @"message containing IOReturn failure code when devices can't be read"), ret]
             beginSheetModalForWindow:outlineView.window
             modalDelegate:nil
             didEndSelector:nil
@@ -274,6 +293,24 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn
     return ![self outlineView:outlineView_ isGroupItem:item];
 }
 
+- (void)outlineViewItemDidExpand:(NSNotification *)notification {
+    id <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 {
+    id <NJInputPathElement> item = notification.userInfo[@"NSObject"];
+    [_expanded removeObject:item.uid];
+    [NSUserDefaults.standardUserDefaults setObject:_expanded
+                                            forKey:@"expanded rows"];
+}
+
 - (void)setTranslatingEvents:(BOOL)translatingEvents {
     if (translatingEvents != _translatingEvents) {
         _translatingEvents = translatingEvents;
@@ -292,6 +329,11 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn
     }
 }
 
+- (void)reexpandAll {
+    for (NSString *uid in [_expanded copy])
+        [self expandRecursiveByUID:uid];
+}
+
 - (void)closeHidIfDisabled:(NSNotification *)application {
     if (!self.translatingEvents)
         [self closeHid];