LIST.H (21114B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/LIST.H 1 3/03/97 10:25a Joe_bostic $ */ 17 /*********************************************************************************************** 18 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : LIST.H * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 01/15/95 * 28 * * 29 * Last Update : January 15, 1995 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 34 35 #ifndef LIST_H 36 #define LIST_H 37 38 #include "control.h" 39 #include "shapebtn.h" 40 #include "slider.h" 41 42 43 /*************************************************************************** 44 * ListClass -- Like a Windows ListBox structure * 45 * * 46 * INPUT: int x -- x position of gadget * 47 * int y -- y position of gadget * 48 * int w -- width of gadget * 49 * int h -- height of gadget * 50 * UWORD flags -- see enumeration choices * 51 * * 52 * OUTPUT: none. * 53 * WARNINGS: * 54 * HISTORY: 01/03/1995 MML : Created. * 55 *=========================================================================*/ 56 class ListClass : public ControlClass 57 { 58 public: 59 ListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down); 60 ListClass(ListClass const & list); 61 virtual ~ListClass(void); 62 63 virtual int Add_Item(char const * text); 64 virtual int Add_Item(int text); 65 virtual int Add_Scroll_Bar(void); 66 virtual void Bump(int up); 67 virtual int Count(void) const {return List.Count();}; 68 virtual int Current_Index(void) const; 69 virtual char const * Current_Item(void) const; 70 virtual int Draw_Me(int forced); 71 virtual char const * Get_Item(int index) const; 72 virtual int Step_Selected_Index(int forward); 73 virtual void Flag_To_Redraw(void); 74 75 virtual void Peer_To_Peer(unsigned flags, KeyNumType & key, ControlClass & whom); 76 virtual void Remove_Item(char const * text); 77 virtual void Remove_Item(int); 78 virtual int Remove_Scroll_Bar(void); 79 virtual void Set_Selected_Index(int index); 80 virtual void Set_Selected_Index(char const * text); 81 virtual void Set_Tabs(int const * tabs); 82 virtual int Set_View_Index(int index); 83 virtual void Step(int up); 84 virtual void Set_Position(int x, int y); 85 86 /* 87 ** These overloaded list routines handle adding/removing the scroll bar 88 ** automatically when the list box is added or removed. 89 */ 90 virtual LinkClass & Add(LinkClass & object); 91 virtual LinkClass & Add_Tail(LinkClass & object); 92 virtual LinkClass & Add_Head(LinkClass & object); 93 virtual GadgetClass * Remove(void); 94 95 protected: 96 virtual int Action(unsigned flags, KeyNumType &key); 97 virtual void Draw_Entry(int index, int x, int y, int width, int selected); 98 99 /* 100 ** This controls what the text looks like. It uses the basic TPF_ flags that 101 ** are used to control Fancy_Text_Print(). 102 */ 103 TextPrintType TextFlags; 104 105 /* 106 ** This is a series of tabstop pixel positions to use when processing any 107 ** <TAB> characters found in a list box string. The tabs are a series of 108 ** pixel offsets from the starting pixel position of the text. 109 */ 110 int const *Tabs; 111 112 /* 113 ** The actual list of text pointers is maintained by this list manager. The pointers 114 ** are stored in EMS. The text that is pointed to may also be in EMS. 115 */ 116 DynamicVectorClass<char const *> List; 117 118 /* 119 ** This is the total pixel height of a standard line of text. This is greatly 120 ** influenced by the TextFlags value. 121 */ 122 int LineHeight; 123 124 /* 125 ** This is the number of text lines that can fit within the list box. 126 */ 127 int LineCount; 128 129 /* 130 ** If the slider bar has been created, these point to the respective gadgets 131 ** that it is composed of. 132 */ 133 unsigned IsScrollActive:1; 134 ShapeButtonClass UpGadget; 135 ShapeButtonClass DownGadget; 136 SliderClass ScrollGadget; 137 138 /* 139 ** This is the currently selected index. It is highlighted. 140 */ 141 int SelectedIndex; 142 143 /* 144 ** This specifies the line (index) that is at the top of the list box. 145 */ 146 int CurrentTopIndex; 147 }; 148 149 150 template<class T> 151 class TListClass : public ControlClass 152 { 153 public: 154 TListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down); 155 TListClass(TListClass<T> const & list); 156 virtual ~TListClass(void); 157 T operator [] (int index) const {return(List[index]);}; 158 T & operator [] (int index) {return(List[index]);}; 159 160 virtual int Add_Item(T text); 161 virtual int Add_Scroll_Bar(void); 162 virtual void Insert_Item(T item); 163 virtual void Bump(int up); 164 virtual int Count(void) const {return List.Count();}; 165 virtual int Current_Index(void) const; 166 virtual T Current_Item(void) const; 167 virtual int Draw_Me(int forced); 168 virtual int Step_Selected_Index(int forward); 169 virtual void Flag_To_Redraw(void); 170 virtual T Get_Item(int index) const {return(List[index]);}; 171 172 virtual void Peer_To_Peer(unsigned flags, KeyNumType & key, ControlClass & whom); 173 virtual void Remove_Item(T); 174 virtual void Remove_Index(int); 175 virtual int Remove_Scroll_Bar(void); 176 virtual void Set_Selected_Index(int index); 177 virtual void Set_Selected_Index(T item); 178 virtual void Set_Tabs(int const * tabs); 179 virtual int Set_View_Index(int index); 180 virtual void Step(int up); 181 virtual void Set_Position(int x, int y); 182 183 /* 184 ** These overloaded list routines handle adding/removing the scroll bar 185 ** automatically when the list box is added or removed. 186 */ 187 virtual LinkClass & Add(LinkClass & object); 188 virtual LinkClass & Add_Tail(LinkClass & object); 189 virtual LinkClass & Add_Head(LinkClass & object); 190 virtual GadgetClass * Remove(void); 191 192 protected: 193 virtual int Action(unsigned flags, KeyNumType &key); 194 195 /* 196 ** This controls what the text looks like. It uses the basic TPF_ flags that 197 ** are used to control Fancy_Text_Print(). 198 */ 199 TextPrintType TextFlags; 200 201 /* 202 ** This is a series of tabstop pixel positions to use when processing any 203 ** <TAB> characters found in a list box string. The tabs are a series of 204 ** pixel offsets from the starting pixel position of the text. 205 */ 206 int const * Tabs; 207 208 /* 209 ** The actual list of text pointers is maintained by this list manager. 210 */ 211 DynamicVectorClass<T> List; 212 213 /* 214 ** This is the total pixel height of a standard line of text. This is greatly 215 ** influenced by the TextFlags value. 216 */ 217 int LineHeight; 218 219 /* 220 ** This is the number of text lines that can fit within the list box. 221 */ 222 int LineCount; 223 224 /* 225 ** If the slider bar has been created, these point to the respective gadgets 226 ** that it is composed of. 227 */ 228 unsigned IsScrollActive:1; 229 ShapeButtonClass UpGadget; 230 ShapeButtonClass DownGadget; 231 SliderClass ScrollGadget; 232 233 /* 234 ** This is the currently selected index. It is highlighted. 235 */ 236 int SelectedIndex; 237 238 /* 239 ** This specifies the line (index) that is at the top of the list box. 240 */ 241 int CurrentTopIndex; 242 }; 243 244 template<class T> 245 TListClass<T>::TListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down) : 246 ControlClass(id, x, y, w, h, LEFTPRESS | LEFTRELEASE | KEYBOARD, false), 247 UpGadget(0, up, x+w, y), 248 DownGadget(0, down, x+w, y+h), 249 ScrollGadget(0, x+w, y, 0, h, true), 250 TextFlags(flags), 251 Tabs(0), 252 IsScrollActive(false), 253 SelectedIndex(0), 254 CurrentTopIndex(0) 255 { 256 /* 257 ** Set preliminary values for the slider related gadgets. They don't automatically 258 ** appear at this time, but there are some values that can be pre-filled in. 259 */ 260 UpGadget.X -= UpGadget.Width; 261 DownGadget.X -= DownGadget.Width; 262 DownGadget.Y -= DownGadget.Height; 263 ScrollGadget.X -= max(UpGadget.Width, DownGadget.Width); 264 ScrollGadget.Y = Y+UpGadget.Height; 265 ScrollGadget.Height -= UpGadget.Height + DownGadget.Height; 266 ScrollGadget.Width = max(UpGadget.Width, DownGadget.Width); 267 268 /* 269 ** Set the list box to a default state. 270 */ 271 Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TextFlags); 272 LineHeight = FontHeight+FontYSpacing-1; 273 LineCount = (h-1) / LineHeight; 274 } 275 276 template<class T> 277 TListClass<T>::TListClass(TListClass<T> const & list) : 278 ControlClass(list), 279 TextFlags(list.TextFlags), 280 Tabs(list.Tabs), 281 List(list.List), 282 LineHeight(list.LineHeight), 283 LineCount(list.LineCount), 284 IsScrollActive(list.IsScrollActive), 285 UpGadget(list.UpGadget), 286 DownGadget(list.DownGadget), 287 ScrollGadget(list.ScrollGadget), 288 SelectedIndex(list.SelectedIndex), 289 CurrentTopIndex(list.CurrentTopIndex) 290 { 291 UpGadget.Make_Peer(*this); 292 DownGadget.Make_Peer(*this); 293 ScrollGadget.Make_Peer(*this); 294 } 295 296 template<class T> 297 void TListClass<T>::Set_Position(int x, int y) 298 { 299 UpGadget.X = x + Width - UpGadget.Width; 300 UpGadget.Y = y; 301 DownGadget.X = x + Width - DownGadget.Width; 302 DownGadget.Y = y + Height - DownGadget.Height; 303 ScrollGadget.X = x + Width - max(UpGadget.Width, DownGadget.Width); 304 ScrollGadget.Y = y + UpGadget.Height; 305 ScrollGadget.Height = Height - (UpGadget.Height + DownGadget.Height); 306 ScrollGadget.Width = max(UpGadget.Width, DownGadget.Width); 307 } 308 309 template<class T> 310 TListClass<T>::~TListClass(void) 311 { 312 Remove_Scroll_Bar(); 313 } 314 315 template<class T> 316 void TListClass<T>::Insert_Item(T item) 317 { 318 if (Current_Index() >= Count()) { 319 List.Add(item); 320 } else { 321 List.Add(item); 322 323 /* 324 ** Move all trailing items upward. 325 */ 326 for (int index = List.Count()-1; index >= Current_Index(); index--) { 327 List[index+1] = List[index]; 328 } 329 330 /* 331 ** Insert the new item into the location at the current index. 332 */ 333 List[Current_Index()] = item; 334 } 335 } 336 337 338 template<class T> 339 int TListClass<T>::Add_Item(T text) 340 { 341 // if (text) { 342 List.Add(text); 343 Flag_To_Redraw(); 344 345 /* 346 ** Add scroll gadget if the list gets too large to display all of the items 347 ** at the same time. 348 */ 349 if (List.Count() > LineCount) { 350 Add_Scroll_Bar(); 351 } 352 353 /* 354 ** Tell the slider that there is one more entry in the list. 355 */ 356 if (IsScrollActive) { 357 ScrollGadget.Set_Maximum(List.Count()); 358 } 359 // } 360 return(List.Count() - 1); 361 } 362 363 template<class T> 364 void TListClass<T>::Remove_Index(int index) 365 { 366 if ((unsigned)index < List.Count()) { 367 List.Delete(index); 368 369 /* 370 ** If the list is now small enough to display completely within the list box region, 371 ** then delete the slider gadget (if they are present). 372 */ 373 if (List.Count() <= LineCount) { 374 Remove_Scroll_Bar(); 375 } 376 377 /* 378 ** Tell the slider that there is one less entry in the list. 379 */ 380 if (IsScrollActive) { 381 ScrollGadget.Set_Maximum(List.Count()); 382 } 383 384 /* 385 ** If we just removed the selected entry, select the previous one 386 */ 387 if (SelectedIndex >= List.Count()) { 388 SelectedIndex--; 389 if (SelectedIndex < 0) { 390 SelectedIndex = 0; 391 } 392 } 393 394 /* 395 ** If we just removed the top-displayed entry, step up one item 396 */ 397 if (CurrentTopIndex >= List.Count()) { 398 CurrentTopIndex--; 399 if (CurrentTopIndex < 0) 400 CurrentTopIndex = 0; 401 if (IsScrollActive) 402 ScrollGadget.Step(1); 403 } 404 } 405 } 406 407 template<class T> 408 void TListClass<T>::Remove_Item(T text) 409 { 410 Remove_Index(List.ID(text)); 411 } 412 413 template<class T> 414 int TListClass<T>::Action(unsigned flags, KeyNumType & key) 415 { 416 if (flags & LEFTRELEASE) { 417 key = KN_NONE; 418 flags &= (~LEFTRELEASE); 419 ControlClass::Action(flags, key); 420 return(true); 421 } else { 422 423 /* 424 ** Handle keyboard events here. 425 */ 426 if (flags & KEYBOARD) { 427 428 /* 429 ** Process the keyboard character. If indicated, consume this keyboard event 430 ** so that the edit gadget ID number is not returned. 431 */ 432 if (key == KN_UP) { 433 Step_Selected_Index(-1); 434 key = KN_NONE; 435 } else if (key == KN_DOWN) { 436 Step_Selected_Index(1); 437 key = KN_NONE; 438 } else { 439 flags &= ~KEYBOARD; 440 } 441 442 } else { 443 444 int index = Get_Mouse_Y() - (Y+1); 445 index = index / LineHeight; 446 SelectedIndex = CurrentTopIndex + index; 447 SelectedIndex = min(SelectedIndex, List.Count()-1); 448 } 449 } 450 return(ControlClass::Action(flags, key)); 451 } 452 453 template<class T> 454 int TListClass<T>::Draw_Me(int forced) 455 { 456 if (GadgetClass::Draw_Me(forced)) { 457 458 /* 459 ** Turn off the mouse. 460 */ 461 if (LogicPage == &SeenBuff) { 462 Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); 463 } 464 465 Draw_Box(X, Y, Width, Height, BOXSTYLE_BOX, true); 466 467 /* 468 ** Draw List. 469 */ 470 if (List.Count()) { 471 for (int index = 0; index < LineCount; index++) { 472 int line = CurrentTopIndex + index; 473 474 if (List.Count() > line) { 475 476 /* 477 ** Prints the text and handles right edge clipping and tabs. 478 */ 479 List[line]->Draw_It(line, X+1, Y+(LineHeight*index)+1, Width-2, LineHeight, (line == SelectedIndex), TextFlags); 480 // List[index].Draw_It(line, X+1, Y+(LineHeight*index)+1, Width-2, LineHeight, (line == SelectedIndex), TextFlags); 481 // Draw_Entry(line, X+1, Y+(LineHeight*index)+1, Width-2, (line == SelectedIndex)); 482 } 483 } 484 } 485 486 /* 487 ** Turn on the mouse. 488 */ 489 if (LogicPage == &SeenBuff) { 490 Conditional_Show_Mouse(); 491 } 492 return(true); 493 } 494 return(false); 495 } 496 497 template<class T> 498 void TListClass<T>::Bump(int up) 499 { 500 if (IsScrollActive) { 501 if (ScrollGadget.Step(up)) { 502 CurrentTopIndex = ScrollGadget.Get_Value(); 503 Flag_To_Redraw(); 504 } 505 } 506 } 507 508 template<class T> 509 void TListClass<T>::Step(int up) 510 { 511 if (IsScrollActive) { 512 if (ScrollGadget.Step(up)) { 513 CurrentTopIndex = ScrollGadget.Get_Value(); 514 Flag_To_Redraw(); 515 } 516 } 517 } 518 519 #ifdef NEVER 520 template<class T> 521 T TListClass<T>::Get_Item(int index) const 522 { 523 index = min(index, List.Count()); 524 return(List[index]); 525 } 526 #endif 527 528 template<class T> 529 T TListClass<T>::Current_Item(void) const 530 { 531 static T _temp; 532 if (List.Count() <= SelectedIndex) { 533 return(_temp); 534 } 535 return(List[SelectedIndex]); 536 } 537 538 template<class T> 539 int TListClass<T>::Current_Index(void) const 540 { 541 return(SelectedIndex); 542 } 543 544 template<class T> 545 void TListClass<T>::Peer_To_Peer(unsigned flags, KeyNumType &, ControlClass & whom) 546 { 547 if (flags & LEFTRELEASE) { 548 if (&whom == &UpGadget) { 549 Step(true); 550 } 551 if (&whom == &DownGadget) { 552 Step(false); 553 } 554 } 555 556 /* 557 ** The slider has changed, so reflect the current list position 558 ** according to the slider setting. 559 */ 560 if (&whom == &ScrollGadget) { 561 Set_View_Index(ScrollGadget.Get_Value()); 562 } 563 } 564 565 template<class T> 566 int TListClass<T>::Set_View_Index(int index) 567 { 568 index = Bound(index, 0, List.Count() - LineCount); 569 if (index != CurrentTopIndex) { 570 CurrentTopIndex = index; 571 Flag_To_Redraw(); 572 if (IsScrollActive) { 573 ScrollGadget.Set_Value(CurrentTopIndex); 574 } 575 return(true); 576 } 577 return(false); 578 } 579 580 template<class T> 581 int TListClass<T>::Add_Scroll_Bar(void) 582 { 583 if (!IsScrollActive) { 584 IsScrollActive = true; 585 586 /* 587 ** Everything has been created successfully. Flag the list box to be 588 ** redrawn because it now must be made narrower to accomodate the new 589 ** slider gadgets. 590 */ 591 Flag_To_Redraw(); 592 Width -= ScrollGadget.Width; 593 594 /* 595 ** Tell the newly created gadgets that they should inform this list box 596 ** whenever they get touched. In this way, the list box will automatically 597 ** be updated under control of the slider buttons. 598 */ 599 UpGadget.Make_Peer(*this); 600 DownGadget.Make_Peer(*this); 601 ScrollGadget.Make_Peer(*this); 602 603 /* 604 ** Add these newly created gadgets to the same gadget list that the 605 ** list box is part of. 606 */ 607 UpGadget.Add(*this); 608 DownGadget.Add(*this); 609 ScrollGadget.Add(*this); 610 611 /* 612 ** Make sure these added gadgets get redrawn at the next opportunity. 613 */ 614 UpGadget.Flag_To_Redraw(); 615 DownGadget.Flag_To_Redraw(); 616 ScrollGadget.Flag_To_Redraw(); 617 618 /* 619 ** Inform the slider of the size of the window and the current view position. 620 */ 621 ScrollGadget.Set_Maximum(List.Count()); 622 ScrollGadget.Set_Thumb_Size(LineCount); 623 ScrollGadget.Set_Value(CurrentTopIndex); 624 625 /* 626 ** Return with success flag. 627 */ 628 return(true); 629 } 630 return(false); 631 } 632 633 template<class T> 634 int TListClass<T>::Remove_Scroll_Bar(void) 635 { 636 if (IsScrollActive) { 637 IsScrollActive = false; 638 Width += ScrollGadget.Width; 639 ScrollGadget.Remove(); 640 UpGadget.Remove(); 641 DownGadget.Remove(); 642 Flag_To_Redraw(); 643 return(true); 644 } 645 return(false); 646 } 647 648 template<class T> 649 void TListClass<T>::Set_Tabs(int const * tabs) 650 { 651 Tabs = tabs; 652 } 653 654 #ifdef NEVER 655 template<class T> 656 void TListClass<T>::Draw_Entry(int index, int x, int y, int width, int selected) 657 { 658 if (TextFlags & TPF_6PT_GRAD) { 659 TextPrintType flags = TextFlags; 660 661 if (selected) { 662 flags = flags | TPF_BRIGHT_COLOR; 663 LogicPage->Fill_Rect(x, y, x + width - 1, y + LineHeight - 1, CC_GREEN_SHADOW); 664 } else { 665 if (!(flags & TPF_USE_GRAD_PAL)) { 666 flags = flags | TPF_MEDIUM_COLOR; 667 } 668 } 669 670 Conquer_Clip_Text_Print(List[index], x, y, CC_GREEN, TBLACK, flags, width, Tabs); 671 672 } else { 673 Conquer_Clip_Text_Print(List[index], x, y, (selected ? BLUE : WHITE), TBLACK, TextFlags, width, Tabs); 674 } 675 } 676 #endif 677 678 template<class T> 679 LinkClass & TListClass<T>::Add(LinkClass & list) 680 { 681 /* 682 ** Add the scroll bar gadgets if they're active. 683 */ 684 if (IsScrollActive) { 685 ScrollGadget.Add(list); 686 DownGadget.Add(list); 687 UpGadget.Add(list); 688 } 689 690 /* 691 ** Add myself to the list, then return. 692 */ 693 return(ControlClass::Add(list)); 694 } 695 696 template<class T> 697 LinkClass & TListClass<T>::Add_Head(LinkClass & list) 698 { 699 /* 700 ** Add the scroll bar gadgets if they're active. 701 */ 702 if (IsScrollActive) { 703 ScrollGadget.Add_Head(list); 704 DownGadget.Add_Head(list); 705 UpGadget.Add_Head(list); 706 } 707 708 /* 709 ** Add myself to the list, then return. 710 */ 711 return(ControlClass::Add_Head(list)); 712 } 713 714 template<class T> 715 LinkClass & TListClass<T>::Add_Tail(LinkClass & list) 716 { 717 /* 718 ** Add myself to the list. 719 */ 720 ControlClass::Add_Tail(list); 721 722 /* 723 ** Add the scroll bar gadgets if they're active. 724 */ 725 if (IsScrollActive) { 726 UpGadget.Add_Tail(list); 727 DownGadget.Add_Tail(list); 728 ScrollGadget.Add_Tail(list); 729 } 730 731 return(Head_Of_List()); 732 } 733 734 template<class T> 735 GadgetClass * TListClass<T>::Remove(void) 736 { 737 /* 738 ** Remove the scroll bar if it's active 739 */ 740 if (IsScrollActive) { 741 ScrollGadget.Remove(); 742 DownGadget.Remove(); 743 UpGadget.Remove(); 744 } 745 746 /* 747 ** Remove myself & return 748 */ 749 return(ControlClass::Remove()); 750 } 751 752 template<class T> 753 void TListClass<T>::Set_Selected_Index(int index) 754 { 755 if ((unsigned)index < List.Count()) { 756 SelectedIndex = index; 757 Flag_To_Redraw(); 758 if (SelectedIndex < CurrentTopIndex) { 759 Set_View_Index(SelectedIndex); 760 } 761 if (SelectedIndex >= CurrentTopIndex+LineCount) { 762 Set_View_Index(SelectedIndex-(LineCount-1)); 763 } 764 } 765 } 766 767 template<class T> 768 int TListClass<T>::Step_Selected_Index(int step) 769 { 770 int old = SelectedIndex; 771 772 Set_Selected_Index(old + step); 773 return(old); 774 } 775 776 template<class T> 777 void TListClass<T>::Flag_To_Redraw(void) 778 { 779 if (IsScrollActive) { 780 UpGadget.Flag_To_Redraw(); 781 DownGadget.Flag_To_Redraw(); 782 ScrollGadget.Flag_To_Redraw(); 783 } 784 ControlClass::Flag_To_Redraw(); 785 } 786 787 template<class T> 788 void TListClass<T>::Set_Selected_Index(T text) 789 { 790 for (int index = 0; index < Count(); index++) { 791 if (text == Get_Item(index)) { 792 Set_Selected_Index(index); 793 break; 794 } 795 } 796 } 797 798 799 #endif