Tweak some animations, clean up for preparation to move to app delegate.
[enjoyable.git] / Classes / NJMappingsViewController.m
1 //
2 // NJMappingsViewController.m
3 // Enjoyable
4 //
5 // Created by Joe Wreschnig on 3/17/13.
6 //
7 //
8
9 #import "NJMappingsViewController.h"
10
11 #import "NJMapping.h"
12
13 #define PB_ROW @"com.yukkurigames.Enjoyable.MappingRow"
14
15
16 @implementation NJMappingsViewController
17
18 - (void)awakeFromNib {
19 [self.mappingList registerForDraggedTypes:@[PB_ROW, NSURLPboardType]];
20 [self.mappingList setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];
21 }
22
23 - (IBAction)addClicked:(id)sender {
24 NJMapping *newMapping = [[NJMapping alloc] init];
25 [self.delegate mappingsViewController:self addMapping:newMapping];
26 }
27
28 - (IBAction)removeClicked:(id)sender {
29 [self.delegate mappingsViewController:self
30 removeMappingAtIndex:self.mappingList.selectedRow];
31 }
32
33 - (IBAction)moveUpClicked:(id)sender {
34 NSInteger fromIdx = self.mappingList.selectedRow;
35 NSInteger toIdx = fromIdx - 1;
36 [self.delegate mappingsViewController:self
37 moveMappingFromIndex:fromIdx
38 toIndex:toIdx];
39 [self.mappingList scrollRowToVisible:toIdx];
40 [self.mappingList selectRowIndexes:[[NSIndexSet alloc] initWithIndex:toIdx]
41 byExtendingSelection:NO];
42 }
43
44 - (IBAction)moveDownClicked:(id)sender {
45 NSInteger fromIdx = self.mappingList.selectedRow;
46 NSInteger toIdx = fromIdx + 1;
47 [self.delegate mappingsViewController:self
48 moveMappingFromIndex:fromIdx
49 toIndex:toIdx];
50 [self.mappingList scrollRowToVisible:toIdx];
51 [self.mappingList selectRowIndexes:[[NSIndexSet alloc] initWithIndex:toIdx]
52 byExtendingSelection:NO];
53 }
54
55 - (IBAction)mappingTriggerClicked:(id)sender {
56 [self.mappingListPopover showRelativeToRect:self.mappingListTrigger.bounds
57 ofView:self.mappingListTrigger
58 preferredEdge:NSMinXEdge];
59 self.mappingListTrigger.state = NSOnState;
60 }
61
62 - (void)popoverWillShow:(NSNotification *)notification {
63 self.mappingListTrigger.state = NSOnState;
64 }
65
66 - (void)popoverWillClose:(NSNotification *)notification {
67 self.mappingListTrigger.state = NSOffState;
68 }
69
70 - (void)addedMappingAtIndex:(NSInteger)index startEditing:(BOOL)startEditing {
71 [self.mappingList abortEditing];
72 [self.mappingList insertRowsAtIndexes:[[NSIndexSet alloc] initWithIndex:index]
73 withAnimation:startEditing ? 0 : NSTableViewAnimationSlideLeft];
74 if (startEditing) {
75 [self.mappingListTrigger performClick:self];
76 [self.mappingList editColumn:0 row:index withEvent:nil select:YES];
77 [self.mappingList scrollRowToVisible:index];
78 }
79 }
80
81 - (void)removedMappingAtIndex:(NSInteger)index {
82 [self.mappingList abortEditing];
83 [self.mappingList removeRowsAtIndexes:[[NSIndexSet alloc] initWithIndex:index]
84 withAnimation:NSTableViewAnimationEffectFade];
85 }
86
87 - (void)changedActiveMappingToIndex:(NSInteger)index {
88 NJMapping *mapping = [self.delegate mappingsViewController:self
89 mappingForIndex:index];
90 self.removeMapping.enabled = [self.delegate mappingsViewController:self
91 canRemoveMappingAtIndex:index];
92 self.moveUp.enabled = [self.delegate mappingsViewController:self
93 canMoveMappingFromIndex:index toIndex:index - 1];
94 self.moveDown.enabled = [self.delegate mappingsViewController:self
95 canMoveMappingFromIndex:index toIndex:index + 1];
96 self.mappingListTrigger.title = mapping.name;
97 [self.mappingList selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO];
98 [self.mappingList scrollRowToVisible:index];
99 [NSUserDefaults.standardUserDefaults setInteger:index forKey:@"selected"];
100
101 }
102
103 - (void)tableViewSelectionDidChange:(NSNotification *)note {
104 [self.mappingList abortEditing];
105 NSTableView *tableView = note.object;
106 [self.delegate mappingsViewController:self
107 choseMappingAtIndex:tableView.selectedRow];
108 }
109
110 - (id)tableView:(NSTableView *)view objectValueForTableColumn:(NSTableColumn *)column row:(NSInteger)index {
111 return [self.delegate mappingsViewController:self
112 mappingForIndex:index].name;
113 }
114
115 - (void)tableView:(NSTableView *)view
116 setObjectValue:(NSString *)obj
117 forTableColumn:(NSTableColumn *)col
118 row:(NSInteger)index {
119 NJMapping *mapping = [self.delegate mappingsViewController:self
120 mappingForIndex:index];
121 mapping.name = obj;
122 [self.delegate mappingsViewController:self editedMappingAtIndex:index];
123 }
124
125 - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
126 return [self.delegate numberOfMappings:self];
127 }
128
129 - (BOOL)tableView:(NSTableView *)tableView
130 acceptDrop:(id <NSDraggingInfo>)info
131 row:(NSInteger)row
132 dropOperation:(NSTableViewDropOperation)dropOperation {
133 NSPasteboard *pboard = [info draggingPasteboard];
134 if ([pboard.types containsObject:PB_ROW]) {
135 NSString *value = [pboard stringForType:PB_ROW];
136 NSInteger srcRow = [value intValue];
137 row -= srcRow < row;
138 [self.delegate mappingsViewController:self
139 moveMappingFromIndex:srcRow
140 toIndex:row];
141 return YES;
142 } else if ([pboard.types containsObject:NSURLPboardType]) {
143 NSURL *url = [NSURL URLFromPasteboard:pboard];
144 NSError *error;
145 if (![self.delegate mappingsViewController:self
146 importMappingFromURL:url
147 atIndex:row
148 error:&error]) {
149 [tableView presentError:error];
150 return NO;
151 } else {
152 return YES;
153 }
154 } else {
155 return NO;
156 }
157 }
158
159 - (NSDragOperation)tableView:(NSTableView *)tableView
160 validateDrop:(id <NSDraggingInfo>)info
161 proposedRow:(NSInteger)row
162 proposedDropOperation:(NSTableViewDropOperation)dropOperation {
163 NSPasteboard *pboard = [info draggingPasteboard];
164 if ([pboard.types containsObject:PB_ROW]) {
165 [tableView setDropRow:MAX(1, row) dropOperation:NSTableViewDropAbove];
166 return NSDragOperationMove;
167 } else if ([pboard.types containsObject:NSURLPboardType]) {
168 NSURL *url = [NSURL URLFromPasteboard:pboard];
169 if ([url.pathExtension isEqualToString:@"enjoyable"]) {
170 [tableView setDropRow:MAX(1, row) dropOperation:NSTableViewDropAbove];
171 return NSDragOperationCopy;
172 } else {
173 return NSDragOperationNone;
174 }
175 } else {
176 return NSDragOperationNone;
177 }
178 }
179
180 - (NSArray *)tableView:(NSTableView *)tableView
181 namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
182 forDraggedRowsWithIndexes:(NSIndexSet *)indexSet {
183 NJMapping *toSave = [self.delegate mappingsViewController:self
184 mappingForIndex:indexSet.firstIndex];
185 NSString *filename = [[toSave.name stringByFixingPathComponent]
186 stringByAppendingPathExtension:@"enjoyable"];
187 NSURL *dst = [dropDestination URLByAppendingPathComponent:filename];
188 dst = [NSFileManager.defaultManager generateUniqueURLWithBase:dst];
189 NSError *error;
190 if (![toSave writeToURL:dst error:&error]) {
191 [tableView presentError:error];
192 return @[];
193 } else {
194 return @[dst.lastPathComponent];
195 }
196 }
197
198 - (BOOL)tableView:(NSTableView *)tableView
199 writeRowsWithIndexes:(NSIndexSet *)rowIndexes
200 toPasteboard:(NSPasteboard *)pboard {
201 if (rowIndexes.count == 1 && rowIndexes.firstIndex != 0) {
202 [pboard declareTypes:@[PB_ROW, NSFilesPromisePboardType] owner:nil];
203 [pboard setString:@(rowIndexes.firstIndex).stringValue forType:PB_ROW];
204 [pboard setPropertyList:@[@"enjoyable"] forType:NSFilesPromisePboardType];
205 return YES;
206 } else if (rowIndexes.count == 1 && rowIndexes.firstIndex == 0) {
207 [pboard declareTypes:@[NSFilesPromisePboardType] owner:nil];
208 [pboard setPropertyList:@[@"enjoyable"] forType:NSFilesPromisePboardType];
209 return YES;
210 } else {
211 return NO;
212 }
213 }
214
215 - (void)reloadData {
216 [self.mappingList reloadData];
217 }
218
219 @end
220