Skip to content

Instantly share code, notes, and snippets.

@mysteriouspants
Created April 17, 2012 18:30
Show Gist options
  • Save mysteriouspants/2408030 to your computer and use it in GitHub Desktop.
Save mysteriouspants/2408030 to your computer and use it in GitHub Desktop.
Basic drag'n'drop functionality.
//
// COADocumentWindowController.m
// Co-Author
//
// Created by Christopher Miller on 4/13/12.
// Copyright (c) 2012 FSDEV. All rights reserved.
//
#import "COADocumentWindowController.h"
#import "COAManagedNode.h"
#import "COAGroupNode.h"
#import "COAFileNode.h"
@interface COADocumentWindowController ()
@end
@implementation COADocumentWindowController
@synthesize drawer=_drawer;
@synthesize outlineView=_outlineView;
@synthesize mutators=_mutators;
@synthesize managedNodes = _managedNodes;
- (IBAction)mutatorClicked:(id)sender {
switch (_mutators.selectedSegment) {
case 0:
[_outlineView beginUpdates];
[[_outlineView selectedRowIndexes] enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
id<COAManagedNode> item = [_outlineView itemAtRow:idx];
id<COAManagedNode> parent = [_outlineView parentForItem:item];
[_outlineView removeItemsAtIndexes:[NSIndexSet indexSetWithIndex:[[parent children] indexOfObject:item]] inParent:parent withAnimation:NSTableViewAnimationSlideLeft | NSTableViewAnimationEffectFade];
[[parent children] removeObject:item];
}];
[_outlineView endUpdates];
break;
case 1:
NSLog(@"add stuff");
NSLog(@"%@", _managedNodes);
break;
default:
NSLog(@"no such segment");
break;
}
}
#pragma mark NSWindowController
- (id)initWithWindow:(NSWindow *)window
{
self = [super initWithWindow:window];
if (self) {
// Initialization code here.
}
return self;
}
- (void)windowDidLoad
{
[super windowDidLoad];
self.managedNodes = [[self document] managedNodes];
[self.drawer openOnEdge:NSMinXEdge];
[self.outlineView registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
[self.outlineView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];
}
#pragma mark NSOutlineViewDataSource
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
if (item) {
id<COAManagedNode> node = item;
return [[node children] objectAtIndex:index];
}
return [_managedNodes objectAtIndex:index];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
if (item) {
id<COAManagedNode> node = item;
if ([node isGroup] || [node isDirectory]) return YES;
}
return NO;
}
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
if (item == nil) return [_managedNodes count];
else return [((id<COAManagedNode>)item).children count];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index
{
NSPasteboard * pboard = [info draggingPasteboard];
NSMutableArray * proposedNodes = [NSMutableArray arrayWithCapacity:[[pboard pasteboardItems] count]];
for (NSPasteboardItem * pasteboarditem in [pboard pasteboardItems]) {
[proposedNodes addObject:[COAFileNode fileNodeWithPath:[pasteboarditem stringForType:(NSString *)kUTTypeFileURL]]];
}
// eliminate items already managed
[proposedNodes filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id<COAManagedNode> evaluatedObject, NSDictionary *bindings) {
return !COAManagedNodePresentInGraph(evaluatedObject, _managedNodes); // don't add nodes already present
}]];
if (index == -1) index = 0;
NSIndexSet * insertions = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, [proposedNodes count])];
if (item) {
id<COAManagedNode> managedNode = item;
[outlineView beginUpdates];
[outlineView insertItemsAtIndexes:insertions inParent:item withAnimation:NSTableViewAnimationSlideRight | NSTableViewAnimationEffectFade];
[[managedNode children] insertObjects:proposedNodes atIndexes:insertions];
[outlineView endUpdates];
} else {
[outlineView beginUpdates];
[outlineView insertItemsAtIndexes:insertions inParent:item withAnimation:NSTableViewAnimationSlideRight | NSTableViewAnimationEffectFade];
[_managedNodes insertObjects:proposedNodes atIndexes:insertions];
[outlineView endUpdates];
}
return YES;
}
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{
if (item != nil && ![((id<COAManagedNode>)item) isGroup]) return NSDragOperationNone;
NSPasteboard * dndPboard = [info draggingPasteboard];
NSMutableArray * proposedNodes = [NSMutableArray arrayWithCapacity:[[dndPboard pasteboardItems] count]];
for (NSPasteboardItem * pasteboarditem in [dndPboard pasteboardItems])
[proposedNodes addObject:[COAFileNode fileNodeWithPath:[pasteboarditem stringForType:(NSString *)kUTTypeFileURL]]];
// eliminate items already managed
[proposedNodes filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id<COAManagedNode> evaluatedObject, NSDictionary *bindings) {
return !COAManagedNodePresentInGraph(evaluatedObject, _managedNodes); // don't add nodes already present
}]];
if ([proposedNodes count] == 0) return NSDragOperationNone;
[info setNumberOfValidItemsForDrop:[proposedNodes count]];
[info setAnimatesToDestination:YES];
return NSDragOperationLink;
}
#pragma mark NSOutlineViewDelegate
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
NSTableCellView * cell = [outlineView makeViewWithIdentifier:@"FileCell" owner:self];
id<COAManagedNode> managedNode = item;
if (cell) {
cell.textField.stringValue = [managedNode name];
cell.imageView.image = [managedNode icon];
} else
NSLog(@"Nil view?");
return cell;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment