Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Dec 2, 2012, 10:57 PM   #1
ArtOfWarfare
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
Allow NSOutlineView to be rearranged?

I have a simple Core Data model with just one entity which has two relationships, parent and children, with them pointing at each other and parent being to many children. They also have three attributes, index, an Int 64, name, a string, and type, an Int 16.

This model is bound to an Array Controller, a Tree Controller, and a custom class that serves as an NSOutlineViewDataSource.

In the header I have this:
Code:
@interface OutlineViewController : NSObject <NSOutlineViewDataSource> {
    IBOutlet NSTreeController* treeController;
    IBOutlet NSOutlineView* outlineView;
    NSArray* dragType;
    NSTreeNode* draggedNode;
}
In main I have these methods:
Code:
- (void)awakeFromNib {
    dragType = [NSArray arrayWithObject:@"factorialDragType"];
    [outlineView registerForDraggedTypes:dragType];
    NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"index" ascending:YES];
    [treeController setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
}

- (BOOL)outlineView:(NSOutlineView*)outlineView writeItems:(NSArray*)items toPasteboard:(NSPasteboard *)pasteboard {
    [pasteboard declareTypes:dragType owner:self];
    draggedNode = [items objectAtIndex:0];
    return YES;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id<NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index {
    NSManagedObject* draggedTreeNode = [draggedNode representedObject];
    [draggedTreeNode setValue:[item representedObject] forKey:@"parent"];
    NSLog(@"Item dragged from %l to %li", [[draggedTreeNode valueForKey:@"index"] longValue], index);
    [draggedTreeNode setValue:[NSNumber numberWithLong:index] forKey:@"index"];
    [outlineView reloadData];
    return YES;
}

- (BOOL)category:(NSManagedObject*)category isSubCategoryOf:(NSManagedObject*)possibleSub {
    if (category == possibleSub) {
        return YES;
    }
    
    NSManagedObject* possibleSubParent = [possibleSub valueForKey:@"parent"];
    while (possibleSubParent != NULL) {
        if (possibleSubParent == category) {
            return YES;
        }
        possibleSubParent = [possibleSubParent valueForKey:@"parent"];
    }
    return NO;
}

- (id)outlineView:(NSOutlineView*)outlineView objectValueForTableColumn:(NSTableColumn*)tableColumn byItem:(id)item {
    return NULL;
}

- (NSDragOperation)outlineView:(NSOutlineView*)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index {
    // TODO: Don't propose moving it to where it already is.
    if ([item representedObject] == NULL) {
        return NSDragOperationGeneric;
    }
    
    if ([self category:[draggedNode representedObject] isSubCategoryOf:[item representedObject]]) {
        return NO;
    }
    
    return NSDragOperationGeneric;
}

-(NSInteger)outlineView:(NSOutlineView*)outlineView {
    return 1;
}

-(BOOL)outlineView:(NSOutlineView*)outlineView isItemExpandable:(id)item {
    return YES;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    return NULL;
}
My issue is this: I can't rearrange items within a given tier. I can move them into and out of each other, but I can't simply have 3 items all on the same level and move the bottom one to be at the top, for example. If I try, what happens is I get a log message that properly reports where I moved the item to and from, but it doesn't actually move the item until I quit the app and relaunch it. Moving items into and out of eachother is instantly reflected. Any idea what I'm doing wrong?

I followed the tutorial I found here to get most of the way to where I am:

http://lifeasclay.wordpress.com/2011...rees/#more-442
__________________
Don't tell me Macs don't last: 2007 iMac, 2007 Mac Mini, 2008 MacBook Air, all Vintage.
(iMac obsoletion: April 28, 2015, MBA: October 14, 2015, Mac Mini: March 9, 2016)
ArtOfWarfare is offline   0 Reply With Quote
Old Dec 4, 2012, 09:24 PM   #2
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
I'm not a big fan of doing this but I'm still stuck with this... Bump?

Does anyone know what I'm missing? Why does the row go back where it started when I drag and drop it (and don't move the tier it's in.)

Edit: I've finally found a promising method:
Code:
[treeController moveNode:(NSTreeNode*) toIndexPath:(NSIndexPath*)];
If I insert that in my outlineView:acceptDrop:... method, then some items move properly sometimes. I'm working on making them move properly all the time.

Last edited by ArtOfWarfare; Dec 5, 2012 at 10:12 PM.
ArtOfWarfare is offline   0 Reply With Quote
Old Dec 5, 2012, 10:48 PM   #3
ArtOfWarfare
Thread Starter
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
Alright... so now I have this code:

Code:
- (BOOL)outlineView:(NSOutlineView *)mOutlineView acceptDrop:(id<NSDraggingInfo>)info item:(id)parent childIndex:(NSInteger)index {
    [draggedObject setValue:[parent representedObject] forKey:@"parent"];
    NSInteger dropIndex = (index == NSOutlineViewDropOnItemIndex) ? 0 : index;
    [draggedObject setValue:[NSNumber numberWithLong:index] forKey:@"index"];
    NSIndexPath* dropPath = (parent) ? [[parent indexPath] indexPathByAddingIndex:dropIndex] : [NSIndexPath indexPathWithIndex:dropIndex];
    [treeController moveNode:draggedNode toIndexPath:dropPath];
    return YES;
}
This works most of the time, except it seems that if the move object originally wasn't a child of anything, I'll end up with two copies of the object: one where it should be, and a second at the bottom of the list of children for the parent. If I add in a check to see if the object was a child of anything and do nothing if it wasn't, it'll be added without a duplicate, but only the child in the wrong spot will be there.

This is confusing/frustrating to say the least...
__________________
Don't tell me Macs don't last: 2007 iMac, 2007 Mac Mini, 2008 MacBook Air, all Vintage.
(iMac obsoletion: April 28, 2015, MBA: October 14, 2015, Mac Mini: March 9, 2016)
ArtOfWarfare is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
App Store bottom buttons rearranged somehow? viktorlsn iOS 6 8 Mar 8, 2013 01:45 PM
Bind NSOutlineView & NSTextView to NSTreeController? ArtOfWarfare Mac Programming 3 Dec 9, 2012 11:25 AM
Issue with NSOutlineView? jaquadro Mac Programming 0 Nov 4, 2012 04:12 PM
NSOutlineView Source List Child Item Titles Disappearing mkmDesign Mac Programming 1 Oct 26, 2012 12:46 PM
NSOutlineView objects being released perrien Mac Programming 3 Aug 28, 2012 06:47 AM

Forum Jump

All times are GMT -5. The time now is 12:02 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps