From: Joe Wreschnig Date: Wed, 20 Mar 2013 20:01:34 +0000 (+0100) Subject: Correct some names. NJOutputController should be NJOutputViewController as it doesn... X-Git-Tag: version-1.1~7 X-Git-Url: https://git.yukkurigames.com/?a=commitdiff_plain;h=1d10a45acf54217e765614cd2b4667297c1f7083;p=enjoyable.git Correct some names. NJOutputController should be NJOutputViewController as it doesn't actually control the outputs. Xcode groups. --- diff --git a/Classes/EnjoyableApplicationDelegate.h b/Classes/EnjoyableApplicationDelegate.h index ddc6acf..d9408aa 100644 --- a/Classes/EnjoyableApplicationDelegate.h +++ b/Classes/EnjoyableApplicationDelegate.h @@ -6,12 +6,10 @@ // Copyright 2009 University of Otago. All rights reserved. // -@class NJMappingsController; - #import "NJMappingMenuController.h" #import "NJMappingsViewController.h" #import "NJDeviceViewController.h" -#import "NJOutputController.h" +#import "NJOutputViewController.h" #import "NJInputController.h" @interface EnjoyableApplicationDelegate : NSObject @property (nonatomic, strong) IBOutlet NJInputController *inputController; -@property (nonatomic, strong) IBOutlet NJOutputController *outputController; +@property (nonatomic, strong) IBOutlet NJOutputViewController *outputController; @property (nonatomic, strong) IBOutlet NJMappingsViewController *mvc; @property (nonatomic, strong) IBOutlet NJDeviceViewController *dvc; diff --git a/Classes/EnjoyableApplicationDelegate.m b/Classes/EnjoyableApplicationDelegate.m index 96aa8dd..83d0771 100644 --- a/Classes/EnjoyableApplicationDelegate.m +++ b/Classes/EnjoyableApplicationDelegate.m @@ -412,31 +412,31 @@ [self.outputController loadInput:dvc.selectedHandler]; } -- (void)deviceController:(NJInputController *)dc - didAddDevice:(NJDevice *)device { - [self.dvc addedDevice:device atIndex:dc.devices.count - 1]; +- (void)inputController:(NJInputController *)ic + didAddDevice:(NJDevice *)device { + [self.dvc addedDevice:device atIndex:ic.devices.count - 1]; } -- (void)deviceController:(NJInputController *)dc - didRemoveDeviceAtIndex:(NSInteger)idx { +- (void)inputController:(NJInputController *)ic + didRemoveDeviceAtIndex:(NSInteger)idx { [self.dvc removedDeviceAtIndex:idx]; } -- (void)deviceControllerDidStartHID:(NJInputController *)dc { +- (void)inputControllerDidStartHID:(NJInputController *)ic { [self.dvc hidStarted]; } -- (void)deviceControllerDidStopHID:(NJInputController *)dc { +- (void)inputControllerDidStopHID:(NJInputController *)ic { [self.dvc hidStopped]; } -- (void)deviceController:(NJInputController *)dc didInput:(NJInput *)input { +- (void)inputController:(NJInputController *)ic didInput:(NJInput *)input { [self.dvc expandAndSelectItem:input]; [self.outputController loadInput:input]; [self.outputController focusKey]; } -- (void)deviceController:(NJInputController *)dc didError:(NSError *)error { +- (void)inputController:(NJInputController *)ic didError:(NSError *)error { // Since the error shows the window, it can trigger another attempt // to re-open the HID manager, which will also probably fail and error, // so don't bother repeating ourselves. diff --git a/Classes/NJInputController.h b/Classes/NJInputController.h index 06852f2..a77a18d 100644 --- a/Classes/NJInputController.h +++ b/Classes/NJInputController.h @@ -1,9 +1,6 @@ // -// NJDeviceController.h -// Enjoy -// -// Created by Sam McCall on 4/05/09. -// Copyright 2009 University of Otago. All rights reserved. +// NJInputController.h +// Enjoyable // #import "NJHIDManager.h" @@ -48,11 +45,11 @@ @protocol NJInputControllerDelegate -- (void)deviceController:(NJInputController *)dc didAddDevice:(NJDevice *)device; -- (void)deviceController:(NJInputController *)dc didRemoveDeviceAtIndex:(NSInteger)idx; -- (void)deviceController:(NJInputController *)dc didInput:(NJInput *)input; -- (void)deviceControllerDidStartHID:(NJInputController *)dc; -- (void)deviceControllerDidStopHID:(NJInputController *)dc; -- (void)deviceController:(NJInputController *)dc didError:(NSError *)error; +- (void)inputController:(NJInputController *)ic didAddDevice:(NJDevice *)device; +- (void)inputController:(NJInputController *)ic didRemoveDeviceAtIndex:(NSInteger)idx; +- (void)inputController:(NJInputController *)ic didInput:(NJInput *)input; +- (void)inputControllerDidStartHID:(NJInputController *)ic; +- (void)inputControllerDidStopHID:(NJInputController *)ic; +- (void)inputController:(NJInputController *)ic didError:(NSError *)error; @end diff --git a/Classes/NJInputController.m b/Classes/NJInputController.m index 4ca33e1..9ff9d26 100644 --- a/Classes/NJInputController.m +++ b/Classes/NJInputController.m @@ -1,8 +1,6 @@ // -// NJDeviceController.m -// Enjoy -// -// Created by Sam McCall on 4/05/09. +// NJInputController.m +// Enjoyable // #import "NJInputController.h" @@ -108,7 +106,7 @@ if (!handler) return; - [self.delegate deviceController:self didInput:handler]; + [self.delegate inputController:self didInput:handler]; } - (void)hidManager:(NJHIDManager *)manager @@ -140,7 +138,7 @@ - (void)hidManager:(NJHIDManager *)manager deviceAdded:(IOHIDDeviceRef)device { NJDevice *match = [[NJDevice alloc] initWithDevice:device]; [self addDevice:match]; - [self.delegate deviceController:self didAddDevice:match]; + [self.delegate inputController:self didAddDevice:match]; } - (NJDevice *)findDeviceByRef:(IOHIDDeviceRef)device { @@ -155,7 +153,7 @@ if (match) { NSInteger idx = [_devices indexOfObjectIdenticalTo:match]; [_devices removeObjectAtIndex:idx]; - [self.delegate deviceController:self didRemoveDeviceAtIndex:idx]; + [self.delegate inputController:self didRemoveDeviceAtIndex:idx]; } } @@ -173,17 +171,17 @@ } - (void)hidManager:(NJHIDManager *)manager didError:(NSError *)error { - [self.delegate deviceController:self didError:error]; + [self.delegate inputController:self didError:error]; self.simulatingEvents = NO; } - (void)hidManagerDidStart:(NJHIDManager *)manager { - [self.delegate deviceControllerDidStartHID:self]; + [self.delegate inputControllerDidStartHID:self]; } - (void)hidManagerDidStop:(NJHIDManager *)manager { [_devices removeAllObjects]; - [self.delegate deviceControllerDidStopHID:self]; + [self.delegate inputControllerDidStopHID:self]; } - (void)startHid { diff --git a/Classes/NJOutputController.h b/Classes/NJOutputController.h deleted file mode 100644 index b22afdb..0000000 --- a/Classes/NJOutputController.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// NJOutputController.h -// Enjoy -// -// Created by Sam McCall on 5/05/09. -// Copyright 2009 University of Otago. All rights reserved. -// - -#import "NJKeyInputField.h" - -@class NJInputController; -@class NJOutput; -@class NJInput; - -@interface NJOutputController : NSObject { - IBOutlet NJKeyInputField *keyInput; - IBOutlet NSMatrix *radioButtons; - IBOutlet NSSegmentedControl *mouseDirSelect; - IBOutlet NSSlider *mouseSpeedSlider; - IBOutlet NSSegmentedControl *mouseBtnSelect; - IBOutlet NSSegmentedControl *scrollDirSelect; - IBOutlet NSSlider *scrollSpeedSlider; - IBOutlet NSTextField *title; - IBOutlet NSPopUpButton *mappingPopup; - IBOutlet NJInputController *inputController; - IBOutlet NSButton *smoothCheck; - IBOutlet NSButton *unknownMapping; -} - -@property (assign) BOOL enabled; - -- (void)loadInput:(NJInput *)input; -- (IBAction)radioChanged:(id)sender; -- (IBAction)mdirChanged:(id)sender; -- (IBAction)mbtnChanged:(id)sender; -- (IBAction)sdirChanged:(id)sender; -- (IBAction)mouseSpeedChanged:(id)sender; -- (IBAction)scrollSpeedChanged:(id)sender; -- (IBAction)scrollTypeChanged:(id)sender; - -- (void)focusKey; - -@end diff --git a/Classes/NJOutputController.m b/Classes/NJOutputController.m deleted file mode 100644 index f8ed2ea..0000000 --- a/Classes/NJOutputController.m +++ /dev/null @@ -1,307 +0,0 @@ -// -// NJOutputController.m -// Enjoy -// -// Created by Sam McCall on 5/05/09. -// - -#import "NJOutputController.h" - -#import "NJMapping.h" -#import "NJInput.h" -#import "NJEvents.h" -#import "NJInputController.h" -#import "NJKeyInputField.h" -#import "NJOutputMapping.h" -#import "NJOutputController.h" -#import "NJOutputKeyPress.h" -#import "NJOutputMouseButton.h" -#import "NJOutputMouseMove.h" -#import "NJOutputMouseScroll.h" - -@implementation NJOutputController { - NJInput *_input; -} - -- (id)init { - if ((self = [super init])) { - [NSNotificationCenter.defaultCenter - addObserver:self - selector:@selector(mappingListDidChange:) - name:NJEventMappingListChanged - object:nil]; - [NSNotificationCenter.defaultCenter - addObserver:self - selector:@selector(mappingDidChange:) - name:NJEventMappingChanged - object:nil]; - } - return self; -} - -- (void)dealloc { - [NSNotificationCenter.defaultCenter removeObserver:self]; -} - -- (void)cleanUpInterface { - NSInteger row = radioButtons.selectedRow; - - if (row != 1) { - keyInput.keyCode = NJKeyInputFieldEmpty; - [keyInput resignIfFirstResponder]; - } - - if (row != 2) { - [mappingPopup selectItemAtIndex:-1]; - [mappingPopup resignIfFirstResponder]; - unknownMapping.hidden = YES; - } - - if (row != 3) { - mouseDirSelect.selectedSegment = -1; - mouseSpeedSlider.floatValue = mouseSpeedSlider.minValue; - [mouseDirSelect resignIfFirstResponder]; - } else { - if (mouseDirSelect.selectedSegment == -1) - mouseDirSelect.selectedSegment = 0; - if (!mouseSpeedSlider.floatValue) - mouseSpeedSlider.floatValue = 10; - } - - if (row != 4) { - mouseBtnSelect.selectedSegment = -1; - [mouseBtnSelect resignIfFirstResponder]; - } else if (mouseBtnSelect.selectedSegment == -1) - mouseBtnSelect.selectedSegment = 0; - - if (row != 5) { - scrollDirSelect.selectedSegment = -1; - scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue; - smoothCheck.state = NSOffState; - [scrollDirSelect resignIfFirstResponder]; - [scrollSpeedSlider resignIfFirstResponder]; - [smoothCheck 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)keyInputField:(NJKeyInputField *)keyInput didChangeKey:(CGKeyCode)keyCode { - [radioButtons selectCellAtRow:1 column:0]; - [radioButtons.window makeFirstResponder:radioButtons]; - [self commit]; -} - -- (void)keyInputFieldDidClear:(NJKeyInputField *)keyInput { - [radioButtons selectCellAtRow:0 column:0]; - [self commit]; -} - -- (void)mappingChosen:(id)sender { - [radioButtons selectCellAtRow:2 column:0]; - [mappingPopup.window makeFirstResponder:mappingPopup]; - unknownMapping.hidden = YES; - [self commit]; -} - -- (void)mdirChanged:(NSView *)sender { - [radioButtons selectCellAtRow:3 column:0]; - [sender.window makeFirstResponder: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)sdirChanged:(NSView *)sender { - [radioButtons selectCellAtRow:5 column:0]; - [sender.window makeFirstResponder:sender]; - [self commit]; -} - -- (void)scrollSpeedChanged:(NSSlider *)sender { - [radioButtons selectCellAtRow:5 column:0]; - [sender.window makeFirstResponder:sender]; - [self commit]; -} - -- (IBAction)scrollTypeChanged:(NSButton *)sender { - [radioButtons selectCellAtRow:5 column:0]; - [sender.window makeFirstResponder:sender]; - if (sender.state == NSOnState) { - scrollSpeedSlider.floatValue = - scrollSpeedSlider.minValue + (scrollSpeedSlider.maxValue - scrollSpeedSlider.minValue) / 2; - scrollSpeedSlider.enabled = YES; - } else { - scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue; - scrollSpeedSlider.enabled = NO; - } - [self commit]; -} - -- (NJOutput *)currentOutput { - return inputController.currentMapping[_input]; -} - -- (NJOutput *)makeOutput { - switch (radioButtons.selectedRow) { - case 0: - return nil; - case 1: - if (keyInput.hasKeyCode) { - NJOutputKeyPress *k = [[NJOutputKeyPress alloc] init]; - k.keyCode = keyInput.keyCode; - return k; - } else { - return nil; - } - break; - case 2: { - NJOutputMapping *c = [[NJOutputMapping alloc] init]; - c.mapping = inputController.mappings[mappingPopup.indexOfSelectedItem]; - return c; - } - case 3: { - NJOutputMouseMove *mm = [[NJOutputMouseMove alloc] init]; - mm.axis = mouseDirSelect.selectedSegment; - mm.speed = mouseSpeedSlider.floatValue; - return mm; - } - case 4: { - NJOutputMouseButton *mb = [[NJOutputMouseButton alloc] init]; - mb.button = [mouseBtnSelect.cell tagForSegment:mouseBtnSelect.selectedSegment]; - return mb; - } - case 5: { - NJOutputMouseScroll *ms = [[NJOutputMouseScroll alloc] init]; - ms.direction = [scrollDirSelect.cell tagForSegment:scrollDirSelect.selectedSegment]; - ms.speed = scrollSpeedSlider.floatValue; - ms.smooth = smoothCheck.state == NSOnState; - return ms; - } - default: - return nil; - } -} - -- (void)commit { - [self cleanUpInterface]; - inputController.currentMapping[_input] = [self makeOutput]; - [inputController save]; -} - -- (BOOL)enabled { - return radioButtons.isEnabled; -} - -- (void)setEnabled:(BOOL)enabled { - radioButtons.enabled = enabled; - keyInput.enabled = enabled; - mappingPopup.enabled = enabled; - mouseDirSelect.enabled = enabled; - mouseSpeedSlider.enabled = enabled; - mouseBtnSelect.enabled = enabled; - scrollDirSelect.enabled = enabled; - smoothCheck.enabled = enabled; - scrollSpeedSlider.enabled = enabled && smoothCheck.state; - if (!enabled) - unknownMapping.hidden = YES; -} - -- (void)loadOutput:(NJOutput *)output forInput:(NJInput *)input { - if (!input) { - self.enabled = NO; - title.stringValue = @""; - } else { - self.enabled = YES; - NSString *inpFullName = input.name; - for (NJInputPathElement *cur = input.parent; cur; cur = cur.parent) { - inpFullName = [[NSString alloc] initWithFormat:@"%@ ▸ %@", cur.name, inpFullName]; - } - title.stringValue = inpFullName; - } - - if ([output isKindOfClass:NJOutputKeyPress.class]) { - [radioButtons selectCellAtRow:1 column:0]; - keyInput.keyCode = [(NJOutputKeyPress*)output keyCode]; - } else if ([output isKindOfClass:NJOutputMapping.class]) { - [radioButtons selectCellAtRow:2 column:0]; - NSMenuItem *item = [mappingPopup itemWithIdenticalRepresentedObject:[(NJOutputMapping *)output mapping]]; - [mappingPopup selectItem:item]; - unknownMapping.hidden = !!item; - unknownMapping.title = [(NJOutputMapping *)output mappingName]; - } - else if ([output isKindOfClass:NJOutputMouseMove.class]) { - [radioButtons selectCellAtRow:3 column:0]; - mouseDirSelect.selectedSegment = [(NJOutputMouseMove *)output axis]; - mouseSpeedSlider.floatValue = [(NJOutputMouseMove *)output speed]; - } - else if ([output isKindOfClass:NJOutputMouseButton.class]) { - [radioButtons selectCellAtRow:4 column:0]; - [mouseBtnSelect selectSegmentWithTag:[(NJOutputMouseButton *)output button]]; - } - else if ([output isKindOfClass:NJOutputMouseScroll.class]) { - [radioButtons selectCellAtRow:5 column:0]; - int direction = [(NJOutputMouseScroll *)output direction]; - float speed = [(NJOutputMouseScroll *)output speed]; - BOOL smooth = [(NJOutputMouseScroll *)output smooth]; - [scrollDirSelect selectSegmentWithTag:direction]; - scrollSpeedSlider.floatValue = speed; - smoothCheck.state = smooth ? NSOnState : NSOffState; - scrollSpeedSlider.enabled = smooth; - } else { - [radioButtons selectCellAtRow:self.enabled ? 0 : -1 column:0]; - } - [self cleanUpInterface]; -} - -- (void)loadInput:(NJInput *)input { - _input = input; - [self loadOutput:self.currentOutput forInput:input]; -} - -- (void)focusKey { - if (radioButtons.selectedRow <= 1) - [keyInput.window makeFirstResponder:keyInput]; - else - [keyInput resignIfFirstResponder]; -} - -- (void)mappingListDidChange:(NSNotification *)note { - NSArray *mappings = note.userInfo[NJMappingListKey]; - NJMapping *current = mappingPopup.selectedItem.representedObject; - [mappingPopup.menu removeAllItems]; - 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 selectItemWithIdenticalRepresentedObject:current]; -} - -- (void)mappingDidChange:(NSNotification *)note { - [self loadInput:_input]; -} - -@end diff --git a/Classes/NJOutputViewController.h b/Classes/NJOutputViewController.h new file mode 100644 index 0000000..2f50ef8 --- /dev/null +++ b/Classes/NJOutputViewController.h @@ -0,0 +1,43 @@ +// +// NJOutputController.h +// Enjoy +// +// Created by Sam McCall on 5/05/09. +// Copyright 2009 University of Otago. All rights reserved. +// + +#import "NJKeyInputField.h" + +@class NJInputController; +@class NJOutput; +@class NJInput; + +@interface NJOutputViewController : NSObject { + IBOutlet NJKeyInputField *keyInput; + IBOutlet NSMatrix *radioButtons; + IBOutlet NSSegmentedControl *mouseDirSelect; + IBOutlet NSSlider *mouseSpeedSlider; + IBOutlet NSSegmentedControl *mouseBtnSelect; + IBOutlet NSSegmentedControl *scrollDirSelect; + IBOutlet NSSlider *scrollSpeedSlider; + IBOutlet NSTextField *title; + IBOutlet NSPopUpButton *mappingPopup; + IBOutlet NJInputController *inputController; + IBOutlet NSButton *smoothCheck; + IBOutlet NSButton *unknownMapping; +} + +@property (assign) BOOL enabled; + +- (void)loadInput:(NJInput *)input; +- (IBAction)radioChanged:(id)sender; +- (IBAction)mdirChanged:(id)sender; +- (IBAction)mbtnChanged:(id)sender; +- (IBAction)sdirChanged:(id)sender; +- (IBAction)mouseSpeedChanged:(id)sender; +- (IBAction)scrollSpeedChanged:(id)sender; +- (IBAction)scrollTypeChanged:(id)sender; + +- (void)focusKey; + +@end diff --git a/Classes/NJOutputViewController.m b/Classes/NJOutputViewController.m new file mode 100644 index 0000000..a0f356f --- /dev/null +++ b/Classes/NJOutputViewController.m @@ -0,0 +1,307 @@ +// +// NJOutputController.m +// Enjoy +// +// Created by Sam McCall on 5/05/09. +// + +#import "NJOutputViewController.h" + +#import "NJMapping.h" +#import "NJInput.h" +#import "NJEvents.h" +#import "NJInputController.h" +#import "NJKeyInputField.h" +#import "NJOutputMapping.h" +#import "NJOutputViewController.h" +#import "NJOutputKeyPress.h" +#import "NJOutputMouseButton.h" +#import "NJOutputMouseMove.h" +#import "NJOutputMouseScroll.h" + +@implementation NJOutputViewController { + NJInput *_input; +} + +- (id)init { + if ((self = [super init])) { + [NSNotificationCenter.defaultCenter + addObserver:self + selector:@selector(mappingListDidChange:) + name:NJEventMappingListChanged + object:nil]; + [NSNotificationCenter.defaultCenter + addObserver:self + selector:@selector(mappingDidChange:) + name:NJEventMappingChanged + object:nil]; + } + return self; +} + +- (void)dealloc { + [NSNotificationCenter.defaultCenter removeObserver:self]; +} + +- (void)cleanUpInterface { + NSInteger row = radioButtons.selectedRow; + + if (row != 1) { + keyInput.keyCode = NJKeyInputFieldEmpty; + [keyInput resignIfFirstResponder]; + } + + if (row != 2) { + [mappingPopup selectItemAtIndex:-1]; + [mappingPopup resignIfFirstResponder]; + unknownMapping.hidden = YES; + } + + if (row != 3) { + mouseDirSelect.selectedSegment = -1; + mouseSpeedSlider.floatValue = mouseSpeedSlider.minValue; + [mouseDirSelect resignIfFirstResponder]; + } else { + if (mouseDirSelect.selectedSegment == -1) + mouseDirSelect.selectedSegment = 0; + if (!mouseSpeedSlider.floatValue) + mouseSpeedSlider.floatValue = 10; + } + + if (row != 4) { + mouseBtnSelect.selectedSegment = -1; + [mouseBtnSelect resignIfFirstResponder]; + } else if (mouseBtnSelect.selectedSegment == -1) + mouseBtnSelect.selectedSegment = 0; + + if (row != 5) { + scrollDirSelect.selectedSegment = -1; + scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue; + smoothCheck.state = NSOffState; + [scrollDirSelect resignIfFirstResponder]; + [scrollSpeedSlider resignIfFirstResponder]; + [smoothCheck 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)keyInputField:(NJKeyInputField *)keyInput didChangeKey:(CGKeyCode)keyCode { + [radioButtons selectCellAtRow:1 column:0]; + [radioButtons.window makeFirstResponder:radioButtons]; + [self commit]; +} + +- (void)keyInputFieldDidClear:(NJKeyInputField *)keyInput { + [radioButtons selectCellAtRow:0 column:0]; + [self commit]; +} + +- (void)mappingChosen:(id)sender { + [radioButtons selectCellAtRow:2 column:0]; + [mappingPopup.window makeFirstResponder:mappingPopup]; + unknownMapping.hidden = YES; + [self commit]; +} + +- (void)mdirChanged:(NSView *)sender { + [radioButtons selectCellAtRow:3 column:0]; + [sender.window makeFirstResponder: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)sdirChanged:(NSView *)sender { + [radioButtons selectCellAtRow:5 column:0]; + [sender.window makeFirstResponder:sender]; + [self commit]; +} + +- (void)scrollSpeedChanged:(NSSlider *)sender { + [radioButtons selectCellAtRow:5 column:0]; + [sender.window makeFirstResponder:sender]; + [self commit]; +} + +- (IBAction)scrollTypeChanged:(NSButton *)sender { + [radioButtons selectCellAtRow:5 column:0]; + [sender.window makeFirstResponder:sender]; + if (sender.state == NSOnState) { + scrollSpeedSlider.floatValue = + scrollSpeedSlider.minValue + (scrollSpeedSlider.maxValue - scrollSpeedSlider.minValue) / 2; + scrollSpeedSlider.enabled = YES; + } else { + scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue; + scrollSpeedSlider.enabled = NO; + } + [self commit]; +} + +- (NJOutput *)currentOutput { + return inputController.currentMapping[_input]; +} + +- (NJOutput *)makeOutput { + switch (radioButtons.selectedRow) { + case 0: + return nil; + case 1: + if (keyInput.hasKeyCode) { + NJOutputKeyPress *k = [[NJOutputKeyPress alloc] init]; + k.keyCode = keyInput.keyCode; + return k; + } else { + return nil; + } + break; + case 2: { + NJOutputMapping *c = [[NJOutputMapping alloc] init]; + c.mapping = inputController.mappings[mappingPopup.indexOfSelectedItem]; + return c; + } + case 3: { + NJOutputMouseMove *mm = [[NJOutputMouseMove alloc] init]; + mm.axis = mouseDirSelect.selectedSegment; + mm.speed = mouseSpeedSlider.floatValue; + return mm; + } + case 4: { + NJOutputMouseButton *mb = [[NJOutputMouseButton alloc] init]; + mb.button = [mouseBtnSelect.cell tagForSegment:mouseBtnSelect.selectedSegment]; + return mb; + } + case 5: { + NJOutputMouseScroll *ms = [[NJOutputMouseScroll alloc] init]; + ms.direction = [scrollDirSelect.cell tagForSegment:scrollDirSelect.selectedSegment]; + ms.speed = scrollSpeedSlider.floatValue; + ms.smooth = smoothCheck.state == NSOnState; + return ms; + } + default: + return nil; + } +} + +- (void)commit { + [self cleanUpInterface]; + inputController.currentMapping[_input] = [self makeOutput]; + [inputController save]; +} + +- (BOOL)enabled { + return radioButtons.isEnabled; +} + +- (void)setEnabled:(BOOL)enabled { + radioButtons.enabled = enabled; + keyInput.enabled = enabled; + mappingPopup.enabled = enabled; + mouseDirSelect.enabled = enabled; + mouseSpeedSlider.enabled = enabled; + mouseBtnSelect.enabled = enabled; + scrollDirSelect.enabled = enabled; + smoothCheck.enabled = enabled; + scrollSpeedSlider.enabled = enabled && smoothCheck.state; + if (!enabled) + unknownMapping.hidden = YES; +} + +- (void)loadOutput:(NJOutput *)output forInput:(NJInput *)input { + if (!input) { + self.enabled = NO; + title.stringValue = @""; + } else { + self.enabled = YES; + NSString *inpFullName = input.name; + for (NJInputPathElement *cur = input.parent; cur; cur = cur.parent) { + inpFullName = [[NSString alloc] initWithFormat:@"%@ ▸ %@", cur.name, inpFullName]; + } + title.stringValue = inpFullName; + } + + if ([output isKindOfClass:NJOutputKeyPress.class]) { + [radioButtons selectCellAtRow:1 column:0]; + keyInput.keyCode = [(NJOutputKeyPress*)output keyCode]; + } else if ([output isKindOfClass:NJOutputMapping.class]) { + [radioButtons selectCellAtRow:2 column:0]; + NSMenuItem *item = [mappingPopup itemWithIdenticalRepresentedObject:[(NJOutputMapping *)output mapping]]; + [mappingPopup selectItem:item]; + unknownMapping.hidden = !!item; + unknownMapping.title = [(NJOutputMapping *)output mappingName]; + } + else if ([output isKindOfClass:NJOutputMouseMove.class]) { + [radioButtons selectCellAtRow:3 column:0]; + mouseDirSelect.selectedSegment = [(NJOutputMouseMove *)output axis]; + mouseSpeedSlider.floatValue = [(NJOutputMouseMove *)output speed]; + } + else if ([output isKindOfClass:NJOutputMouseButton.class]) { + [radioButtons selectCellAtRow:4 column:0]; + [mouseBtnSelect selectSegmentWithTag:[(NJOutputMouseButton *)output button]]; + } + else if ([output isKindOfClass:NJOutputMouseScroll.class]) { + [radioButtons selectCellAtRow:5 column:0]; + int direction = [(NJOutputMouseScroll *)output direction]; + float speed = [(NJOutputMouseScroll *)output speed]; + BOOL smooth = [(NJOutputMouseScroll *)output smooth]; + [scrollDirSelect selectSegmentWithTag:direction]; + scrollSpeedSlider.floatValue = speed; + smoothCheck.state = smooth ? NSOnState : NSOffState; + scrollSpeedSlider.enabled = smooth; + } else { + [radioButtons selectCellAtRow:self.enabled ? 0 : -1 column:0]; + } + [self cleanUpInterface]; +} + +- (void)loadInput:(NJInput *)input { + _input = input; + [self loadOutput:self.currentOutput forInput:input]; +} + +- (void)focusKey { + if (radioButtons.selectedRow <= 1) + [keyInput.window makeFirstResponder:keyInput]; + else + [keyInput resignIfFirstResponder]; +} + +- (void)mappingListDidChange:(NSNotification *)note { + NSArray *mappings = note.userInfo[NJMappingListKey]; + NJMapping *current = mappingPopup.selectedItem.representedObject; + [mappingPopup.menu removeAllItems]; + 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 selectItemWithIdenticalRepresentedObject:current]; +} + +- (void)mappingDidChange:(NSNotification *)note { + [self loadInput:_input]; +} + +@end diff --git a/Enjoyable.xcodeproj/project.pbxproj b/Enjoyable.xcodeproj/project.pbxproj index c19007b..8e9a213 100644 --- a/Enjoyable.xcodeproj/project.pbxproj +++ b/Enjoyable.xcodeproj/project.pbxproj @@ -47,7 +47,7 @@ EEF17D6316E8E2EF00D7DC4D /* NJKeyInputField.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D4916E8E2EF00D7DC4D /* NJKeyInputField.m */; }; EEF17D6416E8E2EF00D7DC4D /* NJMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D4B16E8E2EF00D7DC4D /* NJMapping.m */; }; EEF17D6616E8E2EF00D7DC4D /* NJOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D4F16E8E2EF00D7DC4D /* NJOutput.m */; }; - EEF17D6716E8E2EF00D7DC4D /* NJOutputController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D5116E8E2EF00D7DC4D /* NJOutputController.m */; }; + EEF17D6716E8E2EF00D7DC4D /* NJOutputViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D5116E8E2EF00D7DC4D /* NJOutputViewController.m */; }; EEF17D6816E8E2EF00D7DC4D /* NJOutputKeyPress.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D5316E8E2EF00D7DC4D /* NJOutputKeyPress.m */; }; EEF17D6916E8E2EF00D7DC4D /* NJOutputMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D5516E8E2EF00D7DC4D /* NJOutputMapping.m */; }; EEF17D6A16E8E2EF00D7DC4D /* NJOutputMouseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF17D5716E8E2EF00D7DC4D /* NJOutputMouseButton.m */; }; @@ -140,8 +140,8 @@ EEF17D4B16E8E2EF00D7DC4D /* NJMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NJMapping.m; path = Classes/NJMapping.m; sourceTree = ""; }; EEF17D4E16E8E2EF00D7DC4D /* NJOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NJOutput.h; path = Classes/NJOutput.h; sourceTree = ""; }; EEF17D4F16E8E2EF00D7DC4D /* NJOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NJOutput.m; path = Classes/NJOutput.m; sourceTree = ""; }; - EEF17D5016E8E2EF00D7DC4D /* NJOutputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NJOutputController.h; path = Classes/NJOutputController.h; sourceTree = ""; }; - EEF17D5116E8E2EF00D7DC4D /* NJOutputController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NJOutputController.m; path = Classes/NJOutputController.m; sourceTree = ""; }; + EEF17D5016E8E2EF00D7DC4D /* NJOutputViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NJOutputViewController.h; path = Classes/NJOutputViewController.h; sourceTree = ""; }; + EEF17D5116E8E2EF00D7DC4D /* NJOutputViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NJOutputViewController.m; path = Classes/NJOutputViewController.m; sourceTree = ""; }; EEF17D5216E8E2EF00D7DC4D /* NJOutputKeyPress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NJOutputKeyPress.h; path = Classes/NJOutputKeyPress.h; sourceTree = ""; }; EEF17D5316E8E2EF00D7DC4D /* NJOutputKeyPress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NJOutputKeyPress.m; path = Classes/NJOutputKeyPress.m; sourceTree = ""; }; EEF17D5416E8E2EF00D7DC4D /* NJOutputMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NJOutputMapping.h; path = Classes/NJOutputMapping.h; sourceTree = ""; }; @@ -173,46 +173,10 @@ children = ( EEF17D3916E8E2EF00D7DC4D /* EnjoyableApplicationDelegate.h */, EEF17D3A16E8E2EF00D7DC4D /* EnjoyableApplicationDelegate.m */, - EEF17D3D16E8E2EF00D7DC4D /* NJInputController.h */, - EEF17D3E16E8E2EF00D7DC4D /* NJInputController.m */, - EEF17D5016E8E2EF00D7DC4D /* NJOutputController.h */, - EEF17D5116E8E2EF00D7DC4D /* NJOutputController.m */, - EEF17D4816E8E2EF00D7DC4D /* NJKeyInputField.h */, - EEF17D4916E8E2EF00D7DC4D /* NJKeyInputField.m */, - EEF17D4A16E8E2EF00D7DC4D /* NJMapping.h */, - EEF17D4B16E8E2EF00D7DC4D /* NJMapping.m */, - EEF17D4716E8E2EF00D7DC4D /* NJInputPathElement.h */, - EEE703DD16F0B3F6002FDD69 /* NJInputPathElement.m */, - EEF17D3B16E8E2EF00D7DC4D /* NJDevice.h */, - EEF17D3C16E8E2EF00D7DC4D /* NJDevice.m */, - EEF17D3F16E8E2EF00D7DC4D /* NJInput.h */, - EEF17D4016E8E2EF00D7DC4D /* NJInput.m */, - EEF17D4116E8E2EF00D7DC4D /* NJInputAnalog.h */, - EEF17D4216E8E2EF00D7DC4D /* NJInputAnalog.m */, - EEF17D4316E8E2EF00D7DC4D /* NJInputButton.h */, - EEF17D4416E8E2EF00D7DC4D /* NJInputButton.m */, - EEF17D4516E8E2EF00D7DC4D /* NJInputHat.h */, - EEF17D4616E8E2EF00D7DC4D /* NJInputHat.m */, - EEF17D4E16E8E2EF00D7DC4D /* NJOutput.h */, - EEF17D4F16E8E2EF00D7DC4D /* NJOutput.m */, - EEF17D5216E8E2EF00D7DC4D /* NJOutputKeyPress.h */, - EEF17D5316E8E2EF00D7DC4D /* NJOutputKeyPress.m */, - EEF17D5416E8E2EF00D7DC4D /* NJOutputMapping.h */, - EEF17D5516E8E2EF00D7DC4D /* NJOutputMapping.m */, - EEF17D5616E8E2EF00D7DC4D /* NJOutputMouseButton.h */, - EEF17D5716E8E2EF00D7DC4D /* NJOutputMouseButton.m */, - EEF17D5816E8E2EF00D7DC4D /* NJOutputMouseMove.h */, - EEF17D5916E8E2EF00D7DC4D /* NJOutputMouseMove.m */, - EEF17D5A16E8E2EF00D7DC4D /* NJOutputMouseScroll.h */, - EEF17D5B16E8E2EF00D7DC4D /* NJOutputMouseScroll.m */, - EED4CE6C16ED692400C65AA8 /* NJMappingMenuController.h */, - EED4CE6D16ED692400C65AA8 /* NJMappingMenuController.m */, - EEE703DA16F089FE002FDD69 /* NJHIDManager.h */, - EEE703DB16F089FE002FDD69 /* NJHIDManager.m */, - EE52145D16F404D500E3C574 /* NJDeviceViewController.h */, - EE52145E16F404D500E3C574 /* NJDeviceViewController.m */, - EE83ACEA16F545EA00083E94 /* NJMappingsViewController.h */, - EE83ACEB16F545EA00083E94 /* NJMappingsViewController.m */, + EEDB86A216FA4C42000E91C3 /* Input */, + EEDB86A316FA4C5C000E91C3 /* Output */, + EEDB86A516FA4CE4000E91C3 /* Views */, + EEDB86A416FA4CD1000E91C3 /* View Controllers */, ); name = Classes; sourceTree = ""; @@ -321,6 +285,74 @@ name = Categories; sourceTree = ""; }; + EEDB86A216FA4C42000E91C3 /* Input */ = { + isa = PBXGroup; + children = ( + EEE703DA16F089FE002FDD69 /* NJHIDManager.h */, + EEE703DB16F089FE002FDD69 /* NJHIDManager.m */, + EEF17D3D16E8E2EF00D7DC4D /* NJInputController.h */, + EEF17D3E16E8E2EF00D7DC4D /* NJInputController.m */, + EEF17D4716E8E2EF00D7DC4D /* NJInputPathElement.h */, + EEE703DD16F0B3F6002FDD69 /* NJInputPathElement.m */, + EEF17D4A16E8E2EF00D7DC4D /* NJMapping.h */, + EEF17D4B16E8E2EF00D7DC4D /* NJMapping.m */, + EEF17D3B16E8E2EF00D7DC4D /* NJDevice.h */, + EEF17D3C16E8E2EF00D7DC4D /* NJDevice.m */, + EEF17D3F16E8E2EF00D7DC4D /* NJInput.h */, + EEF17D4016E8E2EF00D7DC4D /* NJInput.m */, + EEF17D4116E8E2EF00D7DC4D /* NJInputAnalog.h */, + EEF17D4216E8E2EF00D7DC4D /* NJInputAnalog.m */, + EEF17D4316E8E2EF00D7DC4D /* NJInputButton.h */, + EEF17D4416E8E2EF00D7DC4D /* NJInputButton.m */, + EEF17D4516E8E2EF00D7DC4D /* NJInputHat.h */, + EEF17D4616E8E2EF00D7DC4D /* NJInputHat.m */, + ); + name = Input; + sourceTree = ""; + }; + EEDB86A316FA4C5C000E91C3 /* Output */ = { + isa = PBXGroup; + children = ( + EEF17D4E16E8E2EF00D7DC4D /* NJOutput.h */, + EEF17D4F16E8E2EF00D7DC4D /* NJOutput.m */, + EEF17D5216E8E2EF00D7DC4D /* NJOutputKeyPress.h */, + EEF17D5316E8E2EF00D7DC4D /* NJOutputKeyPress.m */, + EEF17D5416E8E2EF00D7DC4D /* NJOutputMapping.h */, + EEF17D5516E8E2EF00D7DC4D /* NJOutputMapping.m */, + EEF17D5616E8E2EF00D7DC4D /* NJOutputMouseButton.h */, + EEF17D5716E8E2EF00D7DC4D /* NJOutputMouseButton.m */, + EEF17D5816E8E2EF00D7DC4D /* NJOutputMouseMove.h */, + EEF17D5916E8E2EF00D7DC4D /* NJOutputMouseMove.m */, + EEF17D5A16E8E2EF00D7DC4D /* NJOutputMouseScroll.h */, + EEF17D5B16E8E2EF00D7DC4D /* NJOutputMouseScroll.m */, + ); + name = Output; + sourceTree = ""; + }; + EEDB86A416FA4CD1000E91C3 /* View Controllers */ = { + isa = PBXGroup; + children = ( + EEF17D5016E8E2EF00D7DC4D /* NJOutputViewController.h */, + EEF17D5116E8E2EF00D7DC4D /* NJOutputViewController.m */, + EED4CE6C16ED692400C65AA8 /* NJMappingMenuController.h */, + EED4CE6D16ED692400C65AA8 /* NJMappingMenuController.m */, + EE52145D16F404D500E3C574 /* NJDeviceViewController.h */, + EE52145E16F404D500E3C574 /* NJDeviceViewController.m */, + EE83ACEA16F545EA00083E94 /* NJMappingsViewController.h */, + EE83ACEB16F545EA00083E94 /* NJMappingsViewController.m */, + ); + name = "View Controllers"; + sourceTree = ""; + }; + EEDB86A516FA4CE4000E91C3 /* Views */ = { + isa = PBXGroup; + children = ( + EEF17D4816E8E2EF00D7DC4D /* NJKeyInputField.h */, + EEF17D4916E8E2EF00D7DC4D /* NJKeyInputField.m */, + ); + name = Views; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -445,7 +477,7 @@ EEF17D6316E8E2EF00D7DC4D /* NJKeyInputField.m in Sources */, EEF17D6416E8E2EF00D7DC4D /* NJMapping.m in Sources */, EEF17D6616E8E2EF00D7DC4D /* NJOutput.m in Sources */, - EEF17D6716E8E2EF00D7DC4D /* NJOutputController.m in Sources */, + EEF17D6716E8E2EF00D7DC4D /* NJOutputViewController.m in Sources */, EEF17D6816E8E2EF00D7DC4D /* NJOutputKeyPress.m in Sources */, EEF17D6916E8E2EF00D7DC4D /* NJOutputMapping.m in Sources */, EEF17D6A16E8E2EF00D7DC4D /* NJOutputMouseButton.m in Sources */, diff --git a/Info.plist b/Info.plist index 3114a8b..93dd01a 100644 --- a/Info.plist +++ b/Info.plist @@ -46,7 +46,7 @@ CFBundleSignature ???? CFBundleVersion - 559 + 565 LSApplicationCategoryType public.app-category.utilities NSHumanReadableCopyright diff --git a/Resources/English.lproj/MainMenu.xib b/Resources/English.lproj/MainMenu.xib index 0c068fc..44865f4 100644 --- a/Resources/English.lproj/MainMenu.xib +++ b/Resources/English.lproj/MainMenu.xib @@ -361,10 +361,9 @@ Enabled - + 268 {{7, 14}, {36, 25}} - _NS:9 YES @@ -410,10 +409,9 @@ Mapping Selector - + 268 {{0, 14}, {140, 25}} - _NS:9 YES @@ -490,7 +488,7 @@ {664, 323} - + 256 @@ -502,7 +500,6 @@ -2147483374 {{20, 20}, {194, 283}} - _NS:22 YES @@ -532,7 +529,6 @@ Lg 274 {{20, 20}, {194, 283}} - _NS:22 YES @@ -567,7 +563,6 @@ aW5nLg {232, 321} - YES NO @@ -663,7 +658,6 @@ aW5nLg {{1, 1}, {232, 321}} - @@ -674,7 +668,6 @@ aW5nLg -2147483392 {{1, 1}, {8, 298}} - NO @@ -686,7 +679,6 @@ aW5nLg -2147483392 {{-100, -100}, {473, 15}} - NO 1 @@ -697,7 +689,6 @@ aW5nLg {234, 323} - 150034 @@ -711,7 +702,6 @@ aW5nLg {234, 323} - _NS:9 NSView @@ -725,7 +715,6 @@ aW5nLg 268 {{197, 157}, {193, 21}} - _NS:9 YES @@ -750,7 +739,6 @@ aW5nLg 265 {{189, 117}, {224, 20}} - _NS:9 YES @@ -792,7 +780,6 @@ aW5nLg 268 {{343, 31}, {70, 18}} - _NS:9 YES @@ -823,7 +810,6 @@ aW5nLg 265 {{189, 33}, {150, 20}} - _NS:9 YES @@ -868,7 +854,6 @@ aW5nLg 265 {{191, 24}, {146, 16}} - _NS:9 YES @@ -894,7 +879,6 @@ aW5nLg 265 {{189, 70}, {224, 24}} - _NS:9 YES @@ -948,7 +932,6 @@ aW5nLg 265 {{191, 108}, {220, 16}} - _NS:9 YES @@ -974,7 +957,6 @@ aW5nLg 265 {{191, 196}, {220, 23}} - _NS:9 NJKeyInputField @@ -984,7 +966,6 @@ aW5nLg 265 {{188, 153}, {226, 26}} - YES @@ -1017,7 +998,6 @@ aW5nLg 268 {{24, 20}, {163, 250}} - NO 6 @@ -1148,7 +1128,6 @@ aW5nLg 266 {{9, 286}, {412, 17}} - YES @@ -1172,7 +1151,6 @@ aW5nLg 10 {{12, 276}, {406, 5}} - {0, 0} @@ -1199,15 +1177,12 @@ aW5nLg {{233, 0}, {431, 323}} - _NS:9 NSView {664, 323} - - {{0, 0}, {1440, 878}} @@ -1295,7 +1270,7 @@ aW5nLg NJInputController - NJOutputController + NJOutputViewController NJDeviceViewController @@ -1312,7 +1287,7 @@ aW5nLg YES - + 256 @@ -1328,7 +1303,6 @@ aW5nLg 256 {198, 198} - YES NO @@ -1386,7 +1360,6 @@ aW5nLg {{1, 1}, {198, 198}} - @@ -1397,7 +1370,6 @@ aW5nLg -2147483392 {{306, 1}, {15, 403}} - NO @@ -1409,7 +1381,6 @@ aW5nLg -2147483392 {{-100, -100}, {366, 16}} - NO 1 @@ -1420,7 +1391,6 @@ aW5nLg {{0, 20}, {200, 200}} - 150034 @@ -1436,7 +1406,6 @@ aW5nLg 268 {{66, -1}, {68, 23}} - _NS:22 YES @@ -1465,7 +1434,6 @@ aW5nLg 292 {{0, -1}, {34, 23}} - YES @@ -1492,7 +1460,6 @@ aW5nLg 292 {{166, -1}, {34, 23}} - YES 67108864 @@ -1514,7 +1481,6 @@ aW5nLg 292 {{133, -1}, {34, 23}} - YES @@ -1537,7 +1503,6 @@ aW5nLg 292 {{33, -1}, {34, 23}} - YES @@ -1561,8 +1526,6 @@ aW5nLg {200, 220} - - NSView