Improved analog support for scrolling, and allow speed adjustments.
[enjoyable.git] / NJOutputController.m
index 8f942c6..f3eca24 100644 (file)
@@ -10,6 +10,7 @@
 #import "NJMappingsController.h"
 #import "NJMapping.h"
 #import "NJInput.h"
+#import "NJEvents.h"
 #import "NJDeviceController.h"
 #import "NJKeyInputField.h"
 #import "NJOutputMapping.h"
 
 @implementation NJOutputController
 
+- (id)init {
+    if ((self = [super init])) {
+        [NSNotificationCenter.defaultCenter
+            addObserver:self
+            selector:@selector(mappingListDidChange:)
+            name:NJEventMappingListChanged
+            object:nil];
+    }
+    return self;
+}
+
+- (void)dealloc {
+    [NSNotificationCenter.defaultCenter removeObserver:self];
+}
+
 - (void)cleanUpInterface {
     NSInteger row = radioButtons.selectedRow;
     
     if (row != 1) {
-        keyInput.keyCode = -1;
+        keyInput.keyCode = NJKeyInputFieldEmpty;
         [keyInput resignIfFirstResponder];
     }
     
     
     if (row != 3) {
         mouseDirSelect.selectedSegment = -1;
+        mouseSpeedSlider.floatValue = mouseSpeedSlider.minValue;
         [mouseDirSelect resignIfFirstResponder];
-    } else if (mouseDirSelect.selectedSegment == -1)
-        mouseDirSelect.selectedSegment = 0;
+    } else {
+        if (mouseDirSelect.selectedSegment == -1)
+            mouseDirSelect.selectedSegment = 0;
+        if (!mouseSpeedSlider.floatValue)
+            mouseSpeedSlider.floatValue = 4;
+    }
     
     if (row != 4) {
         mouseBtnSelect.selectedSegment = -1;
     
     if (row != 5) {
         scrollDirSelect.selectedSegment = -1;
+        scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue;
         [scrollDirSelect resignIfFirstResponder];
-    } else if (scrollDirSelect.selectedSegment == -1)
-        scrollDirSelect.selectedSegment = 0;    
+    } else {
+        if (scrollDirSelect.selectedSegment == -1)
+            scrollDirSelect.selectedSegment = 0;
+        if (scrollDirSelect.selectedSegment < 2
+            && !scrollSpeedSlider.floatValue)
+            scrollSpeedSlider.floatValue = 15.f;
+        else if (scrollDirSelect.selectedSegment >= 2
+                 && scrollSpeedSlider.floatValue)
+            scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue;
+    }
+        
 }
 
 - (IBAction)radioChanged:(NSView *)sender {
     [self commit];
 }
 
+- (void)mouseSpeedChanged:(NSSlider *)sender {
+    [radioButtons selectCellAtRow:3 column:0];
+    [sender.window makeFirstResponder:sender];
+    [self commit];
+}
+
 - (void)mbtnChanged:(NSView *)sender {
     [radioButtons selectCellAtRow:4 column:0];
     [sender.window makeFirstResponder:sender];
     [self commit];
 }
 
+- (void)scrollSpeedChanged:(NSSlider *)sender {
+    [radioButtons selectCellAtRow:5 column:0];
+    [sender.window makeFirstResponder:sender];
+    if (!sender.floatValue && scrollDirSelect.selectedSegment < 2)
+        scrollDirSelect.selectedSegment += 2;
+    else if (sender.floatValue && scrollDirSelect.selectedSegment >= 2)
+        scrollDirSelect.selectedSegment -= 2;
+    [self commit];
+}
+
 - (NJOutput *)currentOutput {
     return mappingsController.currentMapping[inputController.selectedInput];
 }
         case 3: {
             NJOutputMouseMove *mm = [[NJOutputMouseMove alloc] init];
             mm.axis = mouseDirSelect.selectedSegment;
+            mm.speed = mouseSpeedSlider.floatValue;
             return mm;
         }
         case 4: {
         }
         case 5: {
             NJOutputMouseScroll *ms = [[NJOutputMouseScroll alloc] init];
-            ms.amount = scrollDirSelect.selectedSegment ? 1 : -1;
+            ms.direction = (scrollDirSelect.selectedSegment & 1) ? 1 : -1;
+            ms.speed = scrollDirSelect.selectedSegment < 2
+                ? scrollSpeedSlider.floatValue
+                : 0.f;
             return ms;
         }
         case 6: {
     [keyInput setEnabled:enabled];
     [mappingPopup setEnabled:enabled];
     [mouseDirSelect setEnabled:enabled];
+    [mouseSpeedSlider setEnabled:enabled];
     [mouseBtnSelect setEnabled:enabled];
     [scrollDirSelect setEnabled:enabled];
 }
         for (id <NJInputPathElement> cur = input.base; cur; cur = cur.base) {
             inpFullName = [[NSString alloc] initWithFormat:@"%@ > %@", cur.name, inpFullName];
         }
-        title.stringValue = [[NSString alloc] initWithFormat:@"%@ > %@", mappingsController.currentMapping.name, inpFullName];
+        title.stringValue = inpFullName;
     }
 
     if ([output isKindOfClass:NJOutputKeyPress.class]) {
         keyInput.keyCode = [(NJOutputKeyPress*)output vk];
     } else if ([output isKindOfClass:NJOutputMapping.class]) {
         [radioButtons selectCellAtRow:2 column:0];
-        NSUInteger idx = [mappingsController.mappings
-                          indexOfObject:[(NJOutputMapping *)output mapping]];
-        if (idx == NSNotFound) {
+        NSMenuItem *item = [mappingPopup itemWithRepresentedObject:[(NJOutputMapping *)output mapping]];
+        [mappingPopup selectItem:item];
+        if (!item)
             [radioButtons selectCellAtRow:self.enabled ? 0 : -1 column:0];
-            [mappingPopup selectItemAtIndex:-1];
-        } else
-            [mappingPopup selectItemAtIndex:idx];
     }
     else if ([output isKindOfClass:NJOutputMouseMove.class]) {
         [radioButtons selectCellAtRow:3 column:0];
-        [mouseDirSelect setSelectedSegment:[(NJOutputMouseMove *)output axis]];
+        mouseDirSelect.selectedSegment = [(NJOutputMouseMove *)output axis];
+        mouseSpeedSlider.floatValue = [(NJOutputMouseMove *)output speed];
     }
     else if ([output isKindOfClass:NJOutputMouseButton.class]) {
         [radioButtons selectCellAtRow:4 column:0];
     }
     else if ([output isKindOfClass:NJOutputMouseScroll.class]) {
         [radioButtons selectCellAtRow:5 column:0];
-        scrollDirSelect.selectedSegment = [(NJOutputMouseScroll *)output amount] > 0;
+        int direction = [(NJOutputMouseScroll *)output direction];
+        float speed = [(NJOutputMouseScroll *)output speed];
+        scrollDirSelect.selectedSegment = (direction > 0) + !speed * 2;
+        scrollSpeedSlider.floatValue = speed;
     }
     else if ([output isKindOfClass:NJOutputSwitchMouseMode.class]) {
         [radioButtons selectCellAtRow:6 column:0];
         [keyInput resignIfFirstResponder];
 }
 
-- (void)refreshMappings {
-    NSInteger initialIndex = mappingPopup.indexOfSelectedItem;
+- (void)mappingListDidChange:(NSNotification *)note {
+    NSArray *mappings = note.object;
+    NJMapping *current = mappingPopup.selectedItem.representedObject;
     [mappingPopup.menu removeAllItems];
-    for (NJMapping *mapping in mappingsController) {
+    for (NJMapping *mapping in mappings) {
         NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:mapping.name
                                                       action:@selector(mappingChosen:)
                                                keyEquivalent:@""];
         item.target = self;
+        item.representedObject = mapping;
         [mappingPopup.menu addItem:item];
     }
-    [mappingPopup selectItemAtIndex:initialIndex];
+    [mappingPopup selectItemWithRepresentedObject:current];
 }
 
 @end