scrollbar.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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.H
  21. //
  22. // History:
  23. // 01/14/97 JMI Started tracking history of this file.
  24. // Added UpdatePosCall and m_upcUser.
  25. // Also, range macros now consider m_lMinPos for other than
  26. // 0.
  27. //
  28. // 01/15/97 JMI Added overrides of base class's Save/LoadChildren() to
  29. // implement special cases for m_btnThumb, Up, & Down.
  30. //
  31. // 01/18/97 JMI Converted Do() to take an RInputEvent* instead of a
  32. // long*.
  33. //
  34. // 01/21/97 JMI Added ReadMembers() and WriteMembers() overloads to read
  35. // and write members of this class.
  36. //
  37. // 01/26/97 JMI Altered static HotCall to accept an RHot* instead of a
  38. // ULONG 'as per' new RHot callbacks.
  39. //
  40. // 01/30/97 JMI Took Do() out of here and put in scrollbar.cpp.
  41. // Fixed rounding error in POS2PIXEL().
  42. //
  43. // 02/05/97 JMI Now has repeatability on up/left button, down/right
  44. // button, and tray presses. To do this in a consistent
  45. // way from the Do(), the up and down buttons had to be
  46. // changed to being hooked at the HotCall() level (like
  47. // the thumb has always been done).
  48. // This removed the need for static versions of the Up/
  49. // DownBtnCall()s.
  50. // Also, moved instantiable Up/DownBtnCall definitions to
  51. // the CPP.
  52. //
  53. // 03/19/97 JMI Converted to using the RHot::m_iecUser (was using
  54. // RHot::m_epcUser) so HotCall and CursorEvent now take
  55. // RInputEvent ptrs.
  56. //
  57. // 04/03/97 JMI Added components for optional timed, smooth scrolling.
  58. // This included overriding OnLoseFocus().
  59. //
  60. // 06/27/97 JMI Moved GetTray() definition from here to scrollbar.cpp.
  61. // SET_IF_NOT_NULL returned the expression even if the
  62. // passed ptr was NULL. This would be okay except for
  63. // the usage in GetTray() included the very same ptr passed
  64. // and deferenced as part of the expression.
  65. //
  66. // 09/22/97 JMI Also, added friend class CScrollBarPropPage for GUI
  67. // editor.
  68. //
  69. //////////////////////////////////////////////////////////////////////////////
  70. //
  71. // See CPP for description.
  72. //
  73. //////////////////////////////////////////////////////////////////////////////
  74. #ifndef SCROLLBAR_H
  75. #define SCROLLBAR_H
  76. //////////////////////////////////////////////////////////////////////////////
  77. // Headers.
  78. //////////////////////////////////////////////////////////////////////////////
  79. #include "System.h"
  80. // If PATHS_IN_INCLUDES macro is defined, we can utilized relative
  81. // paths to a header file. In this case we generally go off of our
  82. // RSPiX root directory. System.h MUST be included before this macro
  83. // is evaluated. System.h is the header that, based on the current
  84. // platform (or more so in this case on the compiler), defines
  85. // PATHS_IN_INCLUDES. Blue.h includes system.h so you can include that
  86. // instead.
  87. #ifdef PATHS_IN_INCLUDES
  88. #include "ORANGE/GUI/btn.h"
  89. #else
  90. #include "Btn.h"
  91. #endif // PATHS_IN_INCLUDES
  92. //////////////////////////////////////////////////////////////////////////////
  93. // Macros.
  94. //////////////////////////////////////////////////////////////////////////////
  95. // Converts a position value, lPos, to a short pixel position w/i the scroll
  96. // bar of orientation o.
  97. #define POS2PIXEL(lPos, o) ((short)((m_oOrientation == o) \
  98. ? ((float)(lPos - m_lMinPos) * m_fPos2PixelRatio + 0.5) \
  99. : 0))
  100. // Converts a position value to a pixel horizontal position w/i the scroll bar.
  101. #define HPOS2PIXEL(lPos) POS2PIXEL(lPos, Horizontal)
  102. // Converts a position value to a pixel vertical position w/i the scroll bar.
  103. #define VPOS2PIXEL(lPos) POS2PIXEL(lPos, Vertical)
  104. // Converts a pixel value (relative to Tray) to a long position value.
  105. #define PIXEL2POS(sPix) ((long)((float)(sPix) / m_fPos2PixelRatio) + m_lMinPos)
  106. // Converts one of two pixel values, dependent on orientation o, to a position
  107. // value.
  108. #define PIXELS2POS(sPixX, sPixY) PIXEL2POS((m_oOrientation == Vertical) \
  109. ? (sPixY) \
  110. : (sPixX) )
  111. // Sets a value pointed to if ptr is not NULL.
  112. #define SET_IF_NOT_NULL(pval, val) (((pval) != NULL) \
  113. ? *(pval) = (val) \
  114. : (0) )
  115. //////////////////////////////////////////////////////////////////////////////
  116. // Typedefs.
  117. //////////////////////////////////////////////////////////////////////////////
  118. //////////////////////////////////////////////////////////////////////////////
  119. class RScrollBar : public RGuiItem
  120. {
  121. public: // Construction/Destruction.
  122. // Default constructor.
  123. RScrollBar(void);
  124. // Destructor.
  125. ~RScrollBar(void);
  126. //////////////////////////////////////////////////////////////////////////////
  127. public:
  128. ////////////////////////////////////////////////////////////////////////
  129. // Enums.
  130. ////////////////////////////////////////////////////////////////////////
  131. typedef enum
  132. {
  133. Vertical, // For a vertical scrollbar.
  134. Horizontal // For a horizontal scrollbar. Very cryptic.
  135. } Orientation;
  136. typedef enum
  137. {
  138. Instant, // Snaps to user specified positions.
  139. Smooth // Slides to user specified positions.
  140. } Scrollage;
  141. ////////////////////////////////////////////////////////////////////////
  142. // Typedefs.
  143. ////////////////////////////////////////////////////////////////////////
  144. // User callback on change in position.
  145. typedef void (*UpdatePosCall)( // Returns nothing. Called when scroll
  146. // position is updated by any means.
  147. RScrollBar* psb); // this RScrollBar.
  148. public: // Methods.
  149. ////////////////////////////////////////////////////////////////////////
  150. // Methods.
  151. ////////////////////////////////////////////////////////////////////////
  152. //////////// Overridden ////////////////////////////////////////////////
  153. // Compose item.
  154. virtual // If you override this, call this base if possible.
  155. void Compose( // Returns nothing.
  156. RImage* pim = NULL); // Dest image, uses m_im if NULL.
  157. // Cursor event notification.
  158. // Events in event area.
  159. virtual // If you override this, call this base if possible.
  160. void CursorEvent( // Returns nothing.
  161. RInputEvent* pie); // In: Most recent user input event.
  162. // Out: pie->sUsed = TRUE, if used.
  163. // Destroys dynamic display data.
  164. virtual // If you override this, call this base if possible.
  165. void Destroy(void) // Returns nothing.
  166. {
  167. // Destroy children we know of.
  168. m_btnThumb.Destroy();
  169. m_btnUp.Destroy();
  170. m_btnDown.Destroy();
  171. // Destroy self.
  172. RGuiItem::Destroy();
  173. }
  174. // Activate or deactivate mouse reaction.
  175. virtual // If you override this, call this base if possible.
  176. void SetActive( // Returns nothing.
  177. short sActive) // TRUE to make active, FALSE otherwise.
  178. {
  179. m_btnThumb.SetActive(sActive);
  180. m_btnUp.SetActive(sActive);
  181. m_btnDown.SetActive(sActive);
  182. RGuiItem::SetActive(sActive);
  183. }
  184. // Called by the static implementation of SetFocus() on the item losing
  185. // the focus.
  186. // It is okay to call SetFocus() from this function.
  187. virtual // If you override this, call this base if possible.
  188. void OnLoseFocus(void)
  189. {
  190. // If scrolling smoothly . . .
  191. if (m_sInSmoothScroll != FALSE)
  192. {
  193. // Jump to destination, ending scrollage.
  194. SetPos(m_lScrollToPos);
  195. }
  196. // Call base class implementation.
  197. RGuiItem::OnLoseFocus();
  198. }
  199. ////////////////////////////////////////////////////////////////////////
  200. // Set the current position of the thumb in the scroll bar.
  201. // This value will be clipped to m_lMin and m_lMax.
  202. void SetPos( // Returns nothing.
  203. long lPos) // New position.
  204. {
  205. if (lPos > m_lMaxPos)
  206. {
  207. m_lCurPos = m_lMaxPos;
  208. }
  209. else
  210. {
  211. if (lPos < m_lMinPos)
  212. {
  213. m_lCurPos = m_lMinPos;
  214. }
  215. else
  216. {
  217. m_lCurPos = lPos;
  218. }
  219. }
  220. // If we've reached the destination of a smooth scroll . . .
  221. if (m_lCurPos == m_lScrollToPos)
  222. {
  223. m_sInSmoothScroll = FALSE;
  224. }
  225. short sX, sY, sW, sH;
  226. GetTray(&sX, &sY, &sW, &sH);
  227. m_btnThumb.Move(sX + HPOS2PIXEL(m_lCurPos), sY + VPOS2PIXEL(m_lCurPos));
  228. // If there's a callback . . .
  229. if (m_upcUser != NULL)
  230. {
  231. // Let user know.
  232. (*m_upcUser)(this);
  233. }
  234. }
  235. // Set the position the thumb will scroll to.
  236. // This value will be clipped to m_lMin and m_lMax.
  237. // This GUI must have the focus for correct operation.
  238. // If this GUI does not have the focus, SetPos() is called.
  239. void ScrollToPos( // Returns nothing.
  240. long lPos) // In: New position.
  241. {
  242. // If we don't have the focus . . .
  243. if (ms_pguiFocus != this)
  244. {
  245. SetPos(lPos);
  246. }
  247. else
  248. {
  249. if (lPos > m_lMaxPos)
  250. {
  251. m_lScrollToPos = m_lMaxPos;
  252. }
  253. else
  254. {
  255. if (lPos < m_lMinPos)
  256. {
  257. m_lScrollToPos = m_lMinPos;
  258. }
  259. else
  260. {
  261. m_lScrollToPos = lPos;
  262. }
  263. }
  264. // Start.
  265. m_sInSmoothScroll = TRUE;
  266. // Reset time.
  267. m_lLastSmoothTime = rspGetMilliseconds();
  268. }
  269. }
  270. // Sets the range of the scroll bar and sizes & moves the thumb
  271. // appropriately.
  272. void SetRange(
  273. long lMin,
  274. long lMax);
  275. // Hot call for thumb positioner.
  276. void ThumbHotCall( // Returns nothing.
  277. RInputEvent* pie); // In: Most recent user input event.
  278. // Out: pie->sUsed = TRUE, if used.
  279. // Hot call for up arrow.
  280. void UpHotCall( // Returns nothing.
  281. RInputEvent* pie); // In: Most recent user input event.
  282. // Out: pie->sUsed = TRUE, if used.
  283. // Hot call for down arrow.
  284. void DownHotCall( // Returns nothing.
  285. RInputEvent* pie); // In: Most recent user input event.
  286. // Out: pie->sUsed = TRUE, if used.
  287. // Called when up/left button pressed.
  288. void UpBtnPressed(void);
  289. // Called when down/right button pressed.
  290. void DownBtnPressed(void);
  291. // Copies border info from this GuiItem to the specified.
  292. void CopyBorderInfoTo(
  293. RGuiItem* pgui) // In: GuiItem to copy to.
  294. {
  295. pgui->m_u32BorderColor = m_u32BorderColor;
  296. pgui->m_u32BorderHighlightColor = m_u32BorderHighlightColor;
  297. pgui->m_u32BorderEdgeColor = m_u32BorderEdgeColor;
  298. pgui->m_u32BorderShadowColor = m_u32BorderShadowColor;
  299. pgui->m_u32TextColor = m_u32TextColor;
  300. pgui->m_u32BackColor = m_u32BackColor;
  301. // pgui->m_sBorderThickness = m_sBorderThickness;
  302. }
  303. // Does tasks that require constant update for scroll bar.
  304. // If called iteratively, the thumb can be dragged on the bar.
  305. virtual // If you override this, call this base if possible.
  306. void Do( // Returns nothing.
  307. RInputEvent* pie); // In: Most recent user input event.
  308. // Out: pie->sUsed = TRUE, if used.
  309. // Draws an appropriate arrow for this button.
  310. void DrawUpArrow( // Returns nothing.
  311. RImage* pim, // Image to draw into. Try to stay within
  312. // prc please.
  313. RRect* prc); // Where to in image.
  314. // Draws an appropriate arrow for this button.
  315. void DrawDownArrow( // Returns nothing.
  316. RImage* pim, // Image to draw into. Try to stay within
  317. // prc please.
  318. RRect* prc); // Where to in image.
  319. ////////////////////////////////////////////////////////////////////////
  320. // Querries.
  321. ////////////////////////////////////////////////////////////////////////
  322. // Get the current position of the thumb in the scroll bar.
  323. long GetPos(void)
  324. { return m_lCurPos; }
  325. // Gets the range of the scroll bar.
  326. void GetRange( // Returns nothing.
  327. long* plMin, // Out: Minimum position unless NULL.
  328. long* plMax) // Out: Maximum position unless NULL.
  329. {
  330. SET_IF_NOT_NULL(plMin, m_lMinPos);
  331. SET_IF_NOT_NULL(plMax, m_lMaxPos);
  332. }
  333. // Get position/size of tray relative to this item.
  334. void GetTray( // Returns nothing.
  335. short* psX, // Out: x coordinate of tray unless NULL.
  336. short* psY, // Out: y coordinate of tray unless NULL.
  337. short* psW, // Out: Width of tray unless NULL.
  338. short* psH); // Out: Height of tray unless NULL.
  339. // Get the "hot" area (i.e., clickable area) relative to this item.
  340. virtual // If you override this, call this base if possible.
  341. void GetHot( // Returns nothing.
  342. short* psX, // Out: X position unless NULL.
  343. short* psY, // Out: Y position unless NULL.
  344. short* psW, // Out: Width unless NULL.
  345. short* psH) // Out: Height unless NULL.
  346. {
  347. // Use tray area.
  348. GetTray(psX, psY, psW, psH);
  349. }
  350. //////////////////////////////////////////////////////////////////////////////
  351. public: // Static
  352. //////////////////////////////////////////////////////////////////////////////
  353. public: // Querries.
  354. //////////////////////////////////////////////////////////////////////////////
  355. protected: // Internal functions.
  356. // These handle callbacks for the buttons and thumb. They get an
  357. // instance for the scroll bar and call the equivalent instantiated
  358. // (non-static) functions.
  359. static void UpHotCall(
  360. RHot* phot, // Ptr to RHot that generated event.
  361. RInputEvent* pie) // In: Most recent user input event.
  362. // Out: pie->sUsed = TRUE, if used.
  363. { ((RScrollBar*)(phot->m_ulUser))->UpHotCall(pie); }
  364. static void DownHotCall(
  365. RHot* phot, // Ptr to RHot that generated event.
  366. RInputEvent* pie) // In: Most recent user input event.
  367. // Out: pie->sUsed = TRUE, if used.
  368. { ((RScrollBar*)(phot->m_ulUser))->DownHotCall(pie); }
  369. static void ThumbHotCall(
  370. RHot* phot, // Ptr to RHot that generated event.
  371. RInputEvent* pie) // In: Most recent user input event.
  372. // Out: pie->sUsed = TRUE, if used.
  373. { ((RScrollBar*)(phot->m_ulUser))->ThumbHotCall(pie); }
  374. static void DrawUpArrow( // Returns nothing.
  375. RGuiItem* pgui, // The RGuiItem being composed (this).
  376. RImage* pim, // Image to draw into. Try to stay within
  377. // prc please.
  378. RRect* prc) // Where to in image.
  379. { ((RScrollBar*)pgui->m_ulUserInstance)->DrawUpArrow(pim, prc); }
  380. static void DrawDownArrow( // Returns nothing.
  381. RGuiItem* pgui, // The RGuiItem being composed (this).
  382. RImage* pim, // Image to draw into. Try to stay within
  383. // prc please.
  384. RRect* prc) // Where to in image.
  385. { ((RScrollBar*)pgui->m_ulUserInstance)->DrawDownArrow(pim, prc); }
  386. // Save item's children to the specified file.
  387. virtual // Overridden here.
  388. short SaveChildren( // Returns 0 on success.
  389. RFile* pfile); // File to save to.
  390. // Load item's children from the specified file.
  391. virtual // Overridden here.
  392. short LoadChildren( // Returns 0 on success.
  393. RFile* pfile); // File to load from.
  394. // Read item's members from file.
  395. virtual // Overridden here.
  396. short ReadMembers( // Returns 0 on success.
  397. RFile* pfile, // File to read from.
  398. U32 u32Version); // File format version to use.
  399. // Write item's members to file.
  400. virtual // Overridden here.
  401. short WriteMembers( // Returns 0 on success.
  402. RFile* pfile); // File to write to.
  403. // Set position, usually as requested by user, using the specified
  404. // type of user feedback.
  405. void UserSetPos( // Returns nothing.
  406. long lPos) // In: New position.
  407. {
  408. switch (m_scrollage)
  409. {
  410. case Instant:
  411. SetPos(lPos);
  412. break;
  413. case Smooth:
  414. ScrollToPos(lPos);
  415. break;
  416. }
  417. }
  418. //////////////////////////////////////////////////////////////////////////////
  419. public: // Member variables.
  420. // Feel free to set the callbacks for these three Guis or the base class
  421. // to your own functions. But if you change gui.m_bcUser or
  422. // gui.m_ulUserInstace, you are responsible for calling SetPos() or the
  423. // callbacks (e.g., UpBtnPressed(void), DownBtnPressed(void), or
  424. // TrayPressed(void)) as appropriate.
  425. RBtn m_btnThumb; // Mobile positioner/indicator.
  426. RBtn m_btnUp; // Up or left arrow button.
  427. RBtn m_btnDown; // Down or right arrow button.
  428. long m_lButtonIncDec; // Amount to increment or decrement the
  429. // position when a button is pressed.
  430. long m_lTrayIncDec; // Amount to increment or decrement the
  431. // position when the tray is pressed.
  432. short m_sArrowBorderDistance; // Number of pixels between arrows'
  433. // edges and borders.
  434. UpdatePosCall m_upcUser; // User callback on postion change.
  435. Scrollage m_scrollage; // { RScrollBar::Instant,
  436. // RScrollBar::Smooth }
  437. long m_lPosPerSecond; // Number of positions smoothly scrolled
  438. // through in a second. The rate of
  439. // smooth scrollage.
  440. long m_lLastSmoothTime; // Last time smooth scroll was processed.
  441. long m_lScrollToPos; // Position to smoothly scroll to.
  442. // This GUI should have the focus to get
  443. // correct operation.
  444. short m_sInSmoothScroll; // TRUE, if we are in a smooth scroll.
  445. // FALSE, otherwise.
  446. // These values may be querried and can be changed directly.
  447. // BUT, they may not affect the appearance of the scroll bar
  448. // until Compose() is called.
  449. Orientation m_oOrientation; // { RScrollBar::Vertical,
  450. // RScrollBar::Horizontal }
  451. long m_lMinThumbLength; // Minimum length for thumb.
  452. short m_sClickOffsetX; // Position in thumb that was clicked.
  453. short m_sClickOffsetY; // Position in thumb that was clicked.
  454. protected: // Internal typedefs.
  455. protected: // Protected member variables.
  456. long m_lMinPos; // Minimum value.
  457. long m_lMaxPos; // Maximum value.
  458. long m_lCurPos; // Current value.
  459. float m_fPos2PixelRatio; // Current ratio of scroll bar
  460. // positions pixels to pixels.
  461. ///////////////////////////////////////////////////////////////////////////
  462. // Friends.
  463. ///////////////////////////////////////////////////////////////////////////
  464. friend class CScrollBarPropPage;
  465. };
  466. #endif // SCROLLBAR_H
  467. //////////////////////////////////////////////////////////////////////////////
  468. // EOF
  469. //////////////////////////////////////////////////////////////////////////////