r717: Made the highlighted text color of the menus WHITE
[cinelerra_cv/mob.git] / guicast / linklist.h
blobabeea1877ccb7f8b167689cff02923bfd2f5b913
1 #ifndef LINKLIST_H
2 #define LINKLIST_H
4 template<class TYPE>
5 class ListItem;
7 template<class TYPE>
8 class List // inherited by lists
10 public:
11 List();
12 virtual ~List();
14 void remove(TYPE *item); // delete the item and the pointers to it
15 void remove_pointer(ListItem<TYPE> *item); // remove the pointers to the item only
17 // these must be used to add an item to a list
18 TYPE *append(); // create new node and return pointer of it
19 TYPE *append(TYPE *new_item); // append the new pointer to the list
20 TYPE *insert_before(TYPE *item); // create new node and return pointer of it
21 TYPE *insert_before(TYPE *item, TYPE *new_item); // create new node and return pointer of it
22 TYPE *insert_after(TYPE *item);
23 TYPE *insert_after(TYPE *item, TYPE *new_item);
24 TYPE *get_item_number(int number);
25 int get_item_number(TYPE *item);
26 void swap(TYPE *item1, TYPE *item2);
28 // query the list
29 int total(); // total number of nodes
30 int number_of(TYPE *item);
32 // convenience macros
33 #define PREVIOUS current->previous
34 #define NEXT current->next
36 // references to list
37 TYPE *first;
38 TYPE *last;
41 template<class TYPE>
42 class ListItem // inherited by list items
44 public:
45 ListItem();
46 virtual ~ListItem();
48 int get_item_number();
49 TYPE *previous;
50 TYPE *next;
51 List<TYPE> *owner; // list that owns this item for deletion
54 template<class TYPE>
55 List<TYPE>::List()
57 last = first = 0;
60 template<class TYPE>
61 List<TYPE>::~List() // delete nodes
63 while(last)
65 delete last;
69 template<class TYPE>
70 int List<TYPE>::total() // total number of nodes
72 int total = 0;
73 TYPE* current;
75 for(current = first; current; current = NEXT)
77 total++;
79 return total;
82 template<class TYPE>
83 int List<TYPE>::number_of(TYPE *item)
85 TYPE* current;
86 int total = 0;
87 for(current = first; current; current = NEXT)
89 if(current == item) return total;
90 total++;
92 return 0;
95 template<class TYPE>
96 TYPE* List<TYPE>::get_item_number(int number)
98 TYPE* current;
99 int i;
100 for(i = 0, current = first; current && i < number; current = NEXT, i++)
104 return current;
107 template<class TYPE>
108 int List<TYPE>::get_item_number(TYPE *item)
110 TYPE* current;
111 int i;
112 for(i = 0, current = first; current && current != item; current = NEXT, i++)
116 return i;
120 template<class TYPE>
121 TYPE* List<TYPE>::append()
123 TYPE* current_item;
125 if(!last) // add first node
127 current_item = last = first = new TYPE;
128 current_item->previous = current_item->next = 0;
129 current_item->owner = this;
130 return current_item;
132 else
133 { // append node
134 current_item = last->next = new TYPE;
135 current_item->previous = last;
136 current_item->next = 0;
137 last = current_item;
138 current_item->owner = this;
139 return current_item;
143 template<class TYPE>
144 TYPE* List<TYPE>::append(TYPE *new_item)
146 TYPE* current_item;
148 if(!last) // add first node
150 current_item = last = first = new_item;
151 current_item->previous = current_item->next = 0;
152 current_item->owner = this;
153 return current_item;
155 else
156 { // append node
157 current_item = last->next = new_item;
158 current_item->previous = last;
159 current_item->next = 0;
160 last = current_item;
161 current_item->owner = this;
162 return current_item;
166 template<class TYPE>
167 TYPE* List<TYPE>::insert_before(TYPE *item)
169 TYPE* new_item = new TYPE;
170 return insert_before(item, new_item);
173 template<class TYPE>
174 TYPE* List<TYPE>::insert_before(TYPE *item, TYPE *new_item)
176 if(!item) return append(new_item); // if item is null, append
178 TYPE* current_item = new_item;
180 if(item == first) first = current_item; // set *first
182 current_item->previous = item->previous; // set this node's pointers
183 current_item->next = item;
185 if(current_item->previous) current_item->previous->next = current_item; // set previous node's pointers
187 if(current_item->next) current_item->next->previous = current_item; // set next node's pointers
189 current_item->owner = this;
190 return current_item;
193 template<class TYPE>
194 TYPE* List<TYPE>::insert_after(TYPE *item)
196 TYPE *new_item = new TYPE;
197 return insert_after(item, new_item);
200 template<class TYPE>
201 TYPE* List<TYPE>::insert_after(TYPE *item, TYPE *new_item)
203 if(!item) return append(new_item); // if item is null, append
205 TYPE* current_item = new_item;
207 if(item == last) last = current_item; // set *last
209 current_item->previous = item; // set this node's pointers
210 current_item->next = item->next;
212 if(current_item->previous) current_item->previous->next = current_item; // set previous node's pointers
214 if(current_item->next) current_item->next->previous = current_item; // set next node's pointers
216 current_item->owner = this;
217 return current_item;
220 template<class TYPE>
221 void List<TYPE>::swap(TYPE *item1, TYPE *item2)
223 TYPE **temp_array;
224 int total = this->total();
225 temp_array = new TYPE*[total];
226 // Copy entire list to a temp. This rewrites the pointers in the original items.
227 for(int i = 0; i < total; i++)
229 temp_array[i] = get_item_number(i);
231 while(last) remove_pointer(last);
232 for(int i = 0; i < total; i++)
234 if(temp_array[i] == item1) append(item2);
235 else
236 if(temp_array[i] == item2) append(item1);
237 else
238 append(temp_array[i]);
240 delete [] temp_array;
242 #if 0
243 TYPE *new_item0, *new_item1, *new_item2, *new_item3;
245 // old == item0 item1 item2 item3
246 // new == item0 item2 item1 item3
248 new_item0 = item1->previous;
249 new_item1 = item2;
250 new_item2 = item1;
251 new_item3 = item2->next;
253 if(new_item0)
254 new_item0->next = new_item1;
255 else
256 first = new_item1;
258 if(new_item1) new_item1->next = new_item2;
259 if(new_item2) new_item2->next = new_item3;
260 if(new_item3)
261 new_item3->previous = new_item2;
262 else
263 last = new_item2;
265 if(new_item2) new_item2->previous = new_item1;
266 if(new_item1) new_item1->previous = new_item0;
267 #endif
270 template<class TYPE>
271 void List<TYPE>::remove(TYPE *item)
273 if(!item) return;
274 delete item; // item calls back to remove pointers
277 template<class TYPE>
278 void List<TYPE>::remove_pointer(ListItem<TYPE> *item)
280 //printf("List<TYPE>::remove_pointer %x %x %x\n", item, last, first);
281 if(!item) return;
283 if(item == last && item == first)
285 // last item
286 last = first = 0;
287 return;
290 if(item == last) last = item->previous; // set *last and *first
291 else
292 if(item == first) first = item->next;
294 if(item->previous) item->previous->next = item->next; // set previous node's pointers
296 if(item->next) item->next->previous = item->previous; // set next node's pointers
299 template<class TYPE>
300 ListItem<TYPE>::ListItem()
302 next = previous = 0;
303 // don't delete the pointer to this if it's not part of a list
304 owner = 0;
307 template<class TYPE>
308 ListItem<TYPE>::~ListItem()
310 // don't delete the pointer to this if it's not part of a list
311 if(owner) owner->remove_pointer(this);
314 template<class TYPE>
315 int ListItem<TYPE>::get_item_number()
317 return owner->get_item_number((TYPE*)this);
320 #endif