Fl_Tree_Item_Array.cxx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. //
  2. // "$Id: Fl_Tree_Item_Array.cxx 10071 2014-01-20 21:23:24Z greg.ercolano $"
  3. //
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <FL/Fl_Tree_Item_Array.H>
  8. #include <FL/Fl_Tree_Item.H>
  9. //////////////////////
  10. // Fl_Tree_Item_Array.cxx
  11. //////////////////////
  12. //
  13. // Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
  14. // Copyright (C) 2009-2010 by Greg Ercolano.
  15. //
  16. // This library is free software. Distribution and use rights are outlined in
  17. // the file "COPYING" which should have been included with this file. If this
  18. // file is missing or damaged, see the license at:
  19. //
  20. // http://www.fltk.org/COPYING.php
  21. //
  22. // Please report all bugs and problems on the following page:
  23. //
  24. // http://www.fltk.org/str.php
  25. //
  26. /// Constructor; creates an empty array.
  27. ///
  28. /// The optional 'chunksize' can be specified to optimize
  29. /// memory allocation for potentially large arrays. Default chunksize is 10.
  30. ///
  31. Fl_Tree_Item_Array::Fl_Tree_Item_Array(int new_chunksize) {
  32. _items = 0;
  33. _total = 0;
  34. _size = 0;
  35. #if FLTK_ABI_VERSION >= 10303
  36. _flags = 0;
  37. #endif
  38. _chunksize = new_chunksize;
  39. }
  40. /// Destructor. Calls each item's destructor, destroys internal _items array.
  41. Fl_Tree_Item_Array::~Fl_Tree_Item_Array() {
  42. clear();
  43. }
  44. /// Copy constructor. Makes new copy of array, with new instances of each item.
  45. Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) {
  46. _items = (Fl_Tree_Item**)malloc(o->_size * sizeof(Fl_Tree_Item*));
  47. _total = 0;
  48. _size = o->_size;
  49. _chunksize = o->_chunksize;
  50. #if FLTK_ABI_VERSION >= 10303
  51. _flags = o->_flags;
  52. #endif
  53. for ( int t=0; t<o->_total; t++ ) {
  54. #if FLTK_ABI_VERSION >= 10303
  55. if ( _flags & MANAGE_ITEM ) {
  56. _items[t] = new Fl_Tree_Item(o->_items[t]); // make new copy of item
  57. ++_total;
  58. _items[t]->update_prev_next(t); // update uses _total's current value
  59. } else {
  60. _items[t] = o->_items[t]; // copy ptr only
  61. ++_total;
  62. }
  63. #else
  64. _items[t] = new Fl_Tree_Item(o->_items[t]); // make new copy of item
  65. ++_total;
  66. _items[t]->update_prev_next(t); // update uses _total's current value
  67. #endif
  68. }
  69. }
  70. /// Clear the entire array.
  71. ///
  72. /// Each item will be deleted (destructors will be called),
  73. /// and the array will be cleared. total() will return 0.
  74. ///
  75. void Fl_Tree_Item_Array::clear() {
  76. if ( _items ) {
  77. for ( int t=0; t<_total; t++ ) {
  78. #if FLTK_ABI_VERSION >= 10303
  79. if ( _flags & MANAGE_ITEM )
  80. #endif
  81. {
  82. delete _items[t];
  83. _items[t] = 0;
  84. }
  85. }
  86. free((void*)_items); _items = 0;
  87. }
  88. _total = _size = 0;
  89. }
  90. // Internal: Enlarge the items array.
  91. //
  92. // Adjusts size/items memory allocation as needed.
  93. // Does NOT change total.
  94. //
  95. void Fl_Tree_Item_Array::enlarge(int count) {
  96. int newtotal = _total + count; // new total
  97. if ( newtotal >= _size ) { // more than we have allocated?
  98. if ( (newtotal/150) > _chunksize ) _chunksize *= 10;
  99. // Increase size of array
  100. int newsize = _size + _chunksize;
  101. Fl_Tree_Item **newitems = (Fl_Tree_Item**)malloc(newsize * sizeof(Fl_Tree_Item*));
  102. if ( _items ) {
  103. // Copy old array -> new, delete old
  104. memmove(newitems, _items, _size * sizeof(Fl_Tree_Item*));
  105. free((void*)_items); _items = 0;
  106. }
  107. // Adjust items/sizeitems
  108. _items = newitems;
  109. _size = newsize;
  110. }
  111. }
  112. /// Insert an item at index position \p pos.
  113. ///
  114. /// Handles enlarging array if needed, total increased by 1.
  115. /// If \p pos == total(), an empty item is appended to the array.
  116. ///
  117. void Fl_Tree_Item_Array::insert(int pos, Fl_Tree_Item *new_item) {
  118. enlarge(1);
  119. // printf("*** POS=%d TOTAL-1=%d NITEMS=%d\n", pos, _total-1, (_total-pos));
  120. if ( pos <= (_total - 1) ) { // need to move memory around?
  121. int nitems = _total - pos;
  122. memmove(&_items[pos+1], &_items[pos], sizeof(Fl_Tree_Item*) * nitems);
  123. }
  124. _items[pos] = new_item;
  125. _total++;
  126. #if FLTK_ABI_VERSION >= 10303
  127. if ( _flags & MANAGE_ITEM )
  128. #endif
  129. {
  130. _items[pos]->update_prev_next(pos); // adjust item's prev/next and its neighbors
  131. }
  132. }
  133. /// Add an item* to the end of the array.
  134. ///
  135. /// Assumes the item was created with 'new', and will remain
  136. /// allocated.. Fl_Tree_Item_Array will handle calling the
  137. /// item's destructor when the array is cleared or the item remove()'ed.
  138. ///
  139. void Fl_Tree_Item_Array::add(Fl_Tree_Item *val) {
  140. insert(_total, val);
  141. }
  142. /// Replace the item at \p index with \p newitem.
  143. ///
  144. /// Old item at index position will be destroyed,
  145. /// and the new item will take it's place, and stitched into the linked list.
  146. ///
  147. void Fl_Tree_Item_Array::replace(int index, Fl_Tree_Item *newitem) {
  148. if ( _items[index] ) { // delete if non-zero
  149. #if FLTK_ABI_VERSION >= 10303
  150. if ( _flags & MANAGE_ITEM )
  151. #endif
  152. // Destroy old item
  153. delete _items[index];
  154. }
  155. _items[index] = newitem; // install new item
  156. #if FLTK_ABI_VERSION >= 10303
  157. if ( _flags & MANAGE_ITEM )
  158. #endif
  159. {
  160. // Restitch into linked list
  161. _items[index]->update_prev_next(index);
  162. }
  163. }
  164. /// Remove the item at \param[in] index from the array.
  165. ///
  166. /// The item will be delete'd (if non-NULL), so its destructor will be called.
  167. ///
  168. void Fl_Tree_Item_Array::remove(int index) {
  169. if ( _items[index] ) { // delete if non-zero
  170. #if FLTK_ABI_VERSION >= 10303
  171. if ( _flags & MANAGE_ITEM )
  172. #endif
  173. delete _items[index];
  174. }
  175. _items[index] = 0;
  176. _total--;
  177. for ( int i=index; i<_total; i++ ) { // reshuffle the array
  178. _items[i] = _items[i+1];
  179. }
  180. #if FLTK_ABI_VERSION >= 10303
  181. if ( _flags & MANAGE_ITEM )
  182. #endif
  183. {
  184. if ( index < _total ) { // removed item not last?
  185. _items[index]->update_prev_next(index); // update next item's prev/next and neighbors
  186. } else if ( ((index-1) >= 0) && // removed item IS last?
  187. ((index-1) < _total)) {
  188. _items[index-1]->update_prev_next(index-1);// update prev item's prev/next and neighbors
  189. }
  190. }
  191. }
  192. /// Remove the item from the array.
  193. ///
  194. /// \returns 0 if removed, or -1 if the item was not in the array.
  195. ///
  196. int Fl_Tree_Item_Array::remove(Fl_Tree_Item *item) {
  197. for ( int t=0; t<_total; t++ ) {
  198. if ( item == _items[t] ) {
  199. remove(t);
  200. return(0);
  201. }
  202. }
  203. return(-1);
  204. }
  205. #if FLTK_ABI_VERSION >= 10301
  206. /// Swap the two items at index positions \p ax and \p bx.
  207. void Fl_Tree_Item_Array::swap(int ax, int bx) {
  208. Fl_Tree_Item *asave = _items[ax];
  209. _items[ax] = _items[bx];
  210. _items[bx] = asave;
  211. #if FLTK_ABI_VERSION >= 10303
  212. if ( _flags & MANAGE_ITEM )
  213. #endif
  214. {
  215. // Adjust prev/next ptrs
  216. _items[ax]->update_prev_next(ax);
  217. _items[bx]->update_prev_next(bx);
  218. }
  219. }
  220. #endif /* FLTK_ABI_VERSION */
  221. //
  222. // End of "$Id: Fl_Tree_Item_Array.cxx 10071 2014-01-20 21:23:24Z greg.ercolano $".
  223. //