ListBox.cpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. //
  20. // ListBox.CPP
  21. //
  22. // History:
  23. // 01/13/97 JMI Started.
  24. //
  25. // 01/15/97 JMI SetProp() now takes the Key parm first and the Item parm
  26. // second. Changed this module to reflect that.
  27. //
  28. // 01/15/97 JMI Added overrides of base class's Save/LoadChildren() to
  29. // implement special cases for m_sbVert, Horz, &
  30. // m_lcContents. List items saved and then loaded will not
  31. // be recognized as list items by this class. This should
  32. // eventually be supported so one can save a list of items.
  33. //
  34. // 01/15/97 JMI Since loading of list items does not work properly, any
  35. // list items in m_lcContents are destroyed immediately
  36. // after they are loaded.
  37. //
  38. // 01/20/97 JMI UpdateScrollBarVisibility() was not working correctly for
  39. // Hidden. Fixed.
  40. //
  41. // 01/21/97 JMI Added ReadMembers() and WriteMembers() overloads to read
  42. // and write members of this class. Note that they call the
  43. // base class version to read/write base class members.
  44. // Support exists for versions 0 and 1. Version 0 did not
  45. // contain other than RGuiItem members.
  46. //
  47. // 01/21/97 JMI RemoveItem() was not considering the possibly that the
  48. // item being removed might be the selected item.
  49. // No longer sizes an encapsulator/string item to
  50. // m_sLargestWidth until the AdjustContents() call.
  51. //
  52. // 01/21/97 JMI Changed m_frmContents (RFrame) to m_lcContents
  53. // (RListContents).
  54. //
  55. // 01/23/97 JMI EnsureVisible() had an error that made it think that
  56. // some items that were list items were not.
  57. //
  58. // 02/05/97 JMI Changed position of default: case in ReadMembers().
  59. // And made CreateStringItem() use m_typeEncapsulator as
  60. // the type of the created encapsulator.
  61. // Note that CreateEncapsulator() still only uses RTxts.
  62. //
  63. // 02/25/97 JMI SaveChildren() now goes through the children in reverse
  64. // order so they, on load, get added back to their parent in
  65. // the order they were originally added to this parent.
  66. //
  67. // 03/28/97 JMI Now AdjustContents() adjusts vertical scroll bar incs
  68. // so that the buttons will advance one item and the tray
  69. // will scroll visible items - 1.
  70. //
  71. // 04/10/97 JMI Now uses m_sFontCellHeight instead of GetPos() to get
  72. // cell height.
  73. //
  74. // 05/25/97 JMI Added GetFirst(), GetNext(), and GetPrev().
  75. //
  76. // 06/15/97 JMI List items are now at least as wide as the viewable area.
  77. //
  78. // 08/11/97 JMI Seemed like there was a potential for infinite loop in
  79. // GetNext() and GetPrev().
  80. // Also, GetFirst() returned the first item in the list
  81. // w/o checking if it was an encapsulator.
  82. //
  83. // 09/01/97 JMI Added MakeEncapsulator().
  84. //
  85. // 09/07/97 JMI Now EnsureVisible() accepts an optional position
  86. // preference so you can bias the location of your item.
  87. //
  88. // 09/24/97 JMI Calls to InsertAfter() and InsertBefore() had their
  89. // parameters backward.
  90. //
  91. //////////////////////////////////////////////////////////////////////////////
  92. //
  93. // This a GUI item that is based on the basic RGuiItem.
  94. // This overrides HotCall() to get information about where a click in its RHot
  95. // occurred.
  96. // This overrides Compose() to create the scrollable area and compose
  97. // the scrollbars.
  98. //
  99. // Enhancements/Uses:
  100. // Not yet known.
  101. //
  102. //////////////////////////////////////////////////////////////////////////////
  103. //////////////////////////////////////////////////////////////////////////////
  104. // Headers.
  105. //////////////////////////////////////////////////////////////////////////////
  106. #include "Blue.h"
  107. #ifdef PATHS_IN_INCLUDES
  108. #include "ORANGE/GUI/ListBox.h"
  109. #include "ORANGE/GUI/txt.h"
  110. #else
  111. #include "listbox.h"
  112. #include "txt.h"
  113. #endif // PATHS_IN_INCLUDES
  114. //////////////////////////////////////////////////////////////////////////////
  115. // Module specific macros.
  116. //////////////////////////////////////////////////////////////////////////////
  117. // Sets val to def if val is -1.
  118. #define DEF(val, def) ((val == -1) ? def : val)
  119. // Default width for vertical scrollbar and height for horizontal scrollbar.
  120. #define DEF_SCROLL_THICKNESS 13
  121. // Space between items.
  122. #define ITEM_SPACING m_sBorderThickness
  123. // Scrollbar priority is very high so it will be above other siblings.
  124. #define SCROLLBAR_PRIORITY ((short)0x8001)
  125. // Frame should be lower priority so that scrollbars are 'on top' of it.
  126. #define FRAME_PRIORITY ((short)0x7FFF)
  127. //////////////////////////////////////////////////////////////////////////////
  128. // Module specific typedefs.
  129. //////////////////////////////////////////////////////////////////////////////
  130. //////////////////////////////////////////////////////////////////////////////
  131. // Module specific (static) variables.
  132. //////////////////////////////////////////////////////////////////////////////
  133. //////////////////////////////////////////////////////////////////////////////
  134. // Construction/Destruction.
  135. //////////////////////////////////////////////////////////////////////////////
  136. //////////////////////////////////////////////////////////////////////////////
  137. //
  138. // Default constructor.
  139. //
  140. //////////////////////////////////////////////////////////////////////////////
  141. RListBox::RListBox()
  142. {
  143. // Override defaults for this.
  144. m_type = ListBox; // Indicates type of GUI item.
  145. m_sInvertedBorder = TRUE; // Want sunken look.
  146. // Override defaults for children.
  147. m_sbVert.m_im.m_sWidth = DEF_SCROLL_THICKNESS;
  148. m_sbVert.m_oOrientation = RScrollBar::Vertical;
  149. m_sbVert.m_upcUser = ScrollCall;
  150. m_sbVert.m_ulUserInstance = (ULONG)this;
  151. // Priority for scrollbars should be higher than any other sibling.
  152. m_sbVert.m_hot.SetPriority(SCROLLBAR_PRIORITY);
  153. m_sbHorz.m_im.m_sHeight = DEF_SCROLL_THICKNESS;
  154. m_sbHorz.m_oOrientation = RScrollBar::Horizontal;
  155. m_sbHorz.m_upcUser = ScrollCall;
  156. m_sbHorz.m_ulUserInstance = (ULONG)this;
  157. // Priority for scrollbars should be higher than any other sibling.
  158. m_sbHorz.m_hot.SetPriority(SCROLLBAR_PRIORITY);
  159. // Priority for frame is low.
  160. m_lcContents.m_hot.SetPriority(FRAME_PRIORITY);
  161. // Set defaults for direct members.
  162. m_sbvVert = ShownAsNeeded;
  163. m_sbvHorz = ShownAsNeeded;
  164. m_sLargestWidth = 0;
  165. m_pguiSel = NULL;
  166. m_typeEncapsulator = Txt;
  167. }
  168. //////////////////////////////////////////////////////////////////////////////
  169. //
  170. // Destructor.
  171. //
  172. //////////////////////////////////////////////////////////////////////////////
  173. RListBox::~RListBox()
  174. {
  175. // Remove all items and destroy their encapsulators.
  176. RemoveAll();
  177. }
  178. ////////////////////////////////////////////////////////////////////////
  179. // Methods.
  180. ////////////////////////////////////////////////////////////////////////
  181. //////////////////////////////////////////////////////////////////////////////
  182. //
  183. // Creates a displayable Listbox item.
  184. //
  185. //////////////////////////////////////////////////////////////////////////////
  186. short RListBox::Create( // Returns 0 on success.
  187. short sX, // X position relative to "parent" item.
  188. short sY, // Y position relative to "parent" item.
  189. short sW, // Width.
  190. short sH, // Height.
  191. short sDepth) // Color depth.
  192. {
  193. short sRes = 0; // Assume success.
  194. Destroy();
  195. m_sX = sX;
  196. m_sY = sY;
  197. if (m_im.CreateImage(sW, sH, RImage::BMP8, 0, sDepth) == 0)
  198. {
  199. // Done.
  200. // If there's an error after calling CreateImage, perhaps
  201. // we should destroy the RImage data here.
  202. if (sRes != 0)
  203. {
  204. Destroy();
  205. }
  206. }
  207. else
  208. {
  209. TRACE("Create(): RImage::CreateImage() failed.\n");
  210. sRes = -1;
  211. }
  212. // Get client area.
  213. short sClientX, sClientY, sClientW, sClientH;
  214. GetClient(&sClientX, &sClientY, &sClientW, &sClientH);
  215. // Create child items:
  216. CopyParms(&m_lcContents);
  217. m_lcContents.m_sBorderThickness = 0;
  218. // Frame is created in AdjustContents() call.
  219. m_lcContents.SetParent(this);
  220. CopyParms(&m_sbVert);
  221. if (m_sbVert.Create(
  222. sClientX + sClientW - m_sbVert.m_im.m_sWidth,
  223. sClientY,
  224. m_sbVert.m_im.m_sWidth,
  225. sClientH,
  226. sDepth) == 0)
  227. {
  228. m_sbVert.SetParent(this);
  229. }
  230. else
  231. {
  232. TRACE("Create(): m_sbVert.Create() failed.\n");
  233. // Don't use this.
  234. m_sbVert.SetParent(NULL);
  235. }
  236. CopyParms(&m_sbHorz);
  237. if (m_sbHorz.Create(
  238. sClientX,
  239. sClientY + sClientH - m_sbHorz.m_im.m_sHeight,
  240. sClientW - m_sbVert.m_im.m_sWidth,
  241. m_sbHorz.m_im.m_sHeight,
  242. sDepth) == 0)
  243. {
  244. m_sbHorz.SetParent(this);
  245. }
  246. else
  247. {
  248. TRACE("Create(): m_sbHorz.Create() failed.\n");
  249. // Don't use this.
  250. m_sbHorz.SetParent(NULL);
  251. }
  252. // Compose this item.
  253. Compose();
  254. return sRes;
  255. }
  256. ////////////////////////////////////////////////////////////////////////
  257. //
  258. // Compose item.
  259. //
  260. ////////////////////////////////////////////////////////////////////////
  261. void RListBox::Compose( // Returns nothing.
  262. RImage* pim /*= NULL*/) // Dest image, uses m_im if NULL.
  263. {
  264. if (pim == NULL)
  265. {
  266. pim = &m_im;
  267. }
  268. // Call base (draws border and background).
  269. RGuiItem::Compose(pim);
  270. // Resizes all encapsulators, m_lcContents, and sets scroll ranges.
  271. AdjustContents();
  272. // No text.
  273. }
  274. ////////////////////////////////////////////////////////////////////////
  275. //
  276. // Add a string into the list box.
  277. //
  278. ////////////////////////////////////////////////////////////////////////
  279. RGuiItem* RListBox::AddString( // Returns new GUI item on success.
  280. char* pszString, // String to add.
  281. RGuiItem* pguiAfter /*= NULL*/) // Gui to add after or NULL to add at
  282. // end.
  283. {
  284. // Create a new string item . . .
  285. RGuiItem* pguiRes = CreateStringItem(pszString);
  286. if (pguiRes != NULL)
  287. {
  288. // Reposition item.
  289. AddAfter(pguiRes, pguiAfter);
  290. }
  291. else
  292. {
  293. TRACE("AddString(): CreateStringItem() failed.\n");
  294. }
  295. return pguiRes;
  296. }
  297. ////////////////////////////////////////////////////////////////////////
  298. //
  299. // Insert a string into the list box.
  300. //
  301. ////////////////////////////////////////////////////////////////////////
  302. RGuiItem* RListBox::InsertString( // Returns new GUI item on success.
  303. char* pszString, // String to insert.
  304. RGuiItem* pguiBefore /*= NULL*/) // Gui to insert before or NULL to
  305. // insert at beginning.
  306. {
  307. // Create a new string item . . .
  308. RGuiItem* pguiRes = CreateStringItem(pszString);
  309. if (pguiRes != NULL)
  310. {
  311. // Reposition item.
  312. InsertBefore(pguiRes, pguiBefore);
  313. }
  314. else
  315. {
  316. TRACE("InsertString(): CreateStringItem() failed.\n");
  317. }
  318. return pguiRes;
  319. }
  320. ////////////////////////////////////////////////////////////////////////
  321. //
  322. // Add an item into the list box.
  323. //
  324. ////////////////////////////////////////////////////////////////////////
  325. RGuiItem* RListBox::AddItem( // Returns new GUI item or pgui on
  326. // success. Depends on sEncapsulate.
  327. RGuiItem* pgui, // GUI item to insert.
  328. short sEncapsulate /*= FALSE*/, // If TRUE, this item will be
  329. // encapsulated in an RGuiItem that
  330. // will be returned on success.
  331. // If FALSE, this item will be a direct
  332. // child of the listbox and will be
  333. // returned on success.
  334. RGuiItem* pguiAfter /*= NULL*/) // Gui to add after or NULL to add at
  335. // end.
  336. {
  337. RGuiItem* pguiRes = NULL; // Assume nothing.
  338. // If encapsulation requested . . .
  339. if (sEncapsulate != FALSE)
  340. {
  341. // Create encapsulator item.
  342. pguiRes = CreateEncapsulator(pgui);
  343. }
  344. else
  345. {
  346. // The item is the item to be placed in the listbox.
  347. pguiRes = pgui;
  348. }
  349. // If we have the item to be added . . .
  350. if (pguiRes != NULL)
  351. {
  352. // Make child of list area.
  353. pguiRes->SetParent(&m_lcContents);
  354. // Reposition item.
  355. AddAfter(pguiRes, pguiAfter);
  356. }
  357. else
  358. {
  359. TRACE("AddItem(): CreateEncapsulator() failed.\n");
  360. }
  361. return pguiRes;
  362. }
  363. ////////////////////////////////////////////////////////////////////////
  364. //
  365. // Insert an item into the list box.
  366. //
  367. ////////////////////////////////////////////////////////////////////////
  368. RGuiItem* RListBox::InsertItem( // Returns new GUI item or pgui on
  369. // success. Depends on sEncapsulate.
  370. RGuiItem* pgui, // GUI item to insert.
  371. short sEncapsulate /*= FALSE*/, // If TRUE, this item will be
  372. // encapsulated in an RGuiItem that
  373. // will be returned on success.
  374. // If FALSE, this item will be a direct
  375. // child of the listbox and will be
  376. // returned on success.
  377. RGuiItem* pguiBefore /*= NULL*/) // Gui to insert before or NULL to
  378. // insert at beginning.
  379. {
  380. RGuiItem* pguiRes = NULL; // Assume nothing.
  381. // If encapsulation requested . . .
  382. if (sEncapsulate != FALSE)
  383. {
  384. // Create encapsulator item.
  385. pguiRes = CreateEncapsulator(pgui);
  386. }
  387. else
  388. {
  389. // The item is the item to be placed in the listbox.
  390. pguiRes = pgui;
  391. }
  392. // If we have the item to be added . . .
  393. if (pguiRes != NULL)
  394. {
  395. // Make child of list area.
  396. pguiRes->SetParent(&m_lcContents);
  397. // Reposition item.
  398. InsertBefore(pguiRes, pguiBefore);
  399. }
  400. else
  401. {
  402. TRACE("AddItem(): CreateEncapsulator() failed.\n");
  403. }
  404. return pguiRes;
  405. }
  406. ////////////////////////////////////////////////////////////////////////
  407. //
  408. // Remove an item from the list box and destroy encapsulator, if an
  409. // encapsulator exists for that item.
  410. //
  411. ////////////////////////////////////////////////////////////////////////
  412. void RListBox::RemoveItem( // Returns nothing.
  413. RGuiItem* pgui) // Item to remove. NOTE: Any
  414. // encapsulating GUI item will be
  415. // destroyed.
  416. {
  417. // Verify item is a list item and get encapsulator, if any:
  418. RGuiItem* pguiParent = pgui->GetParent();
  419. RGuiItem* pguiRemove = NULL;
  420. if (pguiParent != NULL)
  421. {
  422. // If parent is the list container . . .
  423. if (pguiParent == &m_lcContents)
  424. {
  425. // Set item to remove.
  426. pguiRemove = pgui;
  427. }
  428. else
  429. {
  430. // If parent's parent is the list container . . .
  431. if (pguiParent->GetParent() == &m_lcContents)
  432. {
  433. // Free from encapsulator.
  434. pgui->SetParent(NULL);
  435. // Set item to remove.
  436. pguiRemove = pguiParent;
  437. }
  438. }
  439. }
  440. // If there is an item to remove . . .
  441. if (pguiRemove != NULL)
  442. {
  443. // If this item is an encapsulator . . .
  444. if (IsEncapsulator(pguiRemove) != FALSE)
  445. {
  446. // If this item was the selected item . . .
  447. if (pguiRemove == m_pguiSel)
  448. {
  449. // Clear selection.
  450. SetSel(NULL);
  451. }
  452. // Remove encapsulator prop.
  453. pguiRemove->RemoveProp(ENCAPSULATOR_PROP_KEY);
  454. // Destroy item.
  455. delete pguiRemove;
  456. }
  457. else
  458. {
  459. // If dynamic . . .
  460. if (pguiRemove->IsDynamic() != FALSE)
  461. {
  462. delete pguiRemove;
  463. }
  464. }
  465. }
  466. else
  467. {
  468. TRACE("RemoveItem(): Specified item is not an item of this listbox.\n");
  469. }
  470. }
  471. ////////////////////////////////////////////////////////////////////////
  472. //
  473. // Remove all items and encapsulators in listbox.
  474. // Calls RemoveItem() for each item.
  475. //
  476. ////////////////////////////////////////////////////////////////////////
  477. void RListBox::RemoveAll(void) // Returns nothing.
  478. {
  479. RGuiItem* pgui = m_lcContents.m_listguiChildren.GetHead();
  480. while (pgui != NULL)
  481. {
  482. RemoveItem(pgui);
  483. pgui = m_lcContents.m_listguiChildren.GetNext();
  484. }
  485. }
  486. ////////////////////////////////////////////////////////////////////////
  487. //
  488. // Ensure the specified item is within the client of the listbox.
  489. //
  490. ////////////////////////////////////////////////////////////////////////
  491. void RListBox::EnsureVisible( // Returns nothing.
  492. RGuiItem* pgui, // Item to ensure visibility of.
  493. Position posPreference /*= Top*/) // In: Preferred vertical position.
  494. {
  495. short sX = pgui->m_sX;
  496. short sY = pgui->m_sY;
  497. // Take position of item to list contents level.
  498. RGuiItem* pguiParent = pgui->GetParent();
  499. while (pguiParent != NULL && pguiParent != &m_lcContents)
  500. {
  501. sX += pguiParent->m_sX;
  502. sY += pguiParent->m_sY;
  503. pguiParent = pguiParent->GetParent();
  504. }
  505. // If we got to the list contents . . .
  506. if (pguiParent != NULL)
  507. {
  508. // Set new position for list contents such that item
  509. // is in upper left corner of client.
  510. short sClientX, sClientY, sClientH;
  511. GetClient(&sClientX, &sClientY, NULL, &sClientH);
  512. switch (posPreference)
  513. {
  514. case Top:
  515. m_lcContents.Move(-sX + sClientX, -sY + sClientY);
  516. break;
  517. case Middle:
  518. m_lcContents.Move(-sX + sClientX, -sY + sClientY + (sClientH - pgui->m_im.m_sHeight) / 2);
  519. break;
  520. case Bottom:
  521. m_lcContents.Move(-sX + sClientX, -sY + sClientY + sClientH - pgui->m_im.m_sHeight);
  522. break;
  523. }
  524. // Update the scrollbars.
  525. UpdateScrollBars();
  526. }
  527. else
  528. {
  529. TRACE("EnsureVisible(): Specified gui is not a member of this "
  530. "listbox.\n");
  531. }
  532. }
  533. ////////////////////////////////////////////////////////////////////////
  534. //
  535. // Set the selection to the specified GUI item.
  536. //
  537. ////////////////////////////////////////////////////////////////////////
  538. void RListBox::SetSel( // Returns nothing.
  539. RGuiItem* pgui) // Item to select or NULL for none.
  540. {
  541. // If new selection is different than current . . .
  542. if (pgui != m_pguiSel)
  543. {
  544. // Unselect item.
  545. SelectItem(m_pguiSel, FALSE);
  546. // Set new selection.
  547. m_pguiSel = pgui;
  548. // Select item.
  549. SelectItem(m_pguiSel, TRUE);
  550. }
  551. }
  552. ////////////////////////////////////////////////////////////////////////
  553. //
  554. // Update scrollbar visibility based on current listbox contents and
  555. // their visibility.
  556. //
  557. ////////////////////////////////////////////////////////////////////////
  558. void RListBox::UpdateScrollBarVisibility(void) // Returns nothing.
  559. {
  560. // Get client.
  561. short sClientX, sClientY, sClientW, sClientH;
  562. GetClient(&sClientX, &sClientY, &sClientW, &sClientH);
  563. // If visibility is not prohibited . . .
  564. if (m_sbvVert != Hidden)
  565. {
  566. // If the vertical scrollbar should be visible . . .
  567. if (m_lcContents.m_im.m_sHeight > sClientH - m_sbHorz.m_im.m_sHeight || m_sbvVert == Shown)
  568. {
  569. m_sbVert.m_sVisible = TRUE;
  570. }
  571. else
  572. {
  573. m_sbVert.m_sVisible = FALSE;
  574. }
  575. }
  576. else
  577. {
  578. m_sbVert.m_sVisible = FALSE;
  579. }
  580. // If visibility is not prohibited . . .
  581. if (m_sbvHorz != Hidden)
  582. {
  583. // If the horizontal scrollbar should be visible . . .
  584. if (m_lcContents.m_im.m_sWidth > sClientW - m_sbVert.m_im.m_sWidth || m_sbvHorz == Shown)
  585. {
  586. m_sbHorz.m_sVisible = TRUE;
  587. }
  588. else
  589. {
  590. m_sbHorz.m_sVisible = FALSE;
  591. }
  592. }
  593. else
  594. {
  595. m_sbHorz.m_sVisible = FALSE;
  596. }
  597. // Activate scrollbars according to their visibility and current
  598. // activation status of listbox.
  599. m_sbVert.SetActive(m_sbVert.m_sVisible && IsActivated());
  600. m_sbHorz.SetActive(m_sbHorz.m_sVisible && IsActivated());
  601. }
  602. ////////////////////////////////////////////////////////////////////////
  603. //
  604. // Resize encapsulators to fit the largest encapsulated item or string,
  605. // reposition all items to appear in the correct order, resize scrollable
  606. // area (m_lcContents) to fit all listbox items, and update scrollbar
  607. // ranges accordingly.
  608. //
  609. ////////////////////////////////////////////////////////////////////////
  610. void RListBox::AdjustContents(void) // Returns nothing.
  611. {
  612. // Get client.
  613. short sClientX, sClientY, sClientW, sClientH;
  614. GetClient(&sClientX, &sClientY, &sClientW, &sClientH);
  615. // Minimum is viewable area (when vertical scrollbar shown).
  616. m_sLargestWidth = sClientW - m_sbVert.m_im.m_sWidth;
  617. long lTotalHeight = 0; // Used for averaging heights.
  618. long lTotalItems = 0; // Used for averaging heights.
  619. // Get largest width.
  620. RGuiItem* pguiItem = m_lcContents.m_listguiChildren.GetHead();
  621. while (pguiItem != NULL)
  622. {
  623. // If width is larger than largest . . .
  624. if (pguiItem->m_im.m_sWidth > m_sLargestWidth)
  625. {
  626. m_sLargestWidth = pguiItem->m_im.m_sWidth;
  627. }
  628. // Get next item.
  629. pguiItem = m_lcContents.m_listguiChildren.GetNext();
  630. }
  631. // Go through children sizing encapsulators to m_sLargestWidth and
  632. // repositioning items as we go.
  633. short sY = 0;
  634. pguiItem = m_lcContents.m_listguiChildren.GetHead();
  635. while (pguiItem != NULL)
  636. {
  637. // Reposition.
  638. pguiItem->Move(pguiItem->m_sX, sY);
  639. // If this is an encapsulator . . .
  640. if (IsEncapsulator(pguiItem) != FALSE)
  641. {
  642. // If there's a change in width . . .
  643. if (pguiItem->m_im.m_sWidth != m_sLargestWidth)
  644. {
  645. // Recreate item . . .
  646. if (pguiItem->Create(
  647. pguiItem->m_sX,
  648. pguiItem->m_sY,
  649. m_sLargestWidth,
  650. pguiItem->m_im.m_sHeight,
  651. pguiItem->m_im.m_sDepth) == 0)
  652. {
  653. }
  654. else
  655. {
  656. TRACE("AdustContents(): pguiItem->Create() failed.\n");
  657. }
  658. }
  659. }
  660. // Adjust position for next item by this item's height and the
  661. // item spacing.
  662. sY += pguiItem->m_im.m_sHeight + ITEM_SPACING;
  663. // Keep total height so we can average it to determine scrollbar
  664. // increments.
  665. lTotalHeight += pguiItem->m_im.m_sHeight + ITEM_SPACING;
  666. lTotalItems++;
  667. // Get next item.
  668. pguiItem = m_lcContents.m_listguiChildren.GetNext();
  669. }
  670. // New height and/or width for container . . .
  671. if (m_lcContents.Create(
  672. m_lcContents.m_sX,
  673. m_lcContents.m_sY,
  674. m_sLargestWidth,
  675. sY - ITEM_SPACING,
  676. m_lcContents.m_im.m_sDepth) == 0)
  677. {
  678. }
  679. else
  680. {
  681. TRACE("AdjustContents(): m_lcContents.Create() failed.\n");
  682. }
  683. // Update scrollbar visibility.
  684. UpdateScrollBarVisibility();
  685. // Set scroll ranges:
  686. // The scrollable range is the length of the frame minus the size of
  687. // the area that can be viewed. This is subtracted from the client
  688. // position to so it is already mapped directly into 'this's
  689. // coordinate system.
  690. // If the horizontal scrollbar is visible . . .
  691. short sScrollBarH = 0;
  692. if (m_sbHorz.m_sVisible != FALSE)
  693. {
  694. // Compensation:
  695. sScrollBarH = m_sbHorz.m_im.m_sHeight;
  696. }
  697. // If viewable area is smaller than list area . . .
  698. if (m_lcContents.m_im.m_sHeight > sClientH - sScrollBarH)
  699. {
  700. m_sbVert.SetRange(
  701. -sClientY,
  702. (m_lcContents.m_im.m_sHeight - (sClientH - sScrollBarH)) - sClientY);
  703. }
  704. else
  705. {
  706. m_sbVert.SetRange(
  707. -sClientY,
  708. -sClientY);
  709. }
  710. // If the vertical scrollbar is visible . . .
  711. short sScrollBarW = 0;
  712. if (m_sbVert.m_sVisible != FALSE)
  713. {
  714. // Compensation:
  715. sScrollBarW = m_sbVert.m_im.m_sWidth;
  716. }
  717. // If viewable area is smaller than list area . . .
  718. if (m_lcContents.m_im.m_sWidth > sClientW - sScrollBarW)
  719. {
  720. m_sbHorz.SetRange(
  721. -sClientX,
  722. (m_lcContents.m_im.m_sWidth - (sClientW - sScrollBarW)) - sClientX);
  723. }
  724. else
  725. {
  726. m_sbHorz.SetRange(
  727. -sClientX,
  728. -sClientX);
  729. }
  730. // Calculate average height of item.
  731. long lAvgHeight = 0;
  732. if (lTotalItems > 0)
  733. {
  734. lAvgHeight = (short)(lTotalHeight / lTotalItems);
  735. }
  736. // Update vertical scroll bar increments:
  737. // Clicking buttons should scroll one item at a time.
  738. m_sbVert.m_lButtonIncDec = lAvgHeight;
  739. // Clicking tray should scroll visible items - 1 at a time.
  740. m_sbVert.m_lTrayIncDec = (sClientH - sScrollBarH) - lAvgHeight;
  741. // Safety . . .
  742. if (m_sbVert.m_lTrayIncDec <= 0)
  743. {
  744. m_sbVert.m_lTrayIncDec = lAvgHeight;
  745. }
  746. // Update scroll positions.
  747. UpdateScrollBars();
  748. }
  749. ////////////////////////////////////////////////////////////////////////
  750. //
  751. // Update scrollbars' positions. This function is called by
  752. // AdjustContents() and EnsureVisible(), so there is no need to call it
  753. // after calling one of those functions.
  754. //
  755. ////////////////////////////////////////////////////////////////////////
  756. void RListBox::UpdateScrollBars(void)
  757. {
  758. m_sbVert.SetPos(-m_lcContents.m_sY);
  759. m_sbHorz.SetPos(-m_lcContents.m_sX);
  760. }
  761. ////////////////////////////////////////////////////////////////////////
  762. // Querries.
  763. ////////////////////////////////////////////////////////////////////////
  764. ////////////////////////////////////////////////////////////////////////
  765. // Get the first child item.
  766. ////////////////////////////////////////////////////////////////////////
  767. RGuiItem* RListBox::GetFirst(void) // Returns the first child item or
  768. // NULL.
  769. {
  770. // Find first encapsulator.
  771. RGuiItem* pguiFirst = m_lcContents.m_listguiChildren.GetHead();
  772. while (pguiFirst != NULL)
  773. {
  774. if (IsEncapsulator(pguiFirst) != FALSE)
  775. {
  776. break;
  777. }
  778. pguiFirst = m_lcContents.m_listguiChildren.GetNext();
  779. }
  780. return pguiFirst;
  781. }
  782. ////////////////////////////////////////////////////////////////////////
  783. // Get the next child item after the specified item.
  784. ////////////////////////////////////////////////////////////////////////
  785. RGuiItem* RListBox::GetNext( // Returns the next child item.
  786. RGuiItem* pgui) // In: Child item that precedes the next.
  787. {
  788. RGuiItem* pguiNext = m_lcContents.m_listguiChildren.GetNext(pgui);
  789. while (pguiNext != NULL)
  790. {
  791. if (IsEncapsulator(pguiNext) != FALSE)
  792. {
  793. break;
  794. }
  795. pguiNext = m_lcContents.m_listguiChildren.GetNext();
  796. }
  797. return pguiNext;
  798. }
  799. ////////////////////////////////////////////////////////////////////////
  800. // Get the child item before the specified item.
  801. ////////////////////////////////////////////////////////////////////////
  802. RGuiItem* RListBox::GetPrev( // Returns the previous child item or NULL.
  803. RGuiItem* pgui) // In: Child item that follows the prev.
  804. {
  805. RGuiItem* pguiPrev = m_lcContents.m_listguiChildren.GetPrev(pgui);
  806. while (pguiPrev != NULL)
  807. {
  808. if (IsEncapsulator(pguiPrev) != FALSE)
  809. {
  810. break;
  811. }
  812. pguiPrev = m_lcContents.m_listguiChildren.GetPrev();
  813. }
  814. return pguiPrev;
  815. }
  816. ////////////////////////////////////////////////////////////////////////
  817. // Internals.
  818. ////////////////////////////////////////////////////////////////////////
  819. ////////////////////////////////////////////////////////////////////////
  820. //
  821. // Creates an item appropriate for the specified string and makes it
  822. // a child of this listbox.
  823. //
  824. ////////////////////////////////////////////////////////////////////////
  825. RGuiItem* RListBox::CreateStringItem( // Returns new item on success;
  826. // NULL, otherwise.
  827. char* pszString) // Text for new item.
  828. {
  829. RGuiItem* pgui = NULL; // Assume nothing.
  830. short sError = 0;
  831. // We'll need a font and a print for this.
  832. ASSERT(m_pprint != NULL);
  833. ASSERT(m_pprint->GetFont() != NULL);
  834. // Allocate a new item . . .
  835. pgui = CreateGuiItem(m_typeEncapsulator);
  836. if (pgui != NULL)
  837. {
  838. // Copy parms to new item.
  839. CopyParms(pgui);
  840. // Set callback.
  841. pgui->m_bcUser = PressedCall;
  842. pgui->m_ulUserInstance = (ULONG)this;
  843. // Get thickness of border.
  844. short sBorder = pgui->GetTopLeftBorderThickness()
  845. + pgui->GetBottomRightBorderThickness();
  846. // Get the width of the desired string.
  847. short sWidth = m_pprint->GetWidth(pszString);
  848. short sHeight = m_sFontCellHeight;
  849. // Adjust by border thickness.
  850. sWidth += sBorder;
  851. sHeight += sBorder;
  852. // Set text for item before Create() (Create() calls Compose()).
  853. pgui->SetText(pszString);
  854. // Create item . . .
  855. if (pgui->Create(0, 0, sWidth, sHeight, m_im.m_sDepth) == 0)
  856. {
  857. // Make child of list area.
  858. pgui->SetParent(&m_lcContents);
  859. // Remember to delete this item.
  860. MakeEncapsulator(pgui);
  861. // Item position is not set until the next AdjustContents() call.
  862. }
  863. else
  864. {
  865. TRACE("CreateStringItem(): ptxt->Create() failed.\n");
  866. sError = 2;
  867. }
  868. // If any errors occurred after allocation . . .
  869. if (sError != 0)
  870. {
  871. delete pgui;
  872. pgui = NULL;
  873. }
  874. }
  875. else
  876. {
  877. TRACE("CreateStringItem(): Failed to allocate encapsulator of type %s.\n",
  878. ms_apszTypes[m_typeEncapsulator]);
  879. sError = 1;
  880. }
  881. return pgui;
  882. }
  883. ////////////////////////////////////////////////////////////////////////
  884. //
  885. // Creates an encapsulator object for the specified GUI.
  886. //
  887. ////////////////////////////////////////////////////////////////////////
  888. RGuiItem* RListBox::CreateEncapsulator( // Returns new item on success; NULL,
  889. // otherwise.
  890. RGuiItem* pgui) // Item to encapsulate.
  891. {
  892. RGuiItem* pguiRes = NULL; // Assume nothing.
  893. short sError = 0;
  894. // Allocate a new item . . .
  895. pguiRes = new RGuiItem;
  896. if (pguiRes != NULL)
  897. {
  898. // Copy parms to new item.
  899. CopyParms(pguiRes);
  900. // Set callback.
  901. pguiRes->m_bcUser = PressedCall;
  902. pguiRes->m_ulUserInstance = (ULONG)this;
  903. // Get thickness of border.
  904. short sBorder = pguiRes->GetTopLeftBorderThickness()
  905. + pguiRes->GetBottomRightBorderThickness();
  906. // Get the width and height of the encapsulated item.
  907. short sWidth = pgui->m_im.m_sWidth;
  908. short sHeight = pgui->m_im.m_sHeight;
  909. // Adjust by border thickness.
  910. sWidth += sBorder;
  911. sHeight += sBorder;
  912. // Create item . . .
  913. if (pguiRes->Create(0, 0, sWidth, sHeight, m_im.m_sDepth) == 0)
  914. {
  915. // Make item a child of encapsulator.
  916. pgui->SetParent(pguiRes);
  917. // Mark item as an encapsulator.
  918. MakeEncapsulator(pguiRes);
  919. // Item position is not set until the next AdjustContents() call.
  920. }
  921. else
  922. {
  923. TRACE("CreateEncapsulator(): pguiRes->Create() failed.\n");
  924. sError = 2;
  925. }
  926. // If any errors occurred after allocation . . .
  927. if (sError != 0)
  928. {
  929. delete pguiRes;
  930. pguiRes = NULL;
  931. }
  932. }
  933. else
  934. {
  935. TRACE("CreateEncapsulator(): Failed to allocate RTxt.\n");
  936. sError = 1;
  937. }
  938. return pguiRes;
  939. }
  940. //////////////////////////////////////////////////////////////////////////////
  941. //
  942. // Place item at specified location in list of container's child items.
  943. // Under new pretenses, this should not fail.
  944. //
  945. //////////////////////////////////////////////////////////////////////////////
  946. void RListBox::AddAfter( // Returns nothing.
  947. RGuiItem* pgui, // Item to add.
  948. RGuiItem* pguiAfter) // Item to add after or NULL to add at
  949. // end.
  950. {
  951. // Reposition the new item. Under new pretenses, this SHOULD not fail.
  952. m_lcContents.m_listguiChildren.Remove(pgui);
  953. // If none specified . . .
  954. if (pguiAfter == NULL)
  955. {
  956. // Insert new item. Under new pretenses, this SHOULD not fail.
  957. m_lcContents.m_listguiChildren.AddTail(pgui);
  958. }
  959. else
  960. {
  961. // Insert new item. Under new pretenses, this SHOULD not fail.
  962. m_lcContents.m_listguiChildren.InsertAfter(pguiAfter, pgui);
  963. }
  964. }
  965. //////////////////////////////////////////////////////////////////////////////
  966. //
  967. // Place item at specified location in list of container's child items.
  968. // Under new pretenses, this should not fail.
  969. //
  970. //////////////////////////////////////////////////////////////////////////////
  971. void RListBox::InsertBefore( // Returns nothing.
  972. RGuiItem* pgui, // Item to insert.
  973. RGuiItem* pguiBefore) // Item to insert before or NULL to insert
  974. // at beginning.
  975. {
  976. // Reposition the new item. Under new pretenses, this SHOULD not fail.
  977. m_lcContents.m_listguiChildren.Remove(pgui);
  978. // If none specified . . .
  979. if (pguiBefore == NULL)
  980. {
  981. // Insert new item. Under new pretenses, this SHOULD not fail.
  982. m_lcContents.m_listguiChildren.InsertHead(pgui);
  983. }
  984. else
  985. {
  986. // Insert new item. Under new pretenses, this SHOULD not fail.
  987. m_lcContents.m_listguiChildren.InsertBefore(pguiBefore, pgui);
  988. }
  989. }
  990. //////////////////////////////////////////////////////////////////////////////
  991. //
  992. // [Un]Select the specified item.
  993. //
  994. //////////////////////////////////////////////////////////////////////////////
  995. void RListBox::SelectItem( // Returns nothing.
  996. RGuiItem* pguiSel, // Item to [un]select.
  997. short sSelect) // If TRUE, item is selected; if FALSE,
  998. // item is unselected.
  999. {
  1000. // If there was previously a selection . . .
  1001. if (pguiSel != NULL)
  1002. {
  1003. // If this is an encapsulation . . .
  1004. if (IsEncapsulator(pguiSel) != FALSE)
  1005. {
  1006. // Toggle border.
  1007. pguiSel->m_sInvertedBorder = sSelect;
  1008. // Recompose item with new border effect.
  1009. pguiSel->Compose();
  1010. }
  1011. }
  1012. }
  1013. ////////////////////////////////////////////////////////////////////////
  1014. //
  1015. // Load item's children from the specified file.
  1016. // (virtual override).
  1017. // (protected).
  1018. //
  1019. ////////////////////////////////////////////////////////////////////////
  1020. short RListBox::LoadChildren( // Returns 0 on success.
  1021. RFile* pfile) // File to load from.
  1022. {
  1023. short sRes = 0; // Assume success.
  1024. ASSERT(pfile->IsOpen() != FALSE);
  1025. short sNum;
  1026. // Read number of children.
  1027. pfile->Read(&sNum);
  1028. // The first three are our scrollbars and frame.
  1029. ASSERT(sNum >= 3);
  1030. // Load directly into these special children.
  1031. if (m_sbVert.Load(pfile) == 0)
  1032. {
  1033. if (m_sbHorz.Load(pfile) == 0)
  1034. {
  1035. // m_lcContents needs to know its parent during Load() (specifically
  1036. // LoadChildren() needs to know).
  1037. m_lcContents.SetParent(this);
  1038. if (m_lcContents.Load(pfile) == 0)
  1039. {
  1040. // Subtract these three children from total.
  1041. sNum -= 3;
  1042. }
  1043. else
  1044. {
  1045. TRACE("LoadChildren(): m_sbVert.Load() failed.\n");
  1046. sRes = -3;
  1047. }
  1048. }
  1049. else
  1050. {
  1051. TRACE("LoadChildren(): m_sbHorz.Load() failed.\n");
  1052. sRes = -2;
  1053. }
  1054. }
  1055. else
  1056. {
  1057. TRACE("LoadChildren(): m_lcContents.Load() failed.\n");
  1058. sRes = -1;
  1059. }
  1060. // Instantiate rest of children.
  1061. RGuiItem* pgui;
  1062. short sCurChild;
  1063. for ( sCurChild = 0;
  1064. sCurChild < sNum && sRes == 0 && pfile->Error() == FALSE;
  1065. sCurChild++)
  1066. {
  1067. pgui = LoadInstantiate(pfile);
  1068. if (pgui != NULL)
  1069. {
  1070. pgui->SetParent(this);
  1071. }
  1072. else
  1073. {
  1074. TRACE("LoadChildren(): LoadInstantiate() failed.\n");
  1075. sRes = -1;
  1076. }
  1077. }
  1078. return sRes;
  1079. }
  1080. ////////////////////////////////////////////////////////////////////////
  1081. //
  1082. // Save item's children to the specified file.
  1083. // (virtual override).
  1084. // (protected).
  1085. //
  1086. ////////////////////////////////////////////////////////////////////////
  1087. short RListBox::SaveChildren( // Returns 0 on success.
  1088. RFile* pfile) // File to save to.
  1089. {
  1090. short sRes = 0; // Assume success.
  1091. ASSERT(pfile->IsOpen() != FALSE);
  1092. // Determine number of child items.
  1093. short sNum = 0;
  1094. RGuiItem* pgui = m_listguiChildren.GetHead();
  1095. while (pgui != NULL)
  1096. {
  1097. sNum++;
  1098. pgui = m_listguiChildren.GetNext();
  1099. }
  1100. // Write number of children.
  1101. pfile->Write(sNum);
  1102. // These should definitely be children of 'this' item.
  1103. ASSERT(m_sbVert.GetParent() == this);
  1104. ASSERT(m_sbHorz.GetParent() == this);
  1105. ASSERT(m_lcContents.GetParent() == this);
  1106. // Always write our 3 special children (scrollbars & frame) first so we know
  1107. // where to get them on load.
  1108. if (m_sbVert.Save(pfile) == 0)
  1109. {
  1110. if (m_sbHorz.Save(pfile) == 0)
  1111. {
  1112. if (m_lcContents.Save(pfile) == 0)
  1113. {
  1114. // Subtract these three children from total.
  1115. // Currently this number is not used during save,
  1116. // but just in case it ever is.
  1117. sNum -= 3;
  1118. }
  1119. else
  1120. {
  1121. TRACE("SaveChildren(): m_lcContents.Save() failed.\n");
  1122. sRes = -3;
  1123. }
  1124. }
  1125. else
  1126. {
  1127. TRACE("SaveChildren(): m_sbHorz.Save() failed.\n");
  1128. sRes = -2;
  1129. }
  1130. }
  1131. else
  1132. {
  1133. TRACE("SaveChildren(): m_sbVert.Save() failed.\n");
  1134. sRes = -1;
  1135. }
  1136. // Save children. Note that we go through the children in reverse
  1137. // order so they, on load, get added back to their parent in the
  1138. // order they were originally added to this parent.
  1139. pgui = m_listguiChildren.GetTail();
  1140. while (pgui != NULL && sRes == 0 && pfile->Error() == FALSE)
  1141. {
  1142. // Don't write these 3 again . . .
  1143. if (pgui != &m_sbVert && pgui != &m_sbHorz && pgui != &m_lcContents)
  1144. {
  1145. // Save child.
  1146. sRes = pgui->Save(pfile);
  1147. }
  1148. pgui = m_listguiChildren.GetPrev();
  1149. }
  1150. return sRes;
  1151. }
  1152. ////////////////////////////////////////////////////////////////////////
  1153. //
  1154. // Read item's members from file.
  1155. // (virtual/protected (overriden here)).
  1156. //
  1157. ////////////////////////////////////////////////////////////////////////
  1158. short RListBox::ReadMembers( // Returns 0 on success.
  1159. RFile* pfile, // File to read from.
  1160. U32 u32Version) // File format version to use.
  1161. {
  1162. short sRes = 0; // Assume success.
  1163. // Invoke base class to read base members.
  1164. sRes = RGuiItem::ReadMembers(pfile, u32Version);
  1165. // If okay so far . . .
  1166. if (sRes == 0)
  1167. {
  1168. ASSERT(pfile != NULL);
  1169. ASSERT(pfile->IsOpen() != FALSE);
  1170. U32 u32Temp;
  1171. // Switch on version.
  1172. switch (u32Version)
  1173. {
  1174. default:
  1175. // Insert additional version numbers here!
  1176. // case 4: // Version 4 stuff.
  1177. // case 3: // Version 3 stuff.
  1178. case 2: // Version 2 added encapsulator type.
  1179. pfile->Read(&u32Temp);
  1180. m_typeEncapsulator = (Type)u32Temp;
  1181. case 1:
  1182. // Read this class's members.
  1183. pfile->Read(&u32Temp);
  1184. m_sbvVert = (ScrollBarVisibility)u32Temp;
  1185. pfile->Read(&u32Temp);
  1186. m_sbvHorz = (ScrollBarVisibility)u32Temp;
  1187. case 0: // In version 0, only base class RGuiItem members were stored.
  1188. // If successful . . .
  1189. if (pfile->Error() == FALSE)
  1190. {
  1191. // Success.
  1192. }
  1193. else
  1194. {
  1195. TRACE("ReadMembers(): Error reading RListBox members.\n");
  1196. sRes = -1;
  1197. }
  1198. break;
  1199. }
  1200. }
  1201. return sRes;
  1202. }
  1203. ////////////////////////////////////////////////////////////////////////
  1204. //
  1205. // Write item's members to file.
  1206. // (virtual/protected (overriden here)).
  1207. //
  1208. ////////////////////////////////////////////////////////////////////////
  1209. short RListBox::WriteMembers( // Returns 0 on success.
  1210. RFile* pfile) // File to write to.
  1211. {
  1212. short sRes = 0; // Assume success.
  1213. // Invoke base class to read base members.
  1214. sRes = RGuiItem::WriteMembers(pfile);
  1215. // If okay so far . . .
  1216. if (sRes == 0)
  1217. {
  1218. ASSERT(pfile != NULL);
  1219. ASSERT(pfile->IsOpen() != FALSE);
  1220. // Write this class's members.
  1221. ////////////// Version 2 ////////////////////
  1222. pfile->Write((U32)m_typeEncapsulator);
  1223. ////////////// Version 1 ////////////////////
  1224. pfile->Write((U32)m_sbvVert);
  1225. pfile->Write((U32)m_sbvHorz);
  1226. ////////////// Version 0 ////////////////////
  1227. // If successful . . .
  1228. if (pfile->Error() == FALSE)
  1229. {
  1230. // Success.
  1231. }
  1232. else
  1233. {
  1234. TRACE("WriteMembers(): Error writing RListBox members.\n");
  1235. sRes = -1;
  1236. }
  1237. }
  1238. return sRes;
  1239. }
  1240. //////////////////////////////////////////////////////////////////////////////
  1241. // EOF
  1242. //////////////////////////////////////////////////////////////////////////////