Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
text_area.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 * text_area.cpp - description
3 * --------------------------
4 * begin : January 10, 2002
5 * copyright : (C) 2002 by David Ranger
6 * email : ussreliant@users.sourceforge.net
7 ***************************************************************************/
8 
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * any later version. *
15 * *
16 ***************************************************************************/
17 
18 #include "text_area.h"
19 #include "gldrv/winsys.h"
20 #include <cstdlib>
21 #include <cstring>
22 
23 //Array of textures for the text area
24 //GUITexture *Images;
25 
26 //List of images to load. Last element must always be NULL
27 /*
28  * char *LoadImages[] = { TEXT_AREA_00, TEXT_AREA_01, TEXT_AREA_02, TEXT_AREA_03, TEXT_AREA_04,
29  * TEXT_AREA_05, TEXT_AREA_06, TEXT_AREA_07, TEXT_AREA_08, TEXT_AREA_09,
30  * TEXT_AREA_10, TEXT_AREA_11, TEXT_AREA_12, TEXT_AREA_13,
31  * NULL
32  * };
33  */
34 
36 
38 {
39  TextArea( 0, 0, 1, 1, 1 );
40 }
41 
42 //Currently, corners overlap the horizontal and vertical bars. It's only noticable with transparency
43 TextArea::TextArea( float x, float y, float wid, float hei, int scrollbar )
44 {
45  #ifdef DEBUG
46  cout<<"Displaying border at "<<x<<","<<y<<"\n";
47  cout<<"with the dimensions of "<<wid<<","<<y<<"\n";
48  cout<<"Scrollbar: "<<scrollbar<<endl;
49  cout<<"------------\n";
50  #endif
51 
52  LoadTextures();
53 
54  //Initialize the variables
55  item_count = 0;
56  cur_selected = 0;
57  top_item_number = 0;
58  button_pressed = 0;
59  cur_highlighted = 0;
60  page_size = 5;
61  scroll_start = 0;
62  scroll_cur = 0;
63  do_highlight = 1;
64  do_multiline = 0;
65 
66  ratio[0] = 0.06;
67  if (scrollbar == 0) {
68  ratio[1] = ratio[0];
69  has_scrollbar = 0;
70  } else {
71  ratio[1] = 0.12;
72  has_scrollbar = 1;
73  }
74  //Top and bottom button ratios. Only change these if you change the ratio[1] and/or the image
75  //If you change these, uncomment the appropriate ShowColor() in the Refresh to verify the alignment
76  button_ratio[0] = 0.91096; //left x, both buttons
77  button_ratio[1] = 0.0345; //Top button, top left corner y
78  button_ratio[2] = 0.0585; //Height and width of the buttons
79 
80  scrollbar_ratio[0] = 0.91096; //x axis
81  scrollbar_ratio[1] = 0.1; //y axis
82  scrollbar_ratio[2] = 0.0585; //Width
83  //scrollbar_ratio[3] = 0.89; // Height
84  scrollbar_ratio[3] = 0.73; //Height (how much the bar doesn't take of the buttons)
85 
86  //Set the variables to control where and how text will be displayed
87  font_size = 4;
88  font_size_float = 4;
89  horizontal_per_level = 0.05;
90  horizontal_spacer = 0.01;
91  vertical_left_of_text = 0.02;
92  text_spacing = (font_size_float/100)+(horizontal_spacer*2);
93 
94  //The parent TextAreaItem. This is the only link where parent == NULL. It is not displayed and handled only internally
95  ItemList = new TextAreaItem( "", "", NULL );
96  if (wid < 0 || hei < 0) {
97  printf( "Cannot draw border with negative height or width\n" );
98  return;
99  }
100  if (x+wid > 1) wid = 1-x;
101  if (y-hei < -1) hei = -1+y;
102  //Set the class variables to remember the dimensions and locations of the text area
103  xcoord[0] = x;
104  ycoord[0] = y;
105  width[0] = wid;
106  height[0] = hei;
107 
108  //Displayable text area
109  //Some parts of y and height are based on the width, not the height, of the text area
110  //If you want to see the area created by this, there's a commented ShowColor() at the end of TextArea::Refresh
111  xcoord[5] = x+(wid*ratio[0])+(wid*vertical_left_of_text);
112  ycoord[5] = y-(wid*ratio[0])-(wid*horizontal_spacer);
113  width[5] = ( wid*(1-ratio[0]-ratio[1]) )-(wid*vertical_left_of_text*2);
114  height[5] = ( hei*(1-ratio[0]) )-(wid*horizontal_spacer*2);
115 
116  //Top scroll button
117  xcoord[1] = x+(wid*button_ratio[0]);
118  ycoord[1] = y-(wid*button_ratio[1]);
119  width[1] = wid*button_ratio[2];
120  height[1] = width[1];
121 
122  //Bottom scroll button
123  xcoord[2] = xcoord[1];
124  ycoord[2] = y-hei+( wid*(button_ratio[2]+button_ratio[1]) );
125  //The original non-working patched formula. I spent so much time fixing this, that this line is to remember it. God knows why.
126  //ycoord[2] = y - (hei * (1 - button_ratio[1] - button_ratio[3]));
127  width[2] = width[1];
128  height[2] = width[1];
129 
130  //Scrollbar Area
131  xcoord[3] = x+(wid*scrollbar_ratio[0]);
132  ycoord[3] = y-(wid*scrollbar_ratio[1]);
133  width[3] = wid*scrollbar_ratio[2];
134  //height[3] = hei * scrollbar_ratio[3];
135  height[3] = hei-(height[1]+height[2])-( (height[2]*scrollbar_ratio[3])*2 );
136 
137  //Static portion of the active scrollbar
138  xcoord[4] = xcoord[3];
139  width[4] = width[3];
140 
141  max_lines = (height[5]/text_spacing)-1;
142 
143  Refresh();
144 }
145 
146 void TextArea::Refresh( void )
147 {
148  float x = xcoord[0], y = ycoord[0], wid = width[0], hei = height[0];
149  //Local x,y,wid,hei for images to render
150  float lx = 0;
151  float ly = 0;
152  float lwid = 0;
153  float lhei = 0;
154 
155  //Ratio border and scrollbar
156  //float ratio[] = { 0.06, 0.12 };
157 
158  lwid = ratio[0]*wid;
159  lhei = ratio[1]*wid;
160  //Draw the bars to run across the length
161 /*
162  * // Top Horizontal
163  * lx = x;
164  * ly = y;
165  * ShowImage(lx, ly, wid, lwid, Images[IMG_TOP], 1, 0);
166  *
167  * // Left Horizontal
168  * ShowImage(lx, ly, lwid, hei, Images[IMG_LEFT_SIDE], 0, 1);
169  *
170  * // Bottom Horizontal
171  * ly = y - hei + lwid;
172  * ShowImage(lx, ly, wid, lwid, Images[IMG_BOTTOM], 1, 0);
173  *
174  * // Right Horizontal
175  * ly = y;
176  * lx = x + wid - lhei;
177  * if (has_scrollbar != 0) { ShowImage(lx, ly, lhei, hei, Images[IMG_RIGHT_SIDE], 0, 1); }
178  *
179  *
180  * // Draw the corners
181  *
182  * // Top right corner
183  * if (has_scrollbar != 0) { ShowImage(lx, ly, lhei, lhei, Images[IMG_CORNER_TOP_RIGHT], 0, 0); }
184  * else { ShowImage(lx, ly, lhei, lhei, Images[IMG_END], 0, 0); }
185  *
186  * // Bottom right corner
187  * ly = y - hei + lhei;
188  * if (has_scrollbar != 0) { ShowImage(lx, ly, lhei, lhei, Images[IMG_CORNER_BOTTOM_RIGHT], 0, 0); }
189  * else { ShowImage(lx, ly, lhei, lhei, Images[IMG_END], 0, 0); }
190  *
191  * // Bottom left corner
192  * lx = x;
193  * ly = y - hei + lwid;
194  * ShowImage(lx, ly, lwid, lwid, Images[IMG_CORNER_BOTTOM_LEFT], 0, 0);
195  *
196  * // Top left corner
197  * ly = y;
198  * ShowImage(lx, ly, lwid, lwid, Images[IMG_CORNER_TOP_LEFT], 0, 0);
199  *
200  * if (button_pressed == 1) {
201  * ShowImage(xcoord[1], ycoord[1], width[1], height[1], Images[IMG_HIGHLIGHT_BUTTON_UP], 0, 0);
202  * }
203  * if (button_pressed == 2) {
204  * ShowImage(xcoord[2], ycoord[2], width[2], height[2], Images[IMG_HIGHLIGHT_BUTTON_DOWN], 0, 0);
205  * }
206  */
207  if (has_scrollbar != 0) DisplayScrollbar();
208  RenderText();
209 //if (cur_highlighted > 0 && cur_highlighted != (cur_selected - top_item_number)) { HighlightCount(cur_highlighted, 1); }
210  if (cur_highlighted > 0) HighlightCount( cur_highlighted, 1 ); //if (cur_selected > 0) { HighlightCount(cur_selected - top_item_number, 2); }
211  if (cur_selected > 0) HighlightCount( cur_selected, 2 );
212  //Displays a transparent red box in the area where text can be displayed
213  //ShowColor(xcoord[5], ycoord[5], width[5], height[5], 1, 0, 0, 0.5);
214 
215  //Displays a transparent green box in the area where the buttons should be
216  //ShowColor(xcoord[1], ycoord[1], width[1], height[1], 0, 1, 0, 0.5);
217  //ShowColor(xcoord[2], ycoord[2], width[2], height[2], 0, 1, 0, 0.5);
218 
219  //Displays a transparent yellow box in the area where the scrollbar should be
220  //ShowColor(xcoord[3], ycoord[3], width[3], height[3], 1, 1, 0, 0.5);
221 
222  //ShowColor(xcoord[3], ycoord[3], width[3], height[3], 0.51, 0.47, 0.79, 1);
223  //ShowColor(xcoord[3], ycoord[3], width[3], height[3]/2, 0.66, 0.6, 1, 1);
224  //ShowColor(xcoord[3], ycoord[3], width[3], height[3]/2, 0, 1,1, 0.05);
225 
226  //ShowColor(xcoord[3], ycoord[3], width[3], height[3]/2, 1, 0, 0, 0.05);
227 
228  //ShowImage(xcoord[3], ycoord[3], width[3], height[3], Images[IMG_SCROLLBAR], 0, 1);
229 }
230 
232 {
233  if (item_count == 0) return;
234  //There's a bug in glut_support. Can't show a color then text. Have to render an image between colors and text
235  //ShowImage(0,0,0,0, Images[0], 0, 0);
236  RenderTextItem( ItemList, 0 );
237 }
238 void TextArea::RenderTextItem( TextAreaItem *current, int level )
239 {
240  static int count = 0;
241  float new_y = 0, new_x = 0;
242  int max = 0;
243  int cur = 0;
244  if (current == 0) return;
245  if (level == 0) count = 0;
246  if ( (count-top_item_number) >= max_lines ) return;
247  if (level > 0) {
248  if (count < top_item_number) {count++; } else {
249  new_y = ycoord[5]-( text_spacing*(count+1-top_item_number) )+horizontal_spacer;
250  new_x = xcoord[5]+( horizontal_per_level*(level-1) );
251  GFXColorf( current->col );
252  ShowText( new_x, new_y, width[5], font_size, current->description, do_multiline );
253  count++;
254  }
255  }
256  max = current->child_count;
257  if (max <= 0) return;
258  for (cur = 0; cur < max; cur++)
259  RenderTextItem( current->child[cur], level+1 );
260 }
261 void TextArea::AddTextItem( const char *name, const char *description, const char *parent_name, const GFXColor col )
262 {
263  TextAreaItem *master;
264  master = ItemList->FindChild( parent_name );
265  item_count++;
266  if (master == NULL) ItemList->AddChild( name, description, col );
267 
268  else master->AddChild( name, description, col );
269 }
270 
271 void TextArea::ChangeTextItem( const char *name, const char *description, bool wrap )
272 {
273  TextAreaItem *search;
274  search = ItemList->FindChild( name );
275  if (search == 0) return;
276  if (search->description != 0) free( search->description );
277  search->description = strdup( description );
278 }
279 
280 void TextArea::ChangeTextItemColor( const char *name, const GFXColor &col )
281 {
282  TextAreaItem *search;
283  search = ItemList->FindChild( name );
284  if (search == 0) return;
285  search->col = col;
286 }
287 
289 {
290  //Wipe the list clean
291  if (ItemList != NULL) delete ItemList;
292  item_count = 0;
293  cur_selected = 0;
294  top_item_number = 0;
295  ItemList = new TextAreaItem( "", "", NULL );
296 }
297 
298 void TextArea::SetText( const char *text )
299 {
300  do_highlight = 0;
301  do_multiline = 1;
302  ClearList();
303  ChompIntoItems( text, NULL );
304 }
305 
307 {
308  return GetSelectedItem( 1 );
309 }
311 {
312  return GetSelectedItem( 2 );
313 }
314 
315 char* TextArea::GetSelectedItem( int type )
316 {
317  TextAreaItem *search;
318  search = ItemList->FindCount( cur_selected, 0 );
319  if (search == 0) return '\0';
320  if (type == 1) return search->name;
321 
322  else return search->description;
323 }
324 
325 void TextArea::SortList( void )
326 {
327  ItemList->Sort();
328 }
329 
330 //The button checks assume that the scroll buttons and scrollbar are on the same x axis
331 //If you change the position of the buttons, you'll need to add more checks here
332 int TextArea::MouseClick( int button, int state, float x, float y )
333 {
334  if (state == WS_MOUSE_UP && scroll_start != 0) {
335  scroll_cur = 0;
336  scroll_start = 0;
337  return 1;
338  }
339  if (Inside( x, y, 0 ) == 0) return 0;
340  if (button != WS_LEFT_BUTTON) return 1; //Don't have anything to do with the middle and right button
341  //Check to see if the cursor is in the same x axis as the buttons and scrollbar
342  if ( x > xcoord[1] && x < (xcoord[1]+width[1]) ) {
343  //Find out if the click is on a button, the scrollbar, or nowhere
344  if ( y < ycoord[1] && y > (ycoord[1]-height[1]) ) {
345  if (state == WS_MOUSE_UP) {
346  //ShowImage(xcoord[1], ycoord[1], width[1], height[1], Images[IMG_BUTTON_UP], 0, 0);
347  button_pressed = 0;
348  } else {
349  //ShowImage(xcoord[1], ycoord[1], width[1], height[1], Images[IMG_HIGHLIGHT_BUTTON_UP], 0, 0);
350  button_pressed = 1;
351 
352  top_item_number--;
353  if (top_item_number < 0) top_item_number = 0;
354  if (cur_selected < 0) cur_selected = 0;
355  }
356  }
357  if ( y < ycoord[2] && y > (ycoord[2]-height[2]) ) {
358  if (state == WS_MOUSE_UP) {
359  //ShowImage(xcoord[2], ycoord[2], width[2], height[2], Images[IMG_BUTTON_DOWN], 0, 0);
360  button_pressed = 0;
361  } else {
362  //ShowImage(xcoord[2], ycoord[2], width[2], height[2], Images[IMG_HIGHLIGHT_BUTTON_DOWN], 0, 0);
363  button_pressed = 2;
364 
365  top_item_number++;
366  if ( top_item_number >= (item_count-max_lines) ) {
367  //This is to avoid a compile time warning.
368  #ifdef NO_WARNINGS
369  float tmp = item_count-max_lines;
370  char LINE[10];
371  sprintf( LINE, "%.0f", tmp );
372  top_item_number = atoi( LINE );
373  #else
374  top_item_number = item_count-max_lines;
375  #endif //NO_WARNINGS
376  }
377  }
378  }
379  }
380  if (Inside( x, y, 5 ) != 0 && do_highlight > 0)
381  cur_selected = LocateCount( y );
382  if (Inside( x, y, 3 ) != 0 && Inside( x, y, 4 ) == 0) {
383  if (state != WS_MOUSE_UP) return 1; //We're outside the active scroll bar, but in the passive area. The active scrollbar is only for MouseMoveClick
384  if (y > ycoord[4]) {
385  //Top area
386  top_item_number -= page_size;
387  if (top_item_number < 0) top_item_number = 0;
388  } else {
389  //Bottom area
390  top_item_number += page_size;
391  if ( top_item_number >= (item_count-max_lines) ) {
392  #ifdef NO_WARNINGS
393  float tmp = item_count-max_lines;
394  char LINE[10];
395  sprintf( LINE, "%.0f", tmp );
396  top_item_number = atoi( LINE );
397  #else
398  top_item_number = item_count-max_lines;
399  #endif //NO_WARNINGS
400  }
401  }
402  }
403  if ( Inside( x, y, 4 ) )
404  scroll_start = y;
405  return 1;
406 }
407 int TextArea::MouseMove( float x, float y )
408 {
409  if (do_highlight == 0) return 0;
410  if (Inside( x, y, 5 ) == 0) return 0;
411  cur_highlighted = LocateCount( y );
412  return 1;
413 }
414 int TextArea::MouseMoveClick( float x, float y )
415 {
416  if (scroll_start == 0 && Inside( x, y, 4 ) == 0) return 0;
417  if (scroll_start == 0) scroll_start = y;
418  scroll_cur = y;
419  return 1;
420 }
421 
422 int TextArea::DoMouse( int type, float x, float y, int button, int state )
423 {
424  if (type == 1) return MouseClick( button, state, x, y );
425  if (type == 2) return MouseMoveClick( x, y );
426  if (type == 3) return MouseMove( x, y );
427  return 0;
428 }
429 
430 int TextArea::Inside( float x, float y, int group )
431 {
432  if (x < xcoord[group] || y > ycoord[group]) return 0;
433  if ( x > (xcoord[group]+width[group]) ) return 0;
434  if ( y < (ycoord[group]-height[group]) ) return 0;
435  return 1;
436 }
437 
438 void TextArea::LoadTextures( void )
439 {
440  /*
441  * int cur, max;
442  * static int images_loaded = 0;
443  * if (images_loaded == 1) { return; } // We've already loaded the images from a previous TextArea class
444  * else { images_loaded = 1; }
445  *
446  * max = 0;
447  * while (LoadImages[max] != NULL) { max++; }
448  * Images = new GUITexture [max];
449  * #ifdef DEBUG
450  * cout << "Loading " << max << " images\n";
451  * #endif
452  * for (cur = 0; cur < max; cur++) {
453  * Images[cur] = ReadTex(LoadImages[cur]);
454  * #ifdef DEBUG
455  * cout << "\tLoading: #" << cur << ": " << LoadImages[cur] << endl;
456  * #endif
457  * }
458  */
459 }
460 
461 //Assumes the mouse is in the text area
462 int TextArea::LocateCount( float y )
463 {
464  float base = ycoord[5]-y-horizontal_spacer;
465  if (base < 0) return 0;
466  base /= text_spacing;
467  base += 0.5;
468  #ifdef NO_WARNINGS
469  char LINE[1024];
470  sprintf( LINE, "%.0f", base );
471  return atoi( LINE );
472 
473  #else
474  return base;
475  #endif //NO_WARNINGS
476 }
477 
478 void TextArea::HighlightCount( int count, int type )
479 {
480  float x = 0, y = 0;
481  if (count <= 0 || count > max_lines+1) return;
482  y = ycoord[5]-( text_spacing*(count-1) )-horizontal_spacer+( ( text_spacing-(font_size_float/100) )/2 );
483  x = xcoord[5];
484  if (count <= this->ItemList->child_count) {
485  if (type == 1) ShowColor( x, y, width[5], text_spacing, 1, 1, 1, 0.25 );
486  if (type == 2) ShowColor( x, y, width[5], text_spacing, 0.2, 0.2, 0.4, 0.5 );
487  }
488 }
489 
490 void TextArea::DisplayScrollbar( void )
491 {
492  float new_y = 0, new_height = 0, item_perc = 0, page_perc = 0, y_dist = 0;
493  ShowColor( xcoord[3], ycoord[3], width[3], height[3], 0.51, 0.47, 0.79, 1 );
494  if (item_count <= max_lines) {
495  ShowColor( xcoord[3], ycoord[3], width[3], height[3], 0.66, 0.6, 1, 1 );
496  ShowColor( xcoord[3], ycoord[3], width[3], height[3], 0, 1, 1, 0.05 );
497  return;
498  }
499  //The percentage that each item consists of the entire list
500  item_perc = item_count;
501  item_perc = 1/item_perc;
502 
503  //The percentage that the visible list takes of the entire list
504  page_perc = max_lines;
505  page_perc /= item_count;
506  //If this isn't 0, the scrollbar is being moved
507  if (scroll_cur != 0) {
508  float move = ( (scroll_cur-scroll_start)/height[3] )/item_perc;
509  int change = 0;
510  #ifdef NO_WARNINGS
511  char LINE[10];
512  sprintf( LINE, "%.0f", move );
513  change = atoi( LINE );
514  #else
515  change = move;
516  #endif //NO_WARNINGS
517  if (move < 0) {
518  change *= -1;
519  top_item_number += change;
520  if ( top_item_number >= (item_count-max_lines) ) {
521  #ifdef NO_WARNINGS
522  sprintf( LINE, "%.0f", item_count-max_lines );
523  top_item_number = atoi( LINE );
524  #else
525  top_item_number = item_count-max_lines;
526  #endif //NO_WARNINGS
527  }
528  } else {
529  top_item_number -= change;
530  if (top_item_number < 0) top_item_number = 0;
531  }
532  if (change != 0) scroll_start = scroll_cur;
533  }
534  //How much is scrolled up past the view
535  y_dist = item_perc*top_item_number;
536 
537  new_y = ycoord[3]-(y_dist*height[3]);
538  new_height = page_perc*height[3];
539 
540  ycoord[4] = new_y;
541  height[4] = new_height;
542 
543  ShowColor( xcoord[3], new_y, width[3], new_height, 0.66, 0.6, 1, 1 );
544  if (scroll_start == 0)
545  ShowColor( xcoord[3], new_y, width[3], new_height, 0, 1, 1, 0.05 );
546  else
547  ShowColor( xcoord[3], new_y, width[3], new_height, 1, 0, 0, 0.05 );
548 }
549 
550 void TextArea::ChompIntoItems( const char *text, const char *parent )
551 {
552  char *temp = strdup( text );
553  char *cur = temp, chr = '\0';
554  int i = 0, max = strlen( temp );
555  float cur_width = 0, wid = 0, end = glutStrokeWidth( GLUT_STROKE_ROMAN, 'A' );
556  end /= 2500;
557  wid = end;
558  for (i = 0; i <= max; i++) {
559  if (temp[i] == '\r') continue;
560  cur_width = WidthOfChar( temp[i] );
561  if (wid+cur_width > width[5] || temp[i] == '\n') {
562  chr = temp[i];
563  temp[i] = '\0';
564  AddTextItem( "content", cur, parent );
565  temp[i] = chr;
566  cur = &temp[i];
567  if (cur[0] == '\n') cur++;
568  wid = end;
569  } else {wid += cur_width; }}
570  if (temp[i] != '\0') AddTextItem( "content", cur, parent );
571  free( temp );
572 }
573 
574 /*TextAreaItem::TextAreaItem(void) {
575  * TextAreaItem("blank","", NULL);
576  * }*/
577 //#include <stdlib.h>
578 //#define rnd (((float)rand())/((float)RAND_MAX))
579 TextAreaItem::TextAreaItem( const char *new_name, const char *desc, TextAreaItem *parent_class ) :
580  col( 1, 1, 1, 1 )
581 {
582 //{ col = GFXColor (rnd,rnd,rnd,1);
583  if (new_name != 0) name = strdup( new_name );
584 
585  else name = 0;
586  if (desc != 0) description = strdup( desc );
587 
588  else description = 0;
590  child_count = 0;
591  child = NULL;
592  parent = NULL;
593 //if (parent == NULL) { expanded = 1; }
594 }
595 
597 {
598  int cur = 0;
599  if (name != NULL) free( name );
600  if (description != NULL) free( description ); //if there are no children, it won't run through this for
601  for (cur = 0; cur < child_count; cur++)
602  if (child[cur] != NULL) delete child[cur];
603  if (child != NULL) delete child;
604 }
605 
606 TextAreaItem* TextAreaItem::FindChild( const char *search_name )
607 {
608  int cur = 0;
609  //int max = child_count_multiplier * 10;
610  TextAreaItem *match;
611  if (search_name == NULL) return this;
612  if (strcmp( name, search_name ) == 0) return this;
613  for (cur = 0; cur < child_count; cur++) {
614  match = child[cur]->FindChild( search_name );
615  if (match != NULL) return match;
616  }
617  return NULL;
618 }
619 
620 void TextAreaItem::Sort( void )
621 {
622  int cur, cur2;
623  TextAreaItem *temp;
624  for (cur = 0; cur < child_count; cur++) {
625  child[cur]->Sort();
626  for (cur2 = 0; cur2 < child_count-1; cur2++)
627  if (strcmp( child[cur2]->description, child[cur2+1]->description ) > 0) {
628  temp = child[cur2];
629  child[cur2] = child[cur2+1];
630  child[cur2+1] = temp;
631  }
632  }
633 }
634 
635 TextAreaItem* TextAreaItem::FindCount( int count, int cur )
636 {
637  static int current = 0;
638  if (cur == 0) current = 0; //int max = child_count_multiplier * 10;
639  TextAreaItem *match;
640  if (count == current) return this;
641  current++;
642  for (cur = 0; cur < child_count; cur++) {
643  match = child[cur]->FindCount( count, cur+1 );
644  if (match != NULL) return match;
645  }
646  return NULL;
647 }
648 
650 
651 void TextAreaItem::AddChild( const char *new_name, const char *desc, const GFXColor col )
652 {
653  TextAreaItem **newlist;
654  int cur = 0;
655  child_count++;
658  newlist = new TextAreaItemStr[child_count_multiplier*10];
659  if (child != NULL) {
660  for (cur = 0; cur < child_count-1; cur++)
661  newlist[cur] = child[cur];
662  delete child;
663  }
664  child = newlist;
665  }
666  child[child_count-1] = new TextAreaItem( new_name, desc, NULL );
667  child[child_count-1]->col = col;
668 }
669