DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR Pending]

Link: http://www.fltk.org/str.php?L2795
Version: 1.3-current
Fix Version: 1.3-current (r9217)


Attached file "fltree.patch"...


Link: http://www.fltk.org/str.php?L2795
Version: 1.3-current
Fix Version: 1.3-current (r9217)
Index: src/Fl_Tree_Item_Array.cxx
===================================================================
--- src/Fl_Tree_Item_Array.cxx  (revision 9216)
+++ src/Fl_Tree_Item_Array.cxx  (working copy)
@@ -53,6 +53,9 @@
   for ( int t=0; t<o->_total; t++ ) {
     _items[t] = new Fl_Tree_Item(o->_items[t]);
   }
+  for ( int t=0; t<o->_total; t++ ) {
+    _items[t]->update_prev_next(t);
+  }
 }
 
 /// Clear the entire array.
@@ -108,6 +111,7 @@
   } 
   _items[pos] = new_item;
   _total++;
+  _items[pos]->update_prev_next(pos);  // adjust item's prev/next and its 
neighbors
 }
 
 /// Add an item* to the end of the array.
@@ -125,13 +129,20 @@
 ///     The item will be delete'd (if non-NULL), so its destructor will be 
called.
 ///
 void Fl_Tree_Item_Array::remove(int index) {
-  if ( _items[index] ) {               // delete if non-zero
+  if ( _items[index] ) {                       // delete if non-zero
     delete _items[index];
   }
   _items[index] = 0;
-  for ( _total--; index<_total; index++ ) {
-    _items[index] = _items[index+1];
+  _total--;
+  for ( int i=index; i<_total; i++ ) {         // reshuffle array
+    _items[i] = _items[i+1];
   }
+  if ( index < _total ) {                      // removed item not last?
+    _items[index]->update_prev_next(index);    // update next item's prev/next 
and neighbors
+  } else if ( ((index-1) >= 0) &&              // removed item IS last?
+            ((index-1) < _total)) {
+    _items[index-1]->update_prev_next(index-1);        // update prev item's 
prev/next and neighbors
+  }
 }
 
 /// Remove the item from the array.
@@ -148,6 +159,16 @@
   return(-1);
 }
 
+/// Swap the two items at index positions \p ax and \p bx.
+void Fl_Tree_Item_Array::swap(int ax, int bx) {
+  Fl_Tree_Item *asave = _items[ax];
+  _items[ax] = _items[bx];
+  _items[bx] = asave;
+  // Adjust prev/next ptrs
+  _items[ax]->update_prev_next(ax);
+  _items[bx]->update_prev_next(bx);
+}
+
 //
 // End of "$Id$".
 //
Index: src/Fl_Tree_Item.cxx
===================================================================
--- src/Fl_Tree_Item.cxx        (revision 9217)
+++ src/Fl_Tree_Item.cxx        (working copy)
@@ -61,6 +61,8 @@
   _usericon         = 0;
   _userdata         = 0;
   _parent           = 0;
+  _prev_sibling     = 0;
+  _next_sibling     = 0;
 }
 
 // DTOR
@@ -101,6 +103,8 @@
   _usericon         = o->usericon();
   _userdata         = o->user_data();
   _parent           = o->_parent;
+  _prev_sibling     = 0;               // do not copy ptrs! use 
update_prev_next()
+  _next_sibling     = 0;               // do not copy ptrs! use 
update_prev_next()
 }
 
 /// Print the tree as 'ascii art' to stdout.
@@ -108,8 +112,9 @@
 ///
 void Fl_Tree_Item::show_self(const char *indent) const {
   if ( label() ) {
-    printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n",
-           indent,label(),children(),(void*)this, (void*)_parent, depth());
+    printf("%s-%s (%d children, this=%p, parent=%p, prev=%p, next=%p, 
depth=%d)\n",
+           indent,label(),children(),(void*)this, (void*)_parent,
+          _prev_sibling, _next_sibling, depth());
   }
   if ( children() ) {
     char *i2 = (char*)malloc(strlen(indent) + 2);
@@ -794,9 +799,8 @@
     return(c->child(0));
   }
   while ( ( p = c->parent() ) != NULL ) {      // loop upwards through parents
-    int t = p->find_child(c);                  // find our position in 
parent's children[] array
-    if ( ++t < p->children() )                 // not last child?
-      return(p->child(t));                     // return next child
+    if ( c->_next_sibling )                    // not last child?
+      return(c->_next_sibling);                        // return next child
     c = p;                                     // child becomes parent to move 
up generation
   }                                            // loop: moves up to next parent
   return(0);                                   // hit root? done
@@ -832,14 +836,28 @@
 /// \returns item's next sibling, or 0 if none.
 ///
 Fl_Tree_Item *Fl_Tree_Item::next_sibling() {
-  if ( !parent() ) return(0);                  // No parent (root)? We have no 
siblings
-  int index = parent()->find_child(this);      // find our position in 
parent's child() array
-  if ( index == -1 ) return(0);                        // parent doesn't know 
us? weird
-  if ( (index+1) < parent()->children() )      // is there a next child?
-    return(parent()->child(index+1));          // return next child if there's 
one below us
-  return(0);                                   // no siblings below us
+  return(_next_sibling);
 }
 
+/// Update our _prev_sibling and _next_sibling pointers to point to neighbors,
+/// given \p index as being our current position in the parent's item array.
+/// Call this whenever items in the array are added/removed/moved/swapped.
+/// 
+void Fl_Tree_Item::update_prev_next(int index) {
+  int pchildren = parent() ? parent()->children() : 0;
+  int index_prev = index-1;
+  int index_next = index+1;
+  // Get pointers to prev+next items
+  Fl_Tree_Item *item_prev = (index_prev>=0)&&(index_prev<pchildren) ? 
parent()->child(index_prev) : 0;
+  Fl_Tree_Item *item_next = (index_next>=0)&&(index_next<pchildren) ? 
parent()->child(index_next) : 0;
+  // Adjust our prev+next ptrs
+  _prev_sibling = item_prev;
+  _next_sibling = item_next;
+  // Adjust neighbors to point to us
+  if ( item_prev ) item_prev->_next_sibling = this;
+  if ( item_next ) item_next->_prev_sibling = this;
+}
+      
 /// Return this item's previous sibling.
 ///
 /// Moves to the previous item above us at the same level (sibling).
@@ -848,11 +866,7 @@
 /// \returns This item's previous sibling, or 0 if none.
 ///
 Fl_Tree_Item *Fl_Tree_Item::prev_sibling() {
-  if ( !parent() ) return(0);                          // No parent (root)? We 
have no siblings
-  int index = parent()->find_child(this);              // find next position 
up in parent's child() array
-  if ( index == -1 ) return(0);                                // parent 
doesn't know us? weird
-  if ( index > 0 ) return(parent()->child(index-1));   // return previous 
child if there's one above us
-  return(0);                                           // no siblings above us
+  return(_prev_sibling);
 }
 
 /// Return the next visible item. (If this item has children and is closed, 
children are skipped)
Index: FL/Fl_Tree_Item_Array.H
===================================================================
--- FL/Fl_Tree_Item_Array.H     (revision 9196)
+++ FL/Fl_Tree_Item_Array.H     (working copy)
@@ -65,12 +65,7 @@
   int total() const {
     return(_total);
   }
-  /// Swap the two items at index positions \p ax and \p bx.
-  void swap(int ax, int bx) {
-    Fl_Tree_Item *asave = _items[ax];
-    _items[ax] = _items[bx];
-    _items[bx] = asave;
-  }
+  void swap(int ax, int bx);
   void clear();
   void add(Fl_Tree_Item *val);
   void insert(int pos, Fl_Tree_Item *new_item);
Index: FL/Fl_Tree_Item.H
===================================================================
--- FL/Fl_Tree_Item.H   (revision 9196)
+++ FL/Fl_Tree_Item.H   (working copy)
@@ -68,6 +68,8 @@
   Fl_Image               *_usericon;           // item's user-specific icon 
(optional)
   Fl_Tree_Item_Array      _children;           // array of child items
   Fl_Tree_Item           *_parent;             // parent item (=0 if root)
+  Fl_Tree_Item           *_prev_sibling;       // previous sibling (same level)
+  Fl_Tree_Item           *_next_sibling;       // next sibling (same level)
   void                   *_userdata;           // user data that can be 
associated with an item
 protected:
   void show_widgets();
@@ -178,6 +180,7 @@
   Fl_Tree_Item *next();
   Fl_Tree_Item *next_sibling();
   Fl_Tree_Item *prev_sibling();
+  void update_prev_next(int index);
   Fl_Tree_Item *next_displayed(Fl_Tree_Prefs &prefs);
   Fl_Tree_Item *prev_displayed(Fl_Tree_Prefs &prefs);
   
_______________________________________________
fltk-bugs mailing list
fltk-bugs@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to