Fixes to how new move() operations handle the concept

of 'above' and 'below' when referring to items instead
of index positions.

Small offsets needed due to how the arrays are scrolled
after a move operation.



git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10272 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Greg Ercolano 2014-09-05 02:59:00 +00:00
parent 107fc50e48
commit ce1ab7e1ce
2 changed files with 13 additions and 11 deletions

View File

@ -539,8 +539,11 @@ int Fl_Tree_Item::move(Fl_Tree_Item *item, int op, int pos) {
}
if ( !from_parent || !to_parent ) return -1;
if ( from < 0 || to < 0 ) return -2;
if ( op == 1 ) to++; // 'below'? apply +1 offset for 'to'
if ( from_parent == to_parent ) { // same parent?
switch (op) { // 'to' offsets due to scroll
case 0: if ( from < to && to > 0 ) --to; break;
case 1: if ( from > to && to < to_parent->children() ) ++to; break;
}
if ( from_parent->move(to, from) < 0 ) // simple move among siblings
return -4;
} else { // different parent?

View File

@ -234,6 +234,10 @@ void Fl_Tree_Item_Array::swap(int ax, int bx) {
#endif /* FLTK_ABI_VERSION */
/// Move item at 'from' to new position 'to' in the array.
/// Due to how the moving an item shuffles the array around,
/// a positional 'move' implies things that may not be obvious:
/// - When 'from' moved lower in tree, appears BELOW item that was at 'to'.
/// - When 'from' moved higher in tree, appears ABOVE item that was at 'to'.
///
/// \returns 0 on success, -1 on range error (e.g. if \p 'to' or \p 'from' out of range)
///
@ -241,23 +245,18 @@ int Fl_Tree_Item_Array::move(int to, int from) {
if ( from == to ) return 0; // nop
if ( to<0 || to>=_total || from<0 || from>=_total ) return -1;
Fl_Tree_Item *item = _items[from];
Fl_Tree_Item *prev = item->prev_sibling();
Fl_Tree_Item *next = item->next_sibling();
// Remove item..
if ( from < to )
for ( int t=from; t<to && t<_total; t++ )
for ( int t=from; t<to && t<(_total+1); t++ )
_items[t] = _items[t+1];
else
for ( int t=from; t>to; t-- )
for ( int t=from; t>to && t>0; t-- )
_items[t] = _items[t-1];
// Move to new position
_items[to] = item;
// Adjust for new siblings
_items[to]->update_prev_next(to);
_items[from]->update_prev_next(from);
// Adjust old siblings
if ( prev ) prev->update_prev_next(from-1);
if ( next ) next->update_prev_next(from);
// Update all children
for ( int r=0; r<_total; r++ ) // XXX: excessive to do all children,
_items[r]->update_prev_next(r); // XXX: but avoids weird boundary issues
return 0;
}