LIST.H 21 KB

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