scrollbar.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  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. // SCROLLBAR.CPP
  21. //
  22. // History:
  23. // 09/25/96 JMI Started.
  24. //
  25. // 10/31/96 JMI Changed:
  26. // Old label: New label:
  27. // ========= =========
  28. // CScrollBar RScrollBar
  29. // CImage RImage
  30. // CGuiItem RGuiItem
  31. // ORIENTATION Orientation
  32. // HORIZONTAL Horizontal
  33. // VERTICAL Vertical
  34. // CBtn RBtn
  35. //
  36. // 11/01/96 JMI Changed:
  37. // Old label: New label:
  38. // ========= =========
  39. // Rect RRect
  40. //
  41. // Also, changed all members referenced in RImage to
  42. // m_ and all position/dimension members referenced in
  43. // RImage to type short usage.
  44. //
  45. // 11/27/96 JMI Added initialization of m_type to identify this type
  46. // of GUI item.
  47. //
  48. // 12/16/96 JMI Now checks for and reports when width or height is too
  49. // small in Compose().
  50. //
  51. // 12/16/96 JMI Now ASSERTs if width or height is too small in DrawArrow.
  52. //
  53. // 12/31/96 JMI Do() now calls base implementation in RGuiItem.
  54. //
  55. // 01/02/97 JMI Overrode GetHot() to use tray area instead of client.
  56. // GetTray() now checks for NULL pointers before assigning
  57. // values. Changed m_guiThumb to m_btnThumb.
  58. //
  59. // 01/02/97 JMI What was the macro ARROW_BORDER_THICKNESS is now the
  60. // member m_sArrowBorderDistance which is initialized to
  61. // DEF_ARROW_BORDER_THICKNESS.
  62. //
  63. // 01/04/97 JMI Upgraded HotCall() to new CursorEvent(). This upgrade
  64. // is in response to RGuiItem now using relative RHots.
  65. // Now m_hot.m_sX/Y is parent item relative just like
  66. // m_sX/Y. This should simplify a lot of stuff and even
  67. // fix some odd features like being able to click a GUI
  68. // item that exceeds the boundary of its parent. This fix
  69. // will be essential for the not-yet-existent RListBox since
  70. // it will most likely scroll many children through a small
  71. // client area.
  72. // Now there are two regions associated with cursor events.
  73. // The first is the 'hot' area. This is the area that m_hot
  74. // is set to include. Child items can only receive cursor
  75. // events through this area. The second is the 'event' area.
  76. // This is the area where the item really is actually con-
  77. // cerned with cursor events. Example: For a Dlg, the
  78. // entire window is the 'hot' area and the title bar is the
  79. // 'event' area.
  80. //
  81. // 01/14/97 JMI Now initializes m_upcUser to NULL. Also, SetRange()
  82. // now allows a range of 0 size. Still cannot have a range
  83. // of negative size though. This would be useful.
  84. //
  85. // 01/15/97 JMI Added overrides of base class's Save/LoadChildren() to
  86. // implement special cases for m_btnThumb, Up, & Down.
  87. //
  88. // 01/20/97 JMI No longer ASSERTs on odd sizes. Just does the best it
  89. // can with what you give it. You choose a screwy size, you
  90. // get it.
  91. //
  92. // 01/21/97 JMI Added ReadMembers() and WriteMembers() overloads to read
  93. // and write members of this class. Note that they call the
  94. // base class version to read/write base class members.
  95. // Support exists for versions 0 and 1. Version 0 did not
  96. // contain other than RGuiItem members.
  97. //
  98. // 01/27/97 JMI Now, if in a call to SetRange() the min is greater than
  99. // the max, the range is set to 0 instead of ASSERTing.
  100. //
  101. // 01/30/97 JMI Fixed rounding error in POS2PIXEL().
  102. //
  103. // 02/05/97 JMI Changed position of default: case in ReadMembers().
  104. //
  105. // 02/05/97 JMI Now has repeatability on up/left button, down/right
  106. // button, and tray presses. To do this in a consistent
  107. // way from the Do(), the up and down buttons had to be
  108. // changed to being hooked at the HotCall() level (like
  109. // the thumb has always been done).
  110. // This removed the need for static versions of the Up/
  111. // DownBtnCall()s.
  112. // Also, moved instantiable Up/DownBtnCall definitions to
  113. // the CPP.
  114. //
  115. // 02/25/97 JMI SaveChildren() now goes through the children in reverse
  116. // order so they, on load, get added back to their parent in
  117. // the order they were originally added to this parent.
  118. //
  119. // 03/19/97 JMI HotCall() now adapts sPosX,Y from hotbox coords instead
  120. // of hotbox's parent's coords.
  121. //
  122. // 03/19/97 JMI Converted to using the RHot::m_iecUser (was using
  123. // RHot::m_epcUser) so HotCall and CursorEvent now take
  124. // RInputEvent ptrs.
  125. //
  126. // 03/20/97 JMI Still had a reference to m_epcUser in Do(). Fixed.
  127. //
  128. // 03/28/97 JMI RSP_MB0_DOUBLECLICK is now treated the same as
  129. // RSP_MB0_PRESSED.
  130. //
  131. // 04/01/97 JMI Changed short m_sCanBeFocused (TRUE, FALSE) to
  132. // m_targetFocus (Self, Parent, Sibling).
  133. //
  134. // 04/03/97 JMI Added components for optional timed, smooth scrolling.
  135. //
  136. // 04/04/97 JMI Added reading/writing of version 3 members.
  137. //
  138. // 05/14/97 JMI Removed possible divide by 0's in SetRange().
  139. //
  140. // 06/27/97 JMI Moved GetTray() definition to here from scrollbar.h.
  141. //
  142. //////////////////////////////////////////////////////////////////////////////
  143. //
  144. // This a GUI item that is based on the basic RGuiItem.
  145. // This overrides HotCall() to get information about where a click in its CHot
  146. // occurred.
  147. // This overrides Compose() to add buttons and a thumb control.
  148. //
  149. // Enhancements/Uses:
  150. // To change the look of a scrollbar, you may want to override the Compose()
  151. // or DrawBorder() in a derived class (being sure to call
  152. // CSrollBar::DrawBorder() and RScrollBar::Compose() as appropriate).
  153. //
  154. // To change the background of a button, see RGuiItem.
  155. // To get a callback on a click/release pair in the button, set m_bcUser.
  156. // CAUTION:
  157. // You may set the callbacks for these m_scrollbarUp, m_scrollbarDown, or m_btnThumb, or
  158. // the base class to your own functions. But if you change gui.m_bcUser or
  159. // gui.m_ulUserInstace, you are responsible for calling SetPos() or the
  160. // callbacks (e.g., UpScrollBarPressed(void), DownScrollBarPressed(void), or
  161. // TrayPressed(void)) as appropriate. Also, if you change gui.m_ulUserInstance
  162. // on any of the gui children, be sure to set or clear gui.m_bcUser and
  163. // gui.m_backcall from their original values.
  164. //
  165. //////////////////////////////////////////////////////////////////////////////
  166. //////////////////////////////////////////////////////////////////////////////
  167. // Headers.
  168. //////////////////////////////////////////////////////////////////////////////
  169. #include "Blue.h"
  170. #ifdef PATHS_IN_INCLUDES
  171. #include "ORANGE/GUI/scrollbar.h"
  172. #else
  173. #include "ScrollBar.h"
  174. #endif // PATHS_IN_INCLUDES
  175. //////////////////////////////////////////////////////////////////////////////
  176. // Module specific macros.
  177. //////////////////////////////////////////////////////////////////////////////
  178. // Sets val to def if val is -1.
  179. #define DEF(val, def) ((val == -1) ? def : val)
  180. #define DEF_MIN_THUMB_LENGTH 10
  181. #define DEF_ARROW_BORDER_THICKNESS 2
  182. #define REPEAT_INITIAL_TIMEOUT 500
  183. #define REPEAT_SEQUENTIAL_TIMEOUT 100
  184. #define DEF_SCROLL_RATE 100 // Positions per second.
  185. //////////////////////////////////////////////////////////////////////////////
  186. // Module specific typedefs.
  187. //////////////////////////////////////////////////////////////////////////////
  188. //////////////////////////////////////////////////////////////////////////////
  189. // Module specific (static) variables.
  190. //////////////////////////////////////////////////////////////////////////////
  191. static long ms_lNextEventTime = 0; // Time of next repeat event.
  192. //////////////////////////////////////////////////////////////////////////////
  193. // Construction/Destruction.
  194. //////////////////////////////////////////////////////////////////////////////
  195. //////////////////////////////////////////////////////////////////////////////
  196. //
  197. // Default constructor.
  198. //
  199. //////////////////////////////////////////////////////////////////////////////
  200. RScrollBar::RScrollBar()
  201. {
  202. m_lButtonIncDec = 1;
  203. m_lTrayIncDec = 10;
  204. m_oOrientation = Vertical;
  205. m_lMinPos = 0;
  206. m_lMaxPos = 100;
  207. m_lCurPos = 0;
  208. m_lMinThumbLength = DEF_MIN_THUMB_LENGTH;
  209. m_sArrowBorderDistance = DEF_ARROW_BORDER_THICKNESS;
  210. m_sInvertedBorder = TRUE;
  211. m_btnThumb.SetParent(this);
  212. m_btnThumb.m_hot.m_iecUser = ThumbHotCall;
  213. m_btnThumb.m_hot.m_ulUser = (ULONG)this;
  214. m_btnThumb.m_targetFocus = Parent; // Passes focus to parent (this).
  215. m_btnUp.SetParent(this);
  216. m_btnUp.m_hot.m_iecUser = UpHotCall;
  217. m_btnUp.m_hot.m_ulUser = (ULONG)this;
  218. m_btnUp.m_ulUserInstance = (ULONG)this;
  219. m_btnUp.m_backcall = DrawUpArrow;
  220. m_btnUp.m_targetFocus = Parent; // Passes focus to parent (this).
  221. m_btnDown.SetParent(this);
  222. m_btnDown.m_hot.m_iecUser = DownHotCall;
  223. m_btnDown.m_hot.m_ulUser = (ULONG)this;
  224. m_btnDown.m_ulUserInstance = (ULONG)this;
  225. m_btnDown.m_backcall = DrawDownArrow;
  226. m_btnDown.m_targetFocus = Parent; // Passes focus to parent (this).
  227. m_type = ScrollBar; // Indicates type of GUI item.
  228. m_upcUser = NULL;
  229. m_scrollage = Instant;
  230. m_lScrollToPos = m_lCurPos;
  231. m_lPosPerSecond = DEF_SCROLL_RATE;
  232. m_sInSmoothScroll = FALSE;
  233. }
  234. //////////////////////////////////////////////////////////////////////////////
  235. //
  236. // Destructor.
  237. //
  238. //////////////////////////////////////////////////////////////////////////////
  239. RScrollBar::~RScrollBar()
  240. {
  241. }
  242. ////////////////////////////////////////////////////////////////////////
  243. // Methods.
  244. ////////////////////////////////////////////////////////////////////////
  245. ////////////////////////////////////////////////////////////////////////
  246. //
  247. // Compose item.
  248. //
  249. ////////////////////////////////////////////////////////////////////////
  250. void RScrollBar::Compose( // Returns nothing.
  251. RImage* pim /*= NULL*/) // Dest image, uses m_im if NULL.
  252. {
  253. if (pim == NULL)
  254. {
  255. pim = &m_im;
  256. }
  257. // Call base (draws border and background).
  258. RGuiItem::Compose(pim);
  259. // Draw scrollbar stuff.
  260. // Get client relative to border so we know where to
  261. // set up the buttons.
  262. short sX, sY, sW, sH;
  263. GetClient(&sX, &sY, &sW, &sH);
  264. // Set width and height for buttons.
  265. short sBtnWidth;
  266. short sBtnHeight;
  267. if (m_oOrientation == Vertical)
  268. {
  269. sBtnWidth = sW;
  270. sBtnHeight = sW;
  271. }
  272. else // Horizontal
  273. {
  274. sBtnWidth = sH;
  275. sBtnHeight = sH;
  276. }
  277. CopyBorderInfoTo(&m_btnUp);
  278. // Create up/left button . . .
  279. if (m_btnUp.Create(sX, sY, sBtnWidth, sBtnHeight, m_im.m_sDepth) == 0)
  280. {
  281. CopyBorderInfoTo(&m_btnDown);
  282. // Create down/right button . . .
  283. if (m_btnDown.Create(sX + sW - sBtnWidth, sY + sH - sBtnHeight,
  284. sBtnWidth, sBtnHeight, m_im.m_sDepth) == 0)
  285. {
  286. }
  287. else
  288. {
  289. TRACE("Compose(): RBtn::Create() failed for down/right button.\n");
  290. }
  291. }
  292. else
  293. {
  294. TRACE("Compose(): RBtn::Create() failed for up/left button.\n");
  295. }
  296. CopyBorderInfoTo(&m_btnThumb);
  297. // Create thumb . . .
  298. SetRange(m_lMinPos, m_lMaxPos);
  299. }
  300. ////////////////////////////////////////////////////////////////////////
  301. //
  302. // Cursor event notification.
  303. // Events in event area.
  304. // (virtual).
  305. //
  306. /////////////////////////////////////////////////////////////
  307. ///////////
  308. void RScrollBar::CursorEvent( // Returns nothing.
  309. RInputEvent* pie) // In: Most recent user input event.
  310. // Out: pie->sUsed = TRUE, if used.
  311. {
  312. switch (pie->sEvent)
  313. {
  314. case RSP_MB0_DOUBLECLICK:
  315. case RSP_MB0_PRESSED:
  316. {
  317. // Get focus now even though this is done in the base class b/c,
  318. // If using smooth scrollage, we must have the focus.
  319. SetFocus();
  320. // Store time of next event.
  321. ms_lNextEventTime = rspGetMilliseconds();
  322. if (m_sPressed == FALSE)
  323. {
  324. ms_lNextEventTime += REPEAT_INITIAL_TIMEOUT;
  325. }
  326. else
  327. {
  328. ms_lNextEventTime += REPEAT_SEQUENTIAL_TIMEOUT;
  329. }
  330. // If outside the thumb . . .
  331. // NOTE: If the m_lTrayIncDec is greater than the thickness of the
  332. // thumb, this will still hop around a bit.
  333. if ( pie->sPosX < m_btnThumb.m_sX
  334. || pie->sPosX >= m_btnThumb.m_sX + m_btnThumb.m_im.m_sWidth
  335. || pie->sPosY < m_btnThumb.m_sY
  336. || pie->sPosY >= m_btnThumb.m_sY + m_btnThumb.m_im.m_sHeight)
  337. {
  338. short sTrayPosX, sTrayPosY, sTrayRelPosX, sTrayRelPosY;
  339. GetTray(&sTrayPosX, &sTrayPosY, NULL, NULL);
  340. sTrayRelPosX = pie->sPosX - sTrayPosX;
  341. sTrayRelPosY = pie->sPosY - sTrayPosY;
  342. // If less than existing pos . . .
  343. if (PIXELS2POS(sTrayRelPosX, sTrayRelPosY) < m_lCurPos)
  344. {
  345. // Set the thumb position forward.
  346. UserSetPos(m_lCurPos - m_lTrayIncDec);
  347. }
  348. else
  349. {
  350. // Set the thumb position backward.
  351. UserSetPos(m_lCurPos + m_lTrayIncDec);
  352. }
  353. }
  354. // Note that we used it.
  355. pie->sUsed = TRUE;
  356. break;
  357. }
  358. case RSP_MB0_RELEASED:
  359. {
  360. // Note that we used it.
  361. pie->sUsed = TRUE;
  362. break;
  363. }
  364. }
  365. RGuiItem::CursorEvent(pie);
  366. }
  367. ////////////////////////////////////////////////////////////////////////
  368. //
  369. // Called when up/left button pressed.
  370. //
  371. ////////////////////////////////////////////////////////////////////////
  372. void RScrollBar::UpBtnPressed(void)
  373. {
  374. UserSetPos(m_lCurPos - m_lButtonIncDec);
  375. }
  376. ////////////////////////////////////////////////////////////////////////
  377. //
  378. // Called when down/right button pressed.
  379. //
  380. ////////////////////////////////////////////////////////////////////////
  381. void RScrollBar::DownBtnPressed(void)
  382. {
  383. UserSetPos(m_lCurPos + m_lButtonIncDec);
  384. }
  385. ////////////////////////////////////////////////////////////////////////
  386. //
  387. // Sets the range of the scroll bar and sizes & moves the thumb
  388. // appropriately.
  389. //
  390. ////////////////////////////////////////////////////////////////////////
  391. void RScrollBar::SetRange(
  392. long lMin,
  393. long lMax)
  394. {
  395. ASSERT(m_lMinThumbLength > 0);
  396. // Right now we don't support backwards max/min . . .
  397. if (lMin > lMax)
  398. {
  399. // Range is 0.
  400. lMin = lMax;
  401. }
  402. m_lMinPos = lMin;
  403. m_lMaxPos = lMax;
  404. // Compute the range of positions. That is, the number of positions.
  405. long lRange = lMax - lMin;
  406. // Compute the scroll bar size that gives us that many positions.
  407. short sX;
  408. short sY;
  409. short sW;
  410. short sH;
  411. GetTray(&sX, &sY, &sW, &sH);
  412. short sThumbW; // Width for thumb.
  413. short sThumbH; // Height for thumb.
  414. short* psTrayLength; // Pointer to tray length.
  415. short* psTrayThickness; // Pointer to tray thickness.
  416. short* psThumbLength; // Pointer to thumb length.
  417. short* psThumbThickness; // Pointer to thumb thickness.
  418. if (m_oOrientation == Vertical)
  419. {
  420. psTrayLength = &sH;
  421. psTrayThickness = &sW;
  422. psThumbLength = &sThumbH;
  423. psThumbThickness = &sThumbW;
  424. }
  425. else
  426. {
  427. psTrayLength = &sW;
  428. psTrayThickness = &sH;
  429. psThumbLength = &sThumbW;
  430. psThumbThickness = &sThumbH;
  431. }
  432. // Determine length for thumb.
  433. long lLength = (long)(*psTrayLength) - lRange;
  434. // If the size is less than the minimum . . .
  435. if (lLength < m_lMinThumbLength)
  436. {
  437. lLength = MIN(m_lMinThumbLength, (long)(*psTrayLength));
  438. }
  439. // Compute position to pixel ratio.
  440. float fLenDif = (float)(*psTrayLength - lLength);
  441. // If neither value is 0 . . .
  442. if (fLenDif != 0.0F && lRange != 0)
  443. {
  444. if (lRange > lLength)
  445. {
  446. m_fPos2PixelRatio = fLenDif / (float)lRange;
  447. }
  448. else
  449. {
  450. m_fPos2PixelRatio = (float)lRange / fLenDif;
  451. }
  452. }
  453. else
  454. {
  455. m_fPos2PixelRatio = 0.00001F;
  456. }
  457. *psThumbLength = (short)lLength;
  458. *psThumbThickness = *psTrayThickness;
  459. m_btnThumb.Destroy();
  460. // Create thumb . . .
  461. if (m_btnThumb.Create(0, 0, MAX(sThumbW, (short)1), MAX(sThumbH, (short)1), m_im.m_sDepth) == 0)
  462. {
  463. // Set up hot.
  464. m_btnThumb.SetHotArea();
  465. // Set position.
  466. SetPos(m_lCurPos);
  467. }
  468. else
  469. {
  470. TRACE("SetRange(): RGuiItem::Create() failed for thumb.\n");
  471. }
  472. }
  473. ////////////////////////////////////////////////////////////////////////
  474. //
  475. // Hot call for thumb positioner.
  476. //
  477. ////////////////////////////////////////////////////////////////////////
  478. void RScrollBar::ThumbHotCall( // Returns nothing.
  479. RInputEvent* pie) // In: Most recent user input event.
  480. // Out: pie->sUsed = TRUE, if used.
  481. {
  482. short sUsed = pie->sUsed;
  483. // Call base.
  484. m_btnThumb.HotCall(pie);
  485. // If this is an unused mouse event . . .
  486. if (pie->type == RInputEvent::Mouse && sUsed == FALSE)
  487. {
  488. short sHotPosX = m_btnThumb.m_hot.m_sX;
  489. short sHotPosY = m_btnThumb.m_hot.m_sY;
  490. // Make relative to Thumb GUI item (rather than its hotbox).
  491. pie->sPosX -= sHotPosX;
  492. pie->sPosY -= sHotPosY;
  493. switch (pie->sEvent)
  494. {
  495. case RSP_MB0_PRESSED:
  496. // Start dragging thumb on Do().
  497. // Note position clicked so we know what part of bar was
  498. // pressed.
  499. m_sClickOffsetX = pie->sPosX;
  500. m_sClickOffsetY = pie->sPosY;
  501. // Note that we used the event.
  502. pie->sUsed = TRUE;
  503. break;
  504. case RSP_MB0_RELEASED:
  505. // Note that we used the event.
  506. pie->sUsed = TRUE;
  507. break;
  508. }
  509. // Put position back.
  510. pie->sPosX += sHotPosX;
  511. pie->sPosY += sHotPosY;
  512. }
  513. }
  514. ////////////////////////////////////////////////////////////////////////
  515. //
  516. // Hot call for up button.
  517. //
  518. ////////////////////////////////////////////////////////////////////////
  519. void RScrollBar::UpHotCall( // Returns nothing.
  520. RInputEvent* pie) // In: Most recent user input event.
  521. // Out: pie->sUsed = TRUE, if used.
  522. {
  523. short sUsed = pie->sUsed;
  524. // Call base.
  525. m_btnUp.HotCall(pie);
  526. // If this is an unused mouse event . . .
  527. if (pie->type == RInputEvent::Mouse && sUsed == FALSE)
  528. {
  529. short sHotPosX = m_btnUp.m_hot.m_sX;
  530. short sHotPosY = m_btnUp.m_hot.m_sY;
  531. // Make relative to Up GUI item (rather than its hotbox).
  532. pie->sPosX -= sHotPosX;
  533. pie->sPosY -= sHotPosY;
  534. switch (pie->sEvent)
  535. {
  536. case RSP_MB0_PRESSED:
  537. // Store time of next event.
  538. ms_lNextEventTime = rspGetMilliseconds();
  539. if (m_btnUp.m_sPressed == FALSE)
  540. {
  541. ms_lNextEventTime += REPEAT_INITIAL_TIMEOUT;
  542. }
  543. else
  544. {
  545. ms_lNextEventTime += REPEAT_SEQUENTIAL_TIMEOUT;
  546. }
  547. UpBtnPressed();
  548. // Note that we used the event.
  549. pie->sUsed = TRUE;
  550. break;
  551. case RSP_MB0_RELEASED:
  552. // Note that we used the event.
  553. pie->sUsed = TRUE;
  554. break;
  555. }
  556. // Put position back.
  557. pie->sPosX += sHotPosX;
  558. pie->sPosY += sHotPosY;
  559. }
  560. }
  561. ////////////////////////////////////////////////////////////////////////
  562. //
  563. // Hot call for down button.
  564. //
  565. ////////////////////////////////////////////////////////////////////////
  566. void RScrollBar::DownHotCall( // Returns nothing.
  567. RInputEvent* pie) // In: Most recent user input event.
  568. // Out: pie->sUsed = TRUE, if used.
  569. {
  570. short sUsed = pie->sUsed;
  571. // Call base.
  572. m_btnDown.HotCall(pie);
  573. // If this is an unused mouse event . . .
  574. if (pie->type == RInputEvent::Mouse && sUsed == FALSE)
  575. {
  576. short sHotPosX = m_btnDown.m_hot.m_sX;
  577. short sHotPosY = m_btnDown.m_hot.m_sY;
  578. // Make relative to Down GUI item (rather than its hotbox).
  579. pie->sPosX -= sHotPosX;
  580. pie->sPosY -= sHotPosY;
  581. switch (pie->sEvent)
  582. {
  583. case RSP_MB0_PRESSED:
  584. // Store time of next event.
  585. ms_lNextEventTime = rspGetMilliseconds();
  586. if (m_btnDown.m_sPressed == FALSE)
  587. {
  588. ms_lNextEventTime += REPEAT_INITIAL_TIMEOUT;
  589. }
  590. else
  591. {
  592. ms_lNextEventTime += REPEAT_SEQUENTIAL_TIMEOUT;
  593. }
  594. DownBtnPressed();
  595. break;
  596. case RSP_MB0_RELEASED:
  597. break;
  598. }
  599. // Put position back.
  600. pie->sPosX += sHotPosX;
  601. pie->sPosY += sHotPosY;
  602. }
  603. }
  604. ////////////////////////////////////////////////////////////////////////
  605. //
  606. // Does tasks that require constant update for scroll bar.
  607. // If called iteratively, the thumb can be dragged on the bar.
  608. // (virtual (overridden here)).
  609. //
  610. ////////////////////////////////////////////////////////////////////////
  611. void RScrollBar::Do( // Returns nothing.
  612. RInputEvent* pie) // In: Most recent user input event.
  613. // Out: pie->sUsed = TRUE, if used.
  614. {
  615. // Call base.
  616. RGuiItem::Do(pie);
  617. #ifdef MOBILE
  618. //if (pie->sUsed == FALSE && pie->type == RInputEvent::Mouse)
  619. if ( pie->type == RInputEvent::Mouse)
  620. {
  621. TRACE("Mouse scrollbar %d %d %d", pie->sPosX , pie->sPosY, pie->sButtons);
  622. if ( pie->sButtons)
  623. {
  624. short sX, sY, sTrayX, sTrayY;
  625. sX = pie->sPosX;
  626. sY = pie->sPosY;
  627. //rspGetMouse(&sX, &sY, NULL);
  628. TopPosToChild(&sX, &sY);
  629. GetTray(&sTrayX, &sTrayY, NULL, NULL);
  630. sX -= + sTrayX;
  631. //sX += (800-640);
  632. //sY -= m_sClickOffsetY + sTrayY;
  633. SetPos(PIXELS2POS(sX, sY) );
  634. }
  635. pie->sUsed = TRUE;
  636. }
  637. #endif
  638. if (m_btnThumb.m_sPressed != FALSE)
  639. {
  640. short sX, sY, sTrayX, sTrayY;
  641. rspGetMouse(&sX, &sY, NULL);
  642. TopPosToChild(&sX, &sY);
  643. GetTray(&sTrayX, &sTrayY, NULL, NULL);
  644. sX -= m_sClickOffsetX + sTrayX;
  645. sY -= m_sClickOffsetY + sTrayY;
  646. SetPos(PIXELS2POS(sX, sY) );
  647. }
  648. else
  649. {
  650. // If the event is unused . . .
  651. if (pie->sUsed == FALSE)
  652. {
  653. switch (pie->type)
  654. {
  655. case RInputEvent::Key:
  656. {
  657. long* plIncDec = &m_lButtonIncDec; // Amount to move thumb.
  658. // If control held . . .
  659. if ( (pie->lKey & RSP_GKF_CONTROL) != 0)
  660. {
  661. // Use alternate amount.
  662. plIncDec = &m_lTrayIncDec;
  663. }
  664. // Assume we use it. Easier.
  665. pie->sUsed = TRUE;
  666. switch (pie->lKey & 0x0000FFFF)
  667. {
  668. case RSP_GK_LEFT:
  669. if (m_oOrientation == Horizontal)
  670. {
  671. UserSetPos(GetPos() - *plIncDec);
  672. }
  673. break;
  674. case RSP_GK_RIGHT:
  675. if (m_oOrientation == Horizontal)
  676. {
  677. UserSetPos(GetPos() + *plIncDec);
  678. }
  679. break;
  680. case RSP_GK_UP:
  681. if (m_oOrientation == Vertical)
  682. {
  683. UserSetPos(GetPos() - *plIncDec);
  684. }
  685. break;
  686. case RSP_GK_DOWN:
  687. if (m_oOrientation == Vertical)
  688. {
  689. UserSetPos(GetPos() + *plIncDec);
  690. }
  691. break;
  692. case RSP_GK_HOME:
  693. UserSetPos(m_lMinPos);
  694. break;
  695. case RSP_GK_END:
  696. UserSetPos(m_lMaxPos);
  697. break;
  698. default: // Did not use.
  699. // Better clear flag.
  700. pie->sUsed = FALSE;
  701. break;
  702. }
  703. break; // on case RInputEvent::Key.
  704. }
  705. }
  706. }
  707. RGuiItem* pguiPressed = NULL;
  708. // If tray currently pressed . . .
  709. if (m_sPressed != FALSE)
  710. {
  711. pguiPressed = this;
  712. }
  713. else
  714. {
  715. // If up currently pressed . . .
  716. if (m_btnUp.m_sPressed != FALSE)
  717. {
  718. pguiPressed = &m_btnUp;
  719. }
  720. else
  721. {
  722. // If down currently pressed . . .
  723. if (m_btnDown.m_sPressed != FALSE)
  724. {
  725. pguiPressed = &m_btnDown;
  726. }
  727. }
  728. }
  729. // If we found a pressed repeatable GUI . . .
  730. if (pguiPressed != NULL)
  731. {
  732. long lCurTime = rspGetMilliseconds();
  733. if (lCurTime > ms_lNextEventTime)
  734. {
  735. // Get current mouse cursor position.
  736. short sPosX, sPosY;
  737. rspGetMouse(&sPosX, &sPosY, NULL);
  738. // Convert to our coordinate system.
  739. pguiPressed->TopPosToChild(&sPosX, &sPosY);
  740. // Generate event in pressed item.
  741. RInputEvent ie;
  742. ie.type = RInputEvent::Mouse;
  743. ie.lTime = lCurTime;
  744. ie.sEvent = RSP_MB0_PRESSED;
  745. ie.sButtons = 1;
  746. ie.sPosX = sPosX;
  747. ie.sPosY = sPosY;
  748. ie.sUsed = FALSE;
  749. ie.lUser = 0;
  750. pguiPressed->m_hot.m_iecUser(&pguiPressed->m_hot, &ie);
  751. }
  752. }
  753. // If we are smooth scrolling . . .
  754. if (m_sInSmoothScroll != FALSE)
  755. {
  756. long lCurTime = rspGetMilliseconds();
  757. // If any time has occurred . . .
  758. if (lCurTime > m_lLastSmoothTime)
  759. {
  760. // Determine amount to scroll.
  761. // This could overflow in extreme circumstances.
  762. long lScroll = (m_lPosPerSecond * (lCurTime - m_lLastSmoothTime) ) / 1000L;
  763. // Determine distance to destination.
  764. long lDist = m_lScrollToPos - m_lCurPos;
  765. // If positive distance . . .
  766. if (lDist > 0)
  767. {
  768. // Don't scroll too far.
  769. lScroll = MIN(lScroll, lDist);
  770. }
  771. else
  772. {
  773. // Don't scroll too far.
  774. lScroll = MAX(-lScroll, lDist);
  775. }
  776. // Update position (absolute).
  777. SetPos(m_lCurPos + lScroll);
  778. // Store time for next iteration.
  779. m_lLastSmoothTime = lCurTime;
  780. }
  781. }
  782. }
  783. }
  784. ////////////////////////////////////////////////////////////////////////
  785. //
  786. // Draws an arrow pointing sDirection where the directions are:
  787. // 0
  788. // 1 + 3
  789. // 2
  790. // with color or index u32Color into pim at (sX, sY, sW, sH).
  791. // Very cheesy but it'll do for now.
  792. //
  793. ////////////////////////////////////////////////////////////////////////
  794. inline void DrawArrow( // Returns nothing.
  795. short sDirection, // Direction of arrow; see above.
  796. U32 u32Color, // Color or index to draw with.
  797. RImage* pim, // Destination image.
  798. short sX, // Position at which to draw.
  799. short sY, // Position at which to draw.
  800. short sW, // Amount with which to draw.
  801. short sH) // Amount with which to draw.
  802. {
  803. // If there is an area . . .
  804. if (sW > 0 && sH > 0)
  805. {
  806. short sCurX = sX;
  807. short sCurY = sY;
  808. short sCurW = 1;
  809. short sCurH = 1;
  810. short* psCurLine;
  811. short* psCurLinePos;
  812. short* psCurLineLen;
  813. short sLineLenInc;
  814. short sLinePosDec;
  815. short sMaxLineLen;
  816. short sMaxLine;
  817. short sMinLinePos;
  818. switch (sDirection)
  819. {
  820. case 0: // Up.
  821. ASSERT(sW > 0);
  822. sLineLenInc = (sH * 2) / sW;
  823. sLinePosDec = sLineLenInc;
  824. sCurY = sY + sH - sLineLenInc;
  825. sMaxLineLen = sH;
  826. sMaxLine = sW;
  827. sMinLinePos = sY;
  828. psCurLine = &sCurX;
  829. psCurLinePos = &sCurY;
  830. psCurLineLen = &sCurH;
  831. break;
  832. case 1: // Left.
  833. ASSERT(sH > 0);
  834. sLineLenInc = (sW * 2) / sH;
  835. sLinePosDec = sLineLenInc;
  836. sCurX = sX + sW - sLineLenInc;
  837. sMaxLineLen = sW;
  838. sMaxLine = sH;
  839. sMinLinePos = sX;
  840. psCurLine = &sCurY;
  841. psCurLinePos = &sCurX;
  842. psCurLineLen = &sCurW;
  843. break;
  844. case 2: // Down.
  845. ASSERT(sW > 0);
  846. sLineLenInc = (sH * 2) / sW;
  847. sLinePosDec = 0;
  848. sMaxLineLen = sH;
  849. sMaxLine = sW;
  850. sMinLinePos = sY;
  851. psCurLine = &sCurX;
  852. psCurLinePos = &sCurY;
  853. psCurLineLen = &sCurH;
  854. break;
  855. case 3: // Right.
  856. ASSERT(sH > 0);
  857. sLineLenInc = (sW * 2) / sH;
  858. sLinePosDec = 0;
  859. sMaxLineLen = sW;
  860. sMaxLine = sH;
  861. sMinLinePos = sX;
  862. psCurLine = &sCurY;
  863. psCurLinePos = &sCurX;
  864. psCurLineLen = &sCurW;
  865. break;
  866. }
  867. *psCurLineLen = sLineLenInc;
  868. while (*psCurLineLen < sMaxLineLen)
  869. {
  870. rspRect(u32Color, pim, sCurX, sCurY, sCurW, sCurH);
  871. *psCurLine += 1;
  872. *psCurLineLen += sLineLenInc;
  873. *psCurLinePos -= sLinePosDec;
  874. }
  875. // Store current values just in case height is odd (b/c rounding
  876. // errors will have occurred and we'll need restore the in-error
  877. // values).
  878. short sTempLineLen = *psCurLineLen;
  879. short sTempLinePos = *psCurLinePos;
  880. *psCurLineLen = sMaxLineLen;
  881. *psCurLinePos = sMinLinePos;
  882. // Add tip line.
  883. rspRect(u32Color, pim, sCurX, sCurY, sCurW, sCurH);
  884. // If num lines is odd . . .
  885. if (sMaxLine % 2 == 1)
  886. {
  887. // Restore error values so that arrow is symmetrical.
  888. *psCurLineLen = sTempLineLen - sLineLenInc;
  889. *psCurLinePos = sTempLinePos + sLinePosDec;
  890. }
  891. // Next line.
  892. *psCurLine += 1;
  893. while (*psCurLineLen > 0)
  894. {
  895. rspRect(u32Color, pim, sCurX, sCurY, sCurW, sCurH);
  896. *psCurLine += 1;
  897. *psCurLineLen -= sLineLenInc;
  898. *psCurLinePos += sLinePosDec;
  899. }
  900. }
  901. }
  902. ////////////////////////////////////////////////////////////////////////
  903. //
  904. // Draws an appropriate arrow for this button.
  905. //
  906. ////////////////////////////////////////////////////////////////////////
  907. void RScrollBar::DrawUpArrow( // Returns nothing.
  908. RImage* pim, // Image to draw into. Try to stay within
  909. // prc please.
  910. RRect* prc) // Where to in image.
  911. {
  912. // Fill.
  913. rspRect(m_btnUp.m_u32BackColor, pim, prc->sX, prc->sY, prc->sW, prc->sH);
  914. // Draw.
  915. DrawArrow(m_oOrientation,
  916. m_btnUp.m_u32TextColor, pim,
  917. prc->sX + m_sArrowBorderDistance,
  918. prc->sY + m_sArrowBorderDistance,
  919. prc->sW - m_sArrowBorderDistance * 2,
  920. prc->sH - m_sArrowBorderDistance * 2);
  921. }
  922. ////////////////////////////////////////////////////////////////////////
  923. //
  924. // Draws an appropriate arrow for this button.
  925. //
  926. ////////////////////////////////////////////////////////////////////////
  927. void RScrollBar::DrawDownArrow( // Returns nothing.
  928. RImage* pim, // Image to draw into. Try to stay within
  929. // prc please.
  930. RRect* prc) // Where to in image.
  931. {
  932. // Fill.
  933. rspRect(m_btnUp.m_u32BackColor, pim, prc->sX, prc->sY, prc->sW, prc->sH);
  934. // Draw.
  935. DrawArrow(m_oOrientation + 2,
  936. m_btnUp.m_u32TextColor, pim,
  937. prc->sX + m_sArrowBorderDistance,
  938. prc->sY + m_sArrowBorderDistance,
  939. prc->sW - m_sArrowBorderDistance * 2,
  940. prc->sH - m_sArrowBorderDistance * 2);
  941. }
  942. ////////////////////////////////////////////////////////////////////////
  943. //
  944. // Load item's children from the specified file.
  945. // (virtual override).
  946. // (protected).
  947. //
  948. ////////////////////////////////////////////////////////////////////////
  949. short RScrollBar::LoadChildren( // Returns 0 on success.
  950. RFile* pfile) // File to load from.
  951. {
  952. short sRes = 0; // Assume success.
  953. ASSERT(pfile->IsOpen() != FALSE);
  954. short sNum;
  955. // Read number of children.
  956. pfile->Read(&sNum);
  957. // The first three are our arrow and thumb buttons.
  958. ASSERT(sNum >= 3);
  959. // Load directly into these special children.
  960. if (m_btnThumb.Load(pfile) == 0)
  961. {
  962. if (m_btnUp.Load(pfile) == 0)
  963. {
  964. if (m_btnDown.Load(pfile) == 0)
  965. {
  966. // Subtract these three children from total.
  967. sNum -= 3;
  968. }
  969. else
  970. {
  971. TRACE("LoadChildren(): m_btnDown.Load() failed.\n");
  972. sRes = -3;
  973. }
  974. }
  975. else
  976. {
  977. TRACE("LoadChildren(): m_btnUp.Load() failed.\n");
  978. sRes = -2;
  979. }
  980. }
  981. else
  982. {
  983. TRACE("LoadChildren(): m_btnThumb.Load() failed.\n");
  984. sRes = -1;
  985. }
  986. // Instantiate rest of children.
  987. RGuiItem* pgui;
  988. short sCurChild;
  989. for ( sCurChild = 0;
  990. sCurChild < sNum && sRes == 0 && pfile->Error() == FALSE;
  991. sCurChild++)
  992. {
  993. pgui = LoadInstantiate(pfile);
  994. if (pgui != NULL)
  995. {
  996. pgui->SetParent(this);
  997. }
  998. else
  999. {
  1000. TRACE("LoadChildren(): LoadInstantiate() failed.\n");
  1001. sRes = -1;
  1002. }
  1003. }
  1004. return sRes;
  1005. }
  1006. ////////////////////////////////////////////////////////////////////////
  1007. //
  1008. // Save item's children to the specified file.
  1009. // (virtual override).
  1010. // (protected).
  1011. //
  1012. ////////////////////////////////////////////////////////////////////////
  1013. short RScrollBar::SaveChildren( // Returns 0 on success.
  1014. RFile* pfile) // File to save to.
  1015. {
  1016. short sRes = 0; // Assume success.
  1017. ASSERT(pfile->IsOpen() != FALSE);
  1018. // Determine number of child items.
  1019. short sNum = 0;
  1020. RGuiItem* pgui = m_listguiChildren.GetHead();
  1021. while (pgui != NULL)
  1022. {
  1023. sNum++;
  1024. pgui = m_listguiChildren.GetNext();
  1025. }
  1026. // Write number of children.
  1027. pfile->Write(sNum);
  1028. // These should definitely be a child of 'this' item.
  1029. ASSERT(m_btnThumb.GetParent() == this);
  1030. ASSERT(m_btnUp.GetParent() == this);
  1031. ASSERT(m_btnDown.GetParent() == this);
  1032. // Always write our 3 buttons (arrows and thumb) first so we know
  1033. // where to get them on load.
  1034. if (m_btnThumb.Save(pfile) == 0)
  1035. {
  1036. if (m_btnUp.Save(pfile) == 0)
  1037. {
  1038. if (m_btnDown.Save(pfile) == 0)
  1039. {
  1040. // Subtract these three children from total.
  1041. // Currently this number is not used during save,
  1042. // but just in case it ever is.
  1043. sNum -= 3;
  1044. }
  1045. else
  1046. {
  1047. TRACE("SaveChildren(): m_btnDown.Save() failed.\n");
  1048. sRes = -3;
  1049. }
  1050. }
  1051. else
  1052. {
  1053. TRACE("SaveChildren(): m_btnUp.Save() failed.\n");
  1054. sRes = -2;
  1055. }
  1056. }
  1057. else
  1058. {
  1059. TRACE("SaveChildren(): m_btnThumb.Save() failed.\n");
  1060. sRes = -1;
  1061. }
  1062. // Save children. Note that we go through the children in reverse
  1063. // order so they, on load, get added back to their parent in the
  1064. // order they were originally added to this parent.
  1065. pgui = m_listguiChildren.GetTail();
  1066. while (pgui != NULL && sRes == 0 && pfile->Error() == FALSE)
  1067. {
  1068. // Don't write these 3 again . . .
  1069. if (pgui != &m_btnThumb && pgui != &m_btnUp && pgui != &m_btnDown)
  1070. {
  1071. // Save child.
  1072. sRes = pgui->Save(pfile);
  1073. }
  1074. pgui = m_listguiChildren.GetPrev();
  1075. }
  1076. return sRes;
  1077. }
  1078. ////////////////////////////////////////////////////////////////////////
  1079. // Internal.
  1080. ////////////////////////////////////////////////////////////////////////
  1081. ////////////////////////////////////////////////////////////////////////
  1082. //
  1083. // Read item's members from file.
  1084. // (virtual/protected (overriden here)).
  1085. //
  1086. ////////////////////////////////////////////////////////////////////////
  1087. short RScrollBar::ReadMembers( // Returns 0 on success.
  1088. RFile* pfile, // File to read from.
  1089. U32 u32Version) // File format version to use.
  1090. {
  1091. short sRes = 0; // Assume success.
  1092. // Invoke base class to read base members.
  1093. sRes = RGuiItem::ReadMembers(pfile, u32Version);
  1094. // If okay so far . . .
  1095. if (sRes == 0)
  1096. {
  1097. ASSERT(pfile != NULL);
  1098. ASSERT(pfile->IsOpen() != FALSE);
  1099. U32 u32Temp;
  1100. // Switch on version.
  1101. switch (u32Version)
  1102. {
  1103. default:
  1104. // Insert additional version numbers here!
  1105. // case 4: // Version 4 stuff.
  1106. case 3: // Version 3 stuff. Smooth scrollage added.
  1107. short sScrollage;
  1108. pfile->Read(&sScrollage);
  1109. m_scrollage = (Scrollage)sScrollage;
  1110. pfile->Read(&m_lPosPerSecond);
  1111. case 2: // Version 2 stuff.
  1112. case 1:
  1113. // Read this class's members.
  1114. pfile->Read(&m_lButtonIncDec);
  1115. pfile->Read(&m_lTrayIncDec);
  1116. pfile->Read(&m_sArrowBorderDistance);
  1117. pfile->Read(&u32Temp);
  1118. m_oOrientation = (Orientation)u32Temp;
  1119. pfile->Read(&m_lMinThumbLength);
  1120. pfile->Read(&m_lMinPos);
  1121. pfile->Read(&m_lMaxPos);
  1122. pfile->Read(&m_lCurPos);
  1123. case 0: // In version 0, only base class RGuiItem members were stored.
  1124. // If successful . . .
  1125. if (pfile->Error() == FALSE)
  1126. {
  1127. // Success.
  1128. }
  1129. else
  1130. {
  1131. TRACE("ReadMembers(): Error reading RScrollBar members.\n");
  1132. sRes = -1;
  1133. }
  1134. break;
  1135. }
  1136. }
  1137. return sRes;
  1138. }
  1139. ////////////////////////////////////////////////////////////////////////
  1140. //
  1141. // Write item's members to file.
  1142. // (virtual/protected (overriden here)).
  1143. //
  1144. ////////////////////////////////////////////////////////////////////////
  1145. short RScrollBar::WriteMembers( // Returns 0 on success.
  1146. RFile* pfile) // File to write to.
  1147. {
  1148. short sRes = 0; // Assume success.
  1149. // Invoke base class to read base members.
  1150. sRes = RGuiItem::WriteMembers(pfile);
  1151. // If okay so far . . .
  1152. if (sRes == 0)
  1153. {
  1154. ASSERT(pfile != NULL);
  1155. ASSERT(pfile->IsOpen() != FALSE);
  1156. // Write this class's members.
  1157. // Version 3.
  1158. pfile->Write((short)m_scrollage);
  1159. pfile->Write(&m_lPosPerSecond);
  1160. // Version 1.
  1161. pfile->Write(&m_lButtonIncDec);
  1162. pfile->Write(&m_lTrayIncDec);
  1163. pfile->Write(&m_sArrowBorderDistance);
  1164. pfile->Write((U32)m_oOrientation);
  1165. pfile->Write(&m_lMinThumbLength);
  1166. pfile->Write(&m_lMinPos);
  1167. pfile->Write(&m_lMaxPos);
  1168. pfile->Write(&m_lCurPos);
  1169. // If successful . . .
  1170. if (pfile->Error() == FALSE)
  1171. {
  1172. // Success.
  1173. }
  1174. else
  1175. {
  1176. TRACE("WriteMembers(): Error writing RScrollBar members.\n");
  1177. sRes = -1;
  1178. }
  1179. }
  1180. return sRes;
  1181. }
  1182. ////////////////////////////////////////////////////////////////////////
  1183. // Querries.
  1184. ////////////////////////////////////////////////////////////////////////
  1185. ////////////////////////////////////////////////////////////////////////
  1186. // Get position/size of tray relative to this item.
  1187. ////////////////////////////////////////////////////////////////////////
  1188. void RScrollBar::GetTray( // Returns nothing.
  1189. short* psX, // Out: x coordinate of tray unless NULL.
  1190. short* psY, // Out: y coordinate of tray unless NULL.
  1191. short* psW, // Out: Width of tray unless NULL.
  1192. short* psH) // Out: Height of tray unless NULL.
  1193. {
  1194. GetClient(psX, psY, psW, psH);
  1195. if (m_oOrientation == Vertical)
  1196. {
  1197. SET_IF_NOT_NULL(psY, *psY + m_btnUp.m_im.m_sHeight);
  1198. SET_IF_NOT_NULL(psH, *psH - (m_btnUp.m_im.m_sHeight + m_btnDown.m_im.m_sHeight) );
  1199. }
  1200. else
  1201. {
  1202. SET_IF_NOT_NULL(psX, *psX + m_btnUp.m_im.m_sWidth);
  1203. SET_IF_NOT_NULL(psW, *psW - (m_btnUp.m_im.m_sWidth + m_btnDown.m_im.m_sWidth) );
  1204. }
  1205. }
  1206. //////////////////////////////////////////////////////////////////////////////
  1207. // EOF
  1208. //////////////////////////////////////////////////////////////////////////////