LIST.H 21 KB

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