From a2cc76128896f61d5f5cc4039c0dcbb1b6cdff23 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Thu, 7 Mar 2013 00:47:17 +0100 Subject: [PATCH] Drag-and-drop mappings. --- Enjoyable.xcodeproj/project.pbxproj | 6 ++++ Enjoyable_Prefix.pch | 1 + NJMappingsController.m | 54 ++++++++++++++++++++++++++--- NSMutableArray+MoveObject.h | 15 ++++++++ NSMutableArray+MoveObject.m | 19 ++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 NSMutableArray+MoveObject.h create mode 100644 NSMutableArray+MoveObject.m diff --git a/Enjoyable.xcodeproj/project.pbxproj b/Enjoyable.xcodeproj/project.pbxproj index 19eb58e..aef1ed2 100644 --- a/Enjoyable.xcodeproj/project.pbxproj +++ b/Enjoyable.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ EE1D7C9216E01E7000B000EB /* NSView+FirstResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */; }; EE1D7C9616E0ECCF00B000EB /* NSError+Description.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1D7C9516E0ECCF00B000EB /* NSError+Description.m */; }; EE96929416E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.m in Sources */ = {isa = PBXBuildFile; fileRef = EE96929316E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.m */; }; + EEAA9CE116E808E600256B64 /* NSMutableArray+MoveObject.m in Sources */ = {isa = PBXBuildFile; fileRef = EEAA9CE016E808E600256B64 /* NSMutableArray+MoveObject.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -89,6 +90,8 @@ EE1D7C9516E0ECCF00B000EB /* NSError+Description.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+Description.m"; sourceTree = ""; }; EE96929216E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMenu+RepresentedObjectAccessors.h"; sourceTree = ""; }; EE96929316E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMenu+RepresentedObjectAccessors.m"; sourceTree = ""; }; + EEAA9CDF16E808E600256B64 /* NSMutableArray+MoveObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+MoveObject.h"; sourceTree = ""; }; + EEAA9CE016E808E600256B64 /* NSMutableArray+MoveObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+MoveObject.m"; sourceTree = ""; }; EEF86B7316E2241000674B87 /* NJInputPathElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NJInputPathElement.h; sourceTree = ""; }; EEF86B7416E298CD00674B87 /* NJEvents.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NJEvents.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -227,6 +230,8 @@ EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */, EE96929216E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.h */, EE96929316E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.m */, + EEAA9CDF16E808E600256B64 /* NSMutableArray+MoveObject.h */, + EEAA9CE016E808E600256B64 /* NSMutableArray+MoveObject.m */, ); name = Categories; sourceTree = ""; @@ -337,6 +342,7 @@ EE1D7C9216E01E7000B000EB /* NSView+FirstResponder.m in Sources */, EE1D7C9616E0ECCF00B000EB /* NSError+Description.m in Sources */, EE96929416E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.m in Sources */, + EEAA9CE116E808E600256B64 /* NSMutableArray+MoveObject.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Enjoyable_Prefix.pch b/Enjoyable_Prefix.pch index 1057a2c..4f50186 100644 --- a/Enjoyable_Prefix.pch +++ b/Enjoyable_Prefix.pch @@ -11,3 +11,4 @@ #import "NSError+Description.h" #import "NSMenu+RepresentedObjectAccessors.h" #import "NSView+FirstResponder.h" +#import "NSMutableArray+MoveObject.h" diff --git a/NJMappingsController.m b/NJMappingsController.m index a1171a0..cb5baf1 100644 --- a/NJMappingsController.m +++ b/NJMappingsController.m @@ -13,6 +13,8 @@ #import "NJOutputController.h" #import "NJEvents.h" +#define PB_ROW @"com.yukkurigames.Enjoyable.MappingRow" + @implementation NJMappingsController { NSMutableArray *_mappings; NJMapping *manualMapping; @@ -28,6 +30,10 @@ return self; } +- (void)awakeFromNib { + [tableView registerForDraggedTypes:@[PB_ROW]]; +} + - (NJMapping *)objectForKeyedSubscript:(NSString *)name { for (NJMapping *mapping in _mappings) if ([name isEqualToString:mapping.name]) @@ -99,8 +105,8 @@ - (IBAction)addPressed:(id)sender { NJMapping *newMapping = [[NJMapping alloc] initWithName:@"Untitled"]; [_mappings addObject:newMapping]; - [self mappingsChanged]; [self activateMapping:newMapping]; + [self mappingsChanged]; [tableView editColumn:0 row:_mappings.count - 1 withEvent:nil select:YES]; } @@ -109,8 +115,8 @@ return; [_mappings removeObjectAtIndex:tableView.selectedRow]; - [self mappingsChanged]; [self activateMapping:_mappings[0]]; + [self mappingsChanged]; } -(void)tableViewSelectionDidChange:(NSNotification *)notify { @@ -260,9 +266,8 @@ [_mappings addObject:mapping]; } - [self mappingsChanged]; [self activateMapping:mapping]; - [outputController loadCurrent]; + [self mappingsChanged]; if (conflict && !mergeInto) { [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:_mappings.count - 1] byExtendingSelection:NO]; @@ -340,5 +345,46 @@ } } +- (BOOL)tableView:(NSTableView *)tableView + acceptDrop:(id )info + row:(NSInteger)row + dropOperation:(NSTableViewDropOperation)dropOperation { + NSPasteboard *pboard = [info draggingPasteboard]; + if ([pboard.types containsObject:PB_ROW]) { + NSString *value = [pboard stringForType:PB_ROW]; + NSUInteger srcRow = [value intValue]; + [_mappings moveObjectAtIndex:srcRow toIndex:row]; + [self mappingsChanged]; + return YES; + } else { + return NO; + } +} + +- (NSDragOperation)tableView:(NSTableView *)tableView_ + validateDrop:(id )info + proposedRow:(NSInteger)row + proposedDropOperation:(NSTableViewDropOperation)dropOperation { + NSPasteboard *pboard = [info draggingPasteboard]; + if ([pboard.types containsObject:PB_ROW]) { + [tableView_ setDropRow:MAX(1, row) dropOperation:NSTableViewDropAbove]; + return NSDragOperationGeneric; + } else { + return NSDragOperationNone; + } +} + +- (BOOL)tableView:(NSTableView *)tableView +writeRowsWithIndexes:(NSIndexSet *)rowIndexes + toPasteboard:(NSPasteboard *)pboard { + if (rowIndexes.count == 1 && rowIndexes.firstIndex != 0) { + [pboard declareTypes:@[PB_ROW] owner:nil]; + [pboard setString:@(rowIndexes.firstIndex).stringValue forType:PB_ROW]; + return YES; + } else { + return NO; + } + +} @end diff --git a/NSMutableArray+MoveObject.h b/NSMutableArray+MoveObject.h new file mode 100644 index 0000000..c1c60d2 --- /dev/null +++ b/NSMutableArray+MoveObject.h @@ -0,0 +1,15 @@ +// +// NSMutableArray+MoveObject.h +// Enjoyable +// +// Created by Joe Wreschnig on 3/7/13. +// +// + +#import + +@interface NSMutableArray (MoveObject) + +- (void)moveObjectAtIndex:(NSUInteger)src toIndex:(NSUInteger)dst; + +@end diff --git a/NSMutableArray+MoveObject.m b/NSMutableArray+MoveObject.m new file mode 100644 index 0000000..8d9a4ee --- /dev/null +++ b/NSMutableArray+MoveObject.m @@ -0,0 +1,19 @@ +// +// NSMutableArray+MoveObject.m +// Enjoyable +// +// Created by Joe Wreschnig on 3/7/13. +// +// + +#import "NSMutableArray+MoveObject.h" + +@implementation NSMutableArray (MoveObject) + +- (void)moveObjectAtIndex:(NSUInteger)src toIndex:(NSUInteger)dst { + id obj = self[src]; + [self removeObjectAtIndex:src]; + [self insertObject:obj atIndex:dst > src ? dst - 1 : dst]; +} + +@end -- 2.30.2