On 29/11/2012, at 8:35 AM, Quincey Morris <quinceymor...@rivergatesoftware.com> 
wrote:

> On Nov 28, 2012, at 13:02 , Quincey Morris 
> <quinceymor...@rivergatesoftware.com> wrote:
> 
>> I think the loop algorithm needs to look like this:
>> 
>> C1. Loop over the "less than" set starting from its highest index and 
>> working down. At each iteration, move the row at the current index to 
>> 'targetIndex - 1'. (But don't decrement targetIndex here.)
>> 
>> C2. Loop over the "greater than" set starting from its lowest index and 
>> working up. At each iteration, move the row at the current index to the 
>> targetIndex row, and increment targetIndex.
> 
> Ugh, I think I made the same mistake again. The decrement has to be there:
> 
> C1. Loop over the "less than" set starting from its highest index and working 
> down. At each iteration, move the row at the current index to 'targetIndex - 
> 1' and decrement targetIndex.
> 
> C2. Reset targetIndex to its original value.
> 
> C3. Loop over the "greater than" set starting from its lowest index and 
> working up. At each iteration, move the row at the current index to 
> 'targetIndex', and increment targetIndex.
> 


Yay, I think we got there :) (A night's sleep and a large infusion of caffeine 
has also helped with wrapping my head around this). I'm not ignoring Seth's 
approach either, but this seems the simpler one for the moment.

Here's my implementation, where <indexes> are the items to be moved, and 
<newIndexes> are where they are to end up:

                NSUInteger insertionIndex = [newIndexes firstIndex] + offset;
                NSUInteger moveIndex = [indexes 
indexLessThanIndex:insertionIndex];
                
                while( moveIndex != NSNotFound )
                {
                        [traceSelectorView moveRowAtIndex:moveIndex 
toIndex:--insertionIndex];
                        moveIndex = [indexes indexLessThanIndex:moveIndex];
                }
                
                insertionIndex = [newIndexes firstIndex] + offset;
                moveIndex = [indexes 
indexGreaterThanOrEqualToIndex:insertionIndex];
                
                while( moveIndex != NSNotFound )
                {
                        [traceSelectorView moveRowAtIndex:moveIndex 
toIndex:insertionIndex++];
                        moveIndex = [indexes indexGreaterThanIndex:moveIndex];
                }


I'm going to throw a new spanner in the works now, since in achieving this 
small victory (with much help and grateful thanks) I need to push the envelope 
a bit further...

This is factored into a method that takes two index sets, the source, and the 
destination. The destination starts at the insertion index and is a contiguous 
set having the same number of entries as the source set. Why? Because a) it 
allows the removal/insertion of items in the data model to be handled easily 
and b) it allows it to be undoable, by the simple expedient of swapping the two 
index sets when undoing.

The above code adds a mysterious value called 'offset', which is the amount I 
compensated the destination index set by to account for the items being moved 
that are less than the insertion index, i.e:

        NSInteger offset;
        
        offset = [indexes countOfIndexesInRange:NSMakeRange(0,insertionIndex)];
        NSIndexSet* insertions = [NSIndexSet 
indexSetWithIndexesInRange:NSMakeRange( insertionIndex - offset, [indexes 
count])];        <-- insertions becomes 'newIndexes' above when passed to that 
method


So the question now is, can the table reordering with animation be made to work 
in the undo case?

Undo works now in that the data model reordering is correctly undoable and 
redoable, but once again table reordering messes up, because of the assumption 
in the table reordering code that the insertions are contiguous. The code needs 
to be further generalised to move items from one arbitrary index to another.

For now I'll use my earlier implementation when undoing or redoing, which is 
probably acceptable.

--Graham





_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to