summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Fl_Tree_Item.cxx5
-rw-r--r--src/Fl_Tree_Item_Array.cxx19
2 files changed, 13 insertions, 11 deletions
diff --git a/src/Fl_Tree_Item.cxx b/src/Fl_Tree_Item.cxx
index a5ec92d27..8c68c2518 100644
--- a/src/Fl_Tree_Item.cxx
+++ b/src/Fl_Tree_Item.cxx
@@ -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?
diff --git a/src/Fl_Tree_Item_Array.cxx b/src/Fl_Tree_Item_Array.cxx
index 2610bb2a6..7f7476569 100644
--- a/src/Fl_Tree_Item_Array.cxx
+++ b/src/Fl_Tree_Item_Array.cxx
@@ -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;
}