2 // NJOutputController.m
5 // Created by Sam McCall on 5/05/09.
8 #import "NJOutputController.h"
10 #import "NJMappingsController.h"
14 #import "NJDeviceController.h"
15 #import "NJKeyInputField.h"
16 #import "NJOutputMapping.h"
17 #import "NJOutputController.h"
18 #import "NJOutputKeyPress.h"
19 #import "NJOutputMouseButton.h"
20 #import "NJOutputMouseMove.h"
21 #import "NJOutputMouseScroll.h"
23 @implementation NJOutputController
26 if ((self = [super init])) {
27 [NSNotificationCenter.defaultCenter
29 selector:@selector(mappingListDidChange:)
30 name:NJEventMappingListChanged
32 [NSNotificationCenter.defaultCenter
34 selector:@selector(mappingDidChange:)
35 name:NJEventMappingChanged
42 [NSNotificationCenter.defaultCenter removeObserver:self];
45 - (void)cleanUpInterface {
46 NSInteger row = radioButtons.selectedRow;
49 keyInput.keyCode = NJKeyInputFieldEmpty;
50 [keyInput resignIfFirstResponder];
54 [mappingPopup selectItemAtIndex:-1];
55 [mappingPopup resignIfFirstResponder];
56 unknownMapping.hidden = YES;
60 mouseDirSelect.selectedSegment = -1;
61 mouseSpeedSlider.floatValue = mouseSpeedSlider.minValue;
62 [mouseDirSelect resignIfFirstResponder];
64 if (mouseDirSelect.selectedSegment == -1)
65 mouseDirSelect.selectedSegment = 0;
66 if (!mouseSpeedSlider.floatValue)
67 mouseSpeedSlider.floatValue = 10;
71 mouseBtnSelect.selectedSegment = -1;
72 [mouseBtnSelect resignIfFirstResponder];
73 } else if (mouseBtnSelect.selectedSegment == -1)
74 mouseBtnSelect.selectedSegment = 0;
77 scrollDirSelect.selectedSegment = -1;
78 scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue;
79 smoothCheck.state = NSOffState;
80 [scrollDirSelect resignIfFirstResponder];
81 [scrollSpeedSlider resignIfFirstResponder];
82 [smoothCheck resignIfFirstResponder];
84 if (scrollDirSelect.selectedSegment == -1)
85 scrollDirSelect.selectedSegment = 0;
90 - (IBAction)radioChanged:(NSView *)sender {
91 [sender.window makeFirstResponder:sender];
92 if (radioButtons.selectedRow == 1)
93 [keyInput.window makeFirstResponder:keyInput];
97 - (void)keyInputField:(NJKeyInputField *)keyInput didChangeKey:(CGKeyCode)keyCode {
98 [radioButtons selectCellAtRow:1 column:0];
99 [radioButtons.window makeFirstResponder:radioButtons];
103 - (void)keyInputFieldDidClear:(NJKeyInputField *)keyInput {
104 [radioButtons selectCellAtRow:0 column:0];
108 - (void)mappingChosen:(id)sender {
109 [radioButtons selectCellAtRow:2 column:0];
110 [mappingPopup.window makeFirstResponder:mappingPopup];
111 unknownMapping.hidden = YES;
115 - (void)mdirChanged:(NSView *)sender {
116 [radioButtons selectCellAtRow:3 column:0];
117 [sender.window makeFirstResponder:sender];
121 - (void)mouseSpeedChanged:(NSSlider *)sender {
122 [radioButtons selectCellAtRow:3 column:0];
123 [sender.window makeFirstResponder:sender];
127 - (void)mbtnChanged:(NSView *)sender {
128 [radioButtons selectCellAtRow:4 column:0];
129 [sender.window makeFirstResponder:sender];
133 - (void)sdirChanged:(NSView *)sender {
134 [radioButtons selectCellAtRow:5 column:0];
135 [sender.window makeFirstResponder:sender];
139 - (void)scrollSpeedChanged:(NSSlider *)sender {
140 [radioButtons selectCellAtRow:5 column:0];
141 [sender.window makeFirstResponder:sender];
145 - (IBAction)scrollTypeChanged:(NSButton *)sender {
146 [radioButtons selectCellAtRow:5 column:0];
147 [sender.window makeFirstResponder:sender];
148 if (sender.state == NSOnState) {
149 scrollSpeedSlider.floatValue =
150 scrollSpeedSlider.minValue + (scrollSpeedSlider.maxValue - scrollSpeedSlider.minValue) / 2;
151 scrollSpeedSlider.enabled = YES;
153 scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue;
154 scrollSpeedSlider.enabled = NO;
159 - (NJOutput *)currentOutput {
160 return mappingsController.currentMapping[inputController.selectedInput];
163 - (NJOutput *)makeOutput {
164 switch (radioButtons.selectedRow) {
168 if (keyInput.hasKeyCode) {
169 NJOutputKeyPress *k = [[NJOutputKeyPress alloc] init];
170 k.keyCode = keyInput.keyCode;
177 NJOutputMapping *c = [[NJOutputMapping alloc] init];
178 c.mapping = mappingsController[mappingPopup.indexOfSelectedItem];
182 NJOutputMouseMove *mm = [[NJOutputMouseMove alloc] init];
183 mm.axis = mouseDirSelect.selectedSegment;
184 mm.speed = mouseSpeedSlider.floatValue;
188 NJOutputMouseButton *mb = [[NJOutputMouseButton alloc] init];
189 mb.button = [mouseBtnSelect.cell tagForSegment:mouseBtnSelect.selectedSegment];
193 NJOutputMouseScroll *ms = [[NJOutputMouseScroll alloc] init];
194 ms.direction = [scrollDirSelect.cell tagForSegment:scrollDirSelect.selectedSegment];
195 ms.speed = scrollSpeedSlider.floatValue;
196 ms.smooth = smoothCheck.state == NSOnState;
205 [self cleanUpInterface];
206 mappingsController.currentMapping[inputController.selectedInput] = [self makeOutput];
207 [mappingsController save];
211 return radioButtons.isEnabled;
214 - (void)setEnabled:(BOOL)enabled {
215 radioButtons.enabled = enabled;
216 keyInput.enabled = enabled;
217 mappingPopup.enabled = enabled;
218 mouseDirSelect.enabled = enabled;
219 mouseSpeedSlider.enabled = enabled;
220 mouseBtnSelect.enabled = enabled;
221 scrollDirSelect.enabled = enabled;
222 smoothCheck.enabled = enabled;
223 scrollSpeedSlider.enabled = enabled && smoothCheck.state;
225 unknownMapping.hidden = YES;
228 - (void)loadOutput:(NJOutput *)output forInput:(NJInput *)input {
231 title.stringValue = @"";
234 NSString *inpFullName = input.name;
235 for (NJInputPathElement *cur = input.parent; cur; cur = cur.parent) {
236 inpFullName = [[NSString alloc] initWithFormat:@"%@ ▸ %@", cur.name, inpFullName];
238 title.stringValue = inpFullName;
241 if ([output isKindOfClass:NJOutputKeyPress.class]) {
242 [radioButtons selectCellAtRow:1 column:0];
243 keyInput.keyCode = [(NJOutputKeyPress*)output keyCode];
244 } else if ([output isKindOfClass:NJOutputMapping.class]) {
245 [radioButtons selectCellAtRow:2 column:0];
246 NSMenuItem *item = [mappingPopup itemWithRepresentedObject:[(NJOutputMapping *)output mapping]];
247 [mappingPopup selectItem:item];
248 unknownMapping.hidden = !!item;
249 unknownMapping.title = [(NJOutputMapping *)output mappingName];
251 else if ([output isKindOfClass:NJOutputMouseMove.class]) {
252 [radioButtons selectCellAtRow:3 column:0];
253 mouseDirSelect.selectedSegment = [(NJOutputMouseMove *)output axis];
254 mouseSpeedSlider.floatValue = [(NJOutputMouseMove *)output speed];
256 else if ([output isKindOfClass:NJOutputMouseButton.class]) {
257 [radioButtons selectCellAtRow:4 column:0];
258 [mouseBtnSelect selectSegmentWithTag:[(NJOutputMouseButton *)output button]];
260 else if ([output isKindOfClass:NJOutputMouseScroll.class]) {
261 [radioButtons selectCellAtRow:5 column:0];
262 int direction = [(NJOutputMouseScroll *)output direction];
263 float speed = [(NJOutputMouseScroll *)output speed];
264 BOOL smooth = [(NJOutputMouseScroll *)output smooth];
265 [scrollDirSelect selectSegmentWithTag:direction];
266 scrollSpeedSlider.floatValue = speed;
267 smoothCheck.state = smooth ? NSOnState : NSOffState;
268 scrollSpeedSlider.enabled = smooth;
270 [radioButtons selectCellAtRow:self.enabled ? 0 : -1 column:0];
272 [self cleanUpInterface];
275 - (void)loadCurrent {
276 [self loadOutput:self.currentOutput forInput:inputController.selectedInput];
280 if (radioButtons.selectedRow <= 1)
281 [keyInput.window makeFirstResponder:keyInput];
283 [keyInput resignIfFirstResponder];
286 - (void)mappingListDidChange:(NSNotification *)note {
287 NSArray *mappings = note.userInfo[NJMappingListKey];
288 NJMapping *current = mappingPopup.selectedItem.representedObject;
289 [mappingPopup.menu removeAllItems];
290 for (NJMapping *mapping in mappings) {
291 NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:mapping.name
292 action:@selector(mappingChosen:)
295 item.representedObject = mapping;
296 [mappingPopup.menu addItem:item];
298 [mappingPopup selectItemWithRepresentedObject:current];
301 - (void)mappingDidChange:(NSNotification *)note {