Fix a variety of issues with incorrect / unexpected / unfriendly first responder...
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Thu, 28 Feb 2013 23:32:16 +0000 (00:32 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Thu, 28 Feb 2013 23:32:16 +0000 (00:32 +0100)
ApplicationController.m
ConfigsController.m
English.lproj/MainMenu.xib
Enjoy.xcodeproj/project.pbxproj
Enjoy_Prefix.pch
JoystickController.m
KeyInputTextView.m
NSView+FirstResponder.h [new file with mode: 0644]
NSView+FirstResponder.m [new file with mode: 0644]
TargetController.h
TargetController.m

index 6a34916..dd38323 100644 (file)
@@ -63,6 +63,7 @@
         [dockMenuBase removeItemAtIndex:dockMenuBase.numberOfItems - 1];
     for (Config *config in self.configsController.configs)
         [dockMenuBase addItemWithTitle:config.name action:@selector(chooseConfig:) keyEquivalent:@""];
+    [_targetController refreshConfigs];
     [self configChanged];
 }
 
index 769fabd..b4db790 100644 (file)
@@ -48,9 +48,8 @@
         return;
     manualConfig = config;
     _currentConfig = config;
-    [targetController reset];
     [removeButton setEnabled:_configs[0] != config];
-    [targetController load];
+    [targetController loadCurrent];
     [(ApplicationController *)[[NSApplication sharedApplication] delegate] configChanged];
     [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:[_configs indexOfObject:config]] byExtendingSelection:NO];
 }
@@ -91,7 +90,6 @@
 
 - (void)tableView:(NSTableView *)view setObjectValue:(NSString *)obj forTableColumn:(NSTableColumn *)col row:(int)index {
     [(Config *)_configs[index] setName:obj];
-    [targetController refreshConfigsPreservingSelection:YES];
     [tableView reloadData];
     [(ApplicationController *)[[NSApplication sharedApplication] delegate] configsChanged];
 }
index ac82d63..d9cfe8e 100644 (file)
                                                                                        <int key="NSNumCols">1</int>
                                                                                        <array class="NSMutableArray" key="NSCells">
                                                                                                <object class="NSButtonCell" id="177186415">
-                                                                                                       <int key="NSCellFlags">-1543503872</int>
+                                                                                                       <int key="NSCellFlags">603979776</int>
                                                                                                        <int key="NSCellFlags2">0</int>
                                                                                                        <string key="NSContents">Do nothing</string>
                                                                                                        <reference key="NSSupport" ref="45863614"/>
@@ -1012,7 +1012,7 @@ ZSwgSW5jLiwgMjAwOQA</bytes>
                                                                                        </array>
                                                                                        <string key="NSCellSize">{201, 32}</string>
                                                                                        <string key="NSIntercellSpacing">{4, 2}</string>
-                                                                                       <int key="NSMatrixFlags">1151868928</int>
+                                                                                       <int key="NSMatrixFlags">1353195520</int>
                                                                                        <string key="NSCellClass">NSActionCell</string>
                                                                                        <object class="NSButtonCell" key="NSProtoCell" id="632642090">
                                                                                                <int key="NSCellFlags">603979776</int>
@@ -1064,7 +1064,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
                                                                                                <int key="NSPeriodicDelay">400</int>
                                                                                                <int key="NSPeriodicInterval">75</int>
                                                                                        </object>
-                                                                                       <reference key="NSSelectedCell" ref="177186415"/>
+                                                                                       <int key="NSSelectedRow">-1</int>
+                                                                                       <int key="NSSelectedCol">-1</int>
                                                                                        <object class="NSColor" key="NSBackgroundColor" id="473846075">
                                                                                                <int key="NSColorSpace">6</int>
                                                                                                <string key="NSCatalogName">System</string>
index 16e0380..642e5e2 100644 (file)
@@ -32,6 +32,7 @@
                D594BF830FAE9661007A85F2 /* ApplicationController.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BF820FAE9661007A85F2 /* ApplicationController.m */; };
                D5F809710FB093400006A4DE /* TargetConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = D5F809700FB093400006A4DE /* TargetConfig.m */; };
                D5F80A9D0FB0A2FF0006A4DE /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = D5617A080FAEAF8300928B3A /* icon.icns */; };
+               EE1D7C9216E01E7000B000EB /* NSView+FirstResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -85,6 +86,8 @@
                D594BF820FAE9661007A85F2 /* ApplicationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ApplicationController.m; sourceTree = "<group>"; };
                D5F8096F0FB093400006A4DE /* TargetConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TargetConfig.h; sourceTree = "<group>"; };
                D5F809700FB093400006A4DE /* TargetConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TargetConfig.m; sourceTree = "<group>"; };
+               EE1D7C9016E01E7000B000EB /* NSView+FirstResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSView+FirstResponder.h"; sourceTree = "<group>"; };
+               EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSView+FirstResponder.m"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                        children = (
                                32CA4F630368D1EE00C91783 /* Enjoy_Prefix.pch */,
                                29B97316FDCFA39411CA2CEA /* main.m */,
+                               EE1D7C9016E01E7000B000EB /* NSView+FirstResponder.h */,
+                               EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */,
                        );
                        name = "Other Sources";
                        sourceTree = "<group>";
                                8B7E476C15C314A200C588FA /* TargetMouseBtn.m in Sources */,
                                8BEFAD9C15C46BFF00823AEC /* TargetMouseScroll.m in Sources */,
                                8BEFADA015C476DC00823AEC /* TargetToggleMouseScope.m in Sources */,
+                               EE1D7C9216E01E7000B000EB /* NSView+FirstResponder.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index d6e96a6..1f44b2f 100644 (file)
@@ -7,3 +7,5 @@
 #endif
 
 #import <IOKit/hid/IOHIDLib.h>
+
+#import "NSView+FirstResponder.h"
index 84366ef..97ca74b 100644 (file)
@@ -127,7 +127,6 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD
     for (Target *target in [runningTargets copy]) {
         if (![target update:self]) {
             [runningTargets removeObject:target];
-            NSLog(@"Removing action, now running %lu.", runningTargets.count);
         }
     }
     if (!runningTargets.count) {
@@ -194,9 +193,8 @@ static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDD
     return [item name];
 }
 
-- (void)outlineViewSelectionDidChange: (NSNotification*) notification {
-    [targetController reset];
-    [targetController load];
+- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
+    [targetController loadCurrent];
 }
 
 @end
index 1bb7952..abff2c6 100644 (file)
@@ -25,6 +25,8 @@
 
 - (void)clear {
     self.vk = -1;
+    [targetController keyChanged];
+    [self resignIfFirstResponder];
 }
 
 - (BOOL)hasKey {
     return [super resignFirstResponder];
 }
 
-- (void)setBackgroundColor:(NSColor *)color {
-    [super setBackgroundColor:color];
-}
-
 - (void)setVk:(int)key {
     vk = key;
     [self setStringValue:[KeyInputTextView stringForKeyCode:key]];
-    if (self.hasKey)
-        [targetController keyChanged];
 }
 
 - (int)vk {
 - (void)keyDown:(NSEvent *)evt {
     if (!evt.isARepeat) {
         self.vk = evt.keyCode;
-        [self.window makeFirstResponder:nil];
+        [targetController keyChanged];
+        [self resignIfFirstResponder];
     }
 }
 
 - (void)flagsChanged:(NSEvent *)evt {
     self.vk = evt.keyCode;
-    [[self window] makeFirstResponder:nil];
+    [targetController keyChanged];
+    [self resignIfFirstResponder];
 }
 
 - (void)setEnabled:(BOOL)newEnabled {
     enabled = newEnabled;
 
-    if (!enabled && window.firstResponder == self)
-        [window makeFirstResponder:nil];
+    if (!enabled)
+        [self resignIfFirstResponder];
 }
 
 - (BOOL)enabled {
diff --git a/NSView+FirstResponder.h b/NSView+FirstResponder.h
new file mode 100644 (file)
index 0000000..9aee2e6
--- /dev/null
@@ -0,0 +1,15 @@
+//
+//  NSView+FirstResponder.h
+//  Enjoy
+//
+//  Created by Joe Wreschnig on 3/1/13.
+//
+//
+
+#import <Cocoa/Cocoa.h>
+
+@interface NSView (FirstResponder)
+
+- (BOOL)resignIfFirstResponder;
+
+@end
diff --git a/NSView+FirstResponder.m b/NSView+FirstResponder.m
new file mode 100644 (file)
index 0000000..817d399
--- /dev/null
@@ -0,0 +1,19 @@
+//
+//  NSView+FirstResponder.m
+//  Enjoy
+//
+//  Created by Joe Wreschnig on 3/1/13.
+//
+//
+
+#import "NSView+FirstResponder.h"
+
+@implementation NSView (FirstResponder)
+
+- (BOOL)resignIfFirstResponder {
+    if (self.window.firstResponder == self)
+        return [self.window makeFirstResponder:nil];
+    return NO;
+}
+
+@end
index 7e24cc4..9c9ee2c 100644 (file)
@@ -27,9 +27,8 @@
 @property (assign) BOOL enabled;
 
 - (void)keyChanged;
-- (void)load;
-- (void)reset;
-- (void)refreshConfigsPreservingSelection:(BOOL)preserve;
+- (void)loadCurrent;
+- (void)refreshConfigs;
 - (IBAction)configChosen:(id)sender;
 - (IBAction)radioChanged:(id)sender;
 - (IBAction)mdirChanged:(id)sender;
index 08bf149..a7dbd2c 100644 (file)
 
 @implementation TargetController
 
-- (IBAction)radioChanged:(id)sender {
-    NSInteger row, col;
-    [radioButtons getRow:&row column:&col ofCell:sender];
-    [[NSApplication sharedApplication].mainWindow makeFirstResponder:sender];
+- (void)cleanUpInterface {
+    NSInteger row = radioButtons.selectedRow;
     
-    if (row != 1)
+    if (row != 1) {
         keyInput.vk = -1;
+        [keyInput resignIfFirstResponder];
+    }
     
-    if (row != 2)
+    if (row != 2) {
         [configPopup selectItemAtIndex:-1];
-    else if (!configPopup.selectedItem)
+        [configPopup resignIfFirstResponder];
+    } else if (!configPopup.selectedItem)
         [configPopup selectItemAtIndex:0];
     
-    if (row != 3)
+    if (row != 3) {
         mouseDirSelect.selectedSegment = -1;
-    else if (mouseDirSelect.selectedSegment == -1)
+        [mouseDirSelect resignIfFirstResponder];
+    } else if (mouseDirSelect.selectedSegment == -1)
         mouseDirSelect.selectedSegment = 0;
     
-    if (row != 4)
+    if (row != 4) {
         mouseBtnSelect.selectedSegment = -1;
-    else if (mouseBtnSelect.selectedSegment == -1)
+        [mouseBtnSelect resignIfFirstResponder];
+    } else if (mouseBtnSelect.selectedSegment == -1)
         mouseBtnSelect.selectedSegment = 0;
     
-    if (row != 5)
+    if (row != 5) {
         scrollDirSelect.selectedSegment = -1;
-    else if (scrollDirSelect.selectedSegment == -1)
-        scrollDirSelect.selectedSegment = 0;
-    
+        [scrollDirSelect resignIfFirstResponder];
+    } else if (scrollDirSelect.selectedSegment == -1)
+        scrollDirSelect.selectedSegment = 0;    
+}
+
+- (IBAction)radioChanged:(NSView *)sender {
+    [sender.window makeFirstResponder:sender];
+    if (radioButtons.selectedRow == 1)
+        [keyInput.window makeFirstResponder:keyInput];
     [self commit];
 }
 
 - (void)keyChanged {
-    [radioButtons setState:1 atRow:1 column:0];
+    [radioButtons selectCellAtRow:1 column:0];
+    [radioButtons.window makeFirstResponder:radioButtons];
     [self commit];
 }
 
 - (void)configChosen:(id)sender {
-    [radioButtons setState:1 atRow:2 column:0];
+    [radioButtons selectCellAtRow:2 column:0];
+    [configPopup.window makeFirstResponder:configPopup];
     [self commit];
 }
 
-- (void)mdirChanged:(id)sender {
-    [radioButtons setState:1 atRow:3 column:0];
-    [[NSApplication sharedApplication].mainWindow makeFirstResponder:sender];
+- (void)mdirChanged:(NSView *)sender {
+    [radioButtons selectCellAtRow:3 column:0];
+    [sender.window makeFirstResponder:sender];
     [self commit];
 }
 
-- (void)mbtnChanged:(id)sender {
-    [radioButtons setState:1 atRow:4 column:0];
-    [[NSApplication sharedApplication].mainWindow makeFirstResponder:sender];
+- (void)mbtnChanged:(NSView *)sender {
+    [radioButtons selectCellAtRow:4 column:0];
+    [sender.window makeFirstResponder:sender];
     [self commit];
 }
 
-- (void)sdirChanged:(id)sender {
-    [radioButtons setState:1 atRow:5 column:0];
-    [[NSApplication sharedApplication].mainWindow makeFirstResponder:sender];
+- (void)sdirChanged:(NSView *)sender {
+    [radioButtons selectCellAtRow:5 column:0];
+    [sender.window makeFirstResponder:sender];
     [self commit];
 }
 
             break;
         case 2: {
             TargetConfig *c = [[TargetConfig alloc] init];
-            if (!configPopup.selectedItem)
-                [configPopup selectItemAtIndex:0];
             c.config = configsController.configs[configPopup.indexOfSelectedItem];
             return c;
         }
 }
 
 - (void)commit {
+    [self cleanUpInterface];
     configsController.currentConfig[joystickController.selectedAction] = [self makeTarget];
     [configsController save];
 }
 
-- (void)reset {
-    [keyInput clear];
-    [radioButtons setState:1 atRow:0 column:0];
-    [self refreshConfigsPreservingSelection:NO];
-}
-
 - (BOOL)enabled {
     return [radioButtons isEnabled];
 }
     [scrollDirSelect setEnabled:enabled];
 }
 
-- (void)load {
-    JSAction *act = joystickController.selectedAction;
-    if (!act) {
+- (void)loadTarget:(Target *)target forAction:(JSAction *)action {
+    if (!action) {
         self.enabled = NO;
         title.stringValue = @"";
-        return;
     } else {
         self.enabled = YES;
+        NSString *actFullName = action.name;
+        for (JSAction *cur = action.base; cur; cur = cur.base) {
+            actFullName = [[NSString alloc] initWithFormat:@"%@ > %@", cur.name, actFullName];
+        }
+        title.stringValue = [[NSString alloc] initWithFormat:@"%@ > %@", configsController.currentConfig.name, actFullName];
     }
-    
-    Target *target = [self currentTarget];
-    NSString *actFullName = act.name;
-    for (JSAction *cur = act.base; cur; cur = cur.base) {
-        actFullName = [[NSString alloc] initWithFormat:@"%@ > %@", cur.name, actFullName];
-    }
-    title.stringValue = [[NSString alloc] initWithFormat:@"%@ > %@", configsController.currentConfig.name, actFullName];
-    
+
     if ([target isKindOfClass:[TargetKeyboard class]]) {
-        [radioButtons setState:1 atRow:1 column:0];
+        [radioButtons selectCellAtRow:1 column:0];
         keyInput.vk = [(TargetKeyboard*)target vk];
     } else if ([target isKindOfClass:[TargetConfig class]]) {
-        [radioButtons setState:1 atRow:2 column:0];
+        [radioButtons selectCellAtRow:2 column:0];
         [configPopup selectItemAtIndex:[configsController.configs
                                         indexOfObject:[(TargetConfig *)target config]]];
     }
     else if ([target isKindOfClass:[TargetMouseMove class]]) {
-        [radioButtons setState:1 atRow:3 column:0];
+        [radioButtons selectCellAtRow:3 column:0];
         [mouseDirSelect setSelectedSegment:[(TargetMouseMove *)target axis]];
     }
     else if ([target isKindOfClass:[TargetMouseBtn class]]) {
-        [radioButtons setState:1 atRow:4 column:0];
+        [radioButtons selectCellAtRow:4 column:0];
         mouseBtnSelect.selectedSegment = [(TargetMouseBtn *)target button] == kCGMouseButtonLeft ? 0 : 1;
     }
     else if ([target isKindOfClass:[TargetMouseScroll class]]) {
-        [radioButtons setState:1 atRow:5 column:0];
+        [radioButtons selectCellAtRow:5 column:0];
         scrollDirSelect.selectedSegment = [(TargetMouseScroll *)target amount] > 0;
     }
     else if ([target isKindOfClass:[TargetToggleMouseScope class]]) {
-        [radioButtons setState:1 atRow:6 column:0];
+        [radioButtons selectCellAtRow:6 column:0];
     } else {
-        [radioButtons setState:1 atRow:0 column:0];
+        [radioButtons selectCellAtRow:self.enabled ? 0 : -1 column:0];
     }
+    [self cleanUpInterface];
+}
+
+- (void)loadCurrent {
+    [self loadTarget:[self currentTarget] forAction:joystickController.selectedAction];
 }
 
 - (void)focusKey {
-    Target *currentTarget = [self currentTarget];
-    if (!currentTarget || [currentTarget isKindOfClass:[TargetKeyboard class]])
-        [[[NSApplication sharedApplication] mainWindow] makeFirstResponder:keyInput];
+    if (radioButtons.selectedRow <= 1)
+        [keyInput.window makeFirstResponder:keyInput];
     else
-        [keyInput resignFirstResponder];
+        [keyInput resignIfFirstResponder];
 }
 
-- (void)refreshConfigsPreservingSelection:(BOOL)preserve  {
-    int initialIndex = [configPopup indexOfSelectedItem];
+- (void)refreshConfigs {
+    // TODO: This doesn't work when removing configs.
+    int initialIndex = configPopup.indexOfSelectedItem;
     [configPopup removeAllItems];
     for (Config *config in configsController.configs)
         [configPopup addItemWithTitle:config.name];
-    [configPopup selectItemAtIndex:preserve ? initialIndex : -1];
+    [configPopup selectItemAtIndex:initialIndex];
 }
 
 @end