PushBtn.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. // PUSHBTN.CPP
  21. //
  22. // History:
  23. // 02/05/97 JMI Started.
  24. //
  25. // 02/05/97 JMI Forgot to make sure we were actually clicked in before
  26. // processing a release within cursor event area.
  27. //
  28. // 02/05/97 JMI Forgot to remove a debug TRACE.
  29. //
  30. // 03/19/97 JMI Converted to using the RHot::m_iecUser (was using
  31. // RHot::m_epcUser) so HotCall and CursorEvent now take
  32. // RInputEvent ptrs.
  33. //
  34. // 03/28/97 JMI RSP_MB0_DOUBLECLICK is now treated the same as
  35. // RSP_MB0_PRESSED.
  36. //
  37. // 04/16/97 JMI In previous update, forgot to add case RSP_MB0_DOUBLECLICK
  38. // in both places need for this implentation of CursorEvent().
  39. //
  40. //////////////////////////////////////////////////////////////////////////////
  41. //
  42. // This a GUI item that is based on the basic RGuiItem.
  43. // This overrides HotCall() to get information about where a click in its CHot
  44. // occurred.
  45. // This overrides Compose() to add text.
  46. //
  47. // Enhancements/Uses:
  48. // To change the look of a button when pressed, you may want to override the
  49. // Compose() or DrawBorder() in a derived class.
  50. // To change the background of a button, see RGuiItem.
  51. // To get a callback on a click/release pair in the button, set m_bcUser.
  52. //
  53. //////////////////////////////////////////////////////////////////////////////
  54. //////////////////////////////////////////////////////////////////////////////
  55. // Headers.
  56. //////////////////////////////////////////////////////////////////////////////
  57. #include "Blue.h"
  58. #ifdef PATHS_IN_INCLUDES
  59. #include "ORANGE/GUI/PushBtn.h"
  60. #else
  61. #include "PushBtn.h"
  62. #endif // PATHS_IN_INCLUDES
  63. //////////////////////////////////////////////////////////////////////////////
  64. // Module specific macros.
  65. //////////////////////////////////////////////////////////////////////////////
  66. // Sets val to def if val is -1.
  67. #define DEF(val, def) ((val == -1) ? def : val)
  68. //////////////////////////////////////////////////////////////////////////////
  69. // Module specific typedefs.
  70. //////////////////////////////////////////////////////////////////////////////
  71. //////////////////////////////////////////////////////////////////////////////
  72. // Module specific (static) variables.
  73. //////////////////////////////////////////////////////////////////////////////
  74. //////////////////////////////////////////////////////////////////////////////
  75. // Construction/Destruction.
  76. //////////////////////////////////////////////////////////////////////////////
  77. //////////////////////////////////////////////////////////////////////////////
  78. //
  79. // Default constructor.
  80. //
  81. //////////////////////////////////////////////////////////////////////////////
  82. RPushBtn::RPushBtn()
  83. {
  84. // Override RGuiItem's default justification.
  85. m_justification = RGuiItem::Centered;
  86. m_type = PushBtn; // Indicates type of GUI item.
  87. // Initialize RPushBtn members.
  88. m_state = Off; // The button's current state (On or Off (see enums)).
  89. }
  90. //////////////////////////////////////////////////////////////////////////////
  91. //
  92. // Destructor.
  93. //
  94. //////////////////////////////////////////////////////////////////////////////
  95. RPushBtn::~RPushBtn()
  96. {
  97. }
  98. ////////////////////////////////////////////////////////////////////////
  99. // Methods.
  100. ////////////////////////////////////////////////////////////////////////
  101. ////////////////////////////////////////////////////////////////////////
  102. //
  103. // Compose item.
  104. //
  105. ////////////////////////////////////////////////////////////////////////
  106. void RPushBtn::Compose( // Returns nothing.
  107. RImage* pim /*= NULL*/) // Dest image, uses m_im if NULL.
  108. {
  109. if (pim == NULL)
  110. {
  111. pim = &m_im;
  112. }
  113. if (m_sPressed != FALSE || m_state == On)
  114. {
  115. // Invert border.
  116. m_sInvertedBorder = TRUE;
  117. }
  118. else
  119. {
  120. m_sInvertedBorder = FALSE;
  121. }
  122. // Call base (draws border and background).
  123. RGuiItem::Compose(pim);
  124. // Draw pushbtn stuff.
  125. short sX, sY, sW, sH;
  126. // Get client relative to border so we know where to
  127. // put the text.
  128. GetClient(&sX, &sY, &sW, &sH);
  129. // Draw text.
  130. DrawText(sX, sY, sW, sH, pim);
  131. }
  132. ////////////////////////////////////////////////////////////////////////
  133. //
  134. // Cursor event notification.
  135. // Events in event area.
  136. // (virtual).
  137. //
  138. ////////////////////////////////////////////////////////////////////////
  139. void RPushBtn::CursorEvent( // Returns nothing.
  140. RInputEvent* pie) // In: Most recent user input event.
  141. // Out: pie->sUsed = TRUE, if used.
  142. {
  143. switch (pie->sEvent)
  144. {
  145. case RSP_MB0_DOUBLECLICK:
  146. case RSP_MB0_RELEASED:
  147. // If we were clicked in . . .
  148. if (m_sPressed != FALSE)
  149. {
  150. // Do change of state right away so user callback gets the new
  151. // value.
  152. // If within event area . . .
  153. if ( pie->sPosX >= m_sEventAreaX && pie->sPosX < m_sEventAreaX + m_sEventAreaW
  154. && pie->sPosY >= m_sEventAreaY && pie->sPosY < m_sEventAreaY + m_sEventAreaH)
  155. {
  156. // Change state.
  157. m_state = (m_state == Off) ? On : Off;
  158. }
  159. }
  160. break;
  161. }
  162. // Call base.
  163. RGuiItem::CursorEvent(pie);
  164. switch (pie->sEvent)
  165. {
  166. case RSP_MB0_DOUBLECLICK:
  167. case RSP_MB0_PRESSED:
  168. // Always recompose on press, since there's so many possibilities
  169. // with this button.
  170. Compose();
  171. // Note that we used it.
  172. pie->sUsed = TRUE;
  173. break;
  174. case RSP_MB0_RELEASED:
  175. // Always recompose on release, since there's so many possibilities
  176. // with this button.
  177. Compose();
  178. // Note that we used it.
  179. pie->sUsed = TRUE;
  180. break;
  181. }
  182. }
  183. //////////////////////////////////////////////////////////////////////////////
  184. //
  185. // Draw border.
  186. // (virtual (Overridden here)).
  187. //
  188. //////////////////////////////////////////////////////////////////////////////
  189. void RPushBtn::DrawBorder( // Returns nothing.
  190. RImage* pim /*= NULL*/, // Dest image, uses m_im if NULL.
  191. short sInvert /*= FALSE*/) // Inverts border if TRUE.
  192. {
  193. short sVertShadowPos;
  194. short sHorzShadowPos;
  195. short sVertHighlightPos;
  196. short sHorzHighlightPos;
  197. short sVertEdgePos;
  198. short sHorzEdgePos;
  199. short sShadowThickness = m_sBorderThickness;
  200. short sEdgeThickness = m_sBorderThickness;
  201. short sHighlightThickness = m_sBorderThickness;
  202. if (pim == NULL)
  203. {
  204. pim = &m_im;
  205. }
  206. short sW = pim->m_sWidth;
  207. short sH = pim->m_sHeight;
  208. m_sInvertedBorder = sInvert;
  209. if (sInvert == FALSE)
  210. {
  211. sVertShadowPos = sW - m_sBorderThickness;
  212. sHorzShadowPos = sH - m_sBorderThickness;
  213. sVertHighlightPos = 0;
  214. sHorzHighlightPos = 0;
  215. sVertEdgePos = sW - m_sBorderThickness * 2;
  216. sHorzEdgePos = sH - m_sBorderThickness * 2;
  217. }
  218. else
  219. {
  220. // Left top becomes thicker when pressed.
  221. sShadowThickness = (m_sPressed == FALSE) ? m_sBorderThickness
  222. : (m_sBorderThickness * 2);
  223. sEdgeThickness = sShadowThickness;
  224. sHighlightThickness = m_sBorderThickness;//sShadowThickness;
  225. sVertShadowPos = 0;
  226. sHorzShadowPos = 0;
  227. sVertHighlightPos = sW - sHighlightThickness;
  228. sHorzHighlightPos = sH - sHighlightThickness;
  229. sVertEdgePos = sShadowThickness;
  230. sHorzEdgePos = sShadowThickness;
  231. }
  232. // One pixel for each edge of border gets overwritten.
  233. rspRect(m_u32BorderHighlightColor, pim, 0, sHorzHighlightPos, sW, sHighlightThickness);
  234. rspRect(m_u32BorderHighlightColor, pim, sVertHighlightPos, 0, sHighlightThickness, sH);
  235. rspRect(m_u32BorderShadowColor, pim, 0, sHorzShadowPos, sW, sShadowThickness);
  236. rspRect(m_u32BorderShadowColor, pim, sVertShadowPos, 0, sShadowThickness, sH);
  237. rspRect(m_u32BorderEdgeColor, pim, sShadowThickness, sHorzEdgePos, sW - sShadowThickness - sEdgeThickness, sEdgeThickness);
  238. rspRect(m_u32BorderEdgeColor, pim, sVertEdgePos, sShadowThickness, sEdgeThickness, sH - sShadowThickness - sEdgeThickness);
  239. }
  240. //////////////////////////////////////////////////////////////////////////////
  241. // Querries.
  242. //////////////////////////////////////////////////////////////////////////////
  243. //////////////////////////////////////////////////////////////////////////////
  244. //
  245. // Gets the thickness of the top/left border (including border edge effect).
  246. // (virtual (Overridden here)).
  247. //
  248. //////////////////////////////////////////////////////////////////////////////
  249. short RPushBtn::GetTopLeftBorderThickness(void) // Returns border thickness
  250. // including edge effect.
  251. {
  252. if (m_sBorderThickness == 0)
  253. return 0;
  254. else
  255. return (m_sBorderThickness
  256. + ((m_sInvertedBorder == FALSE) ? 0 : m_sBorderThickness) )
  257. * ((m_sPressed == FALSE) ? 1 : 2);
  258. }
  259. //////////////////////////////////////////////////////////////////////////////
  260. //
  261. // Gets the thickness of the bottom/right border (including border edge effect).
  262. // (virtual (Overridden here)).
  263. //
  264. //////////////////////////////////////////////////////////////////////////////
  265. short RPushBtn::GetBottomRightBorderThickness(void) // Returns border thickness
  266. // including edge effect.
  267. {
  268. if (m_sBorderThickness == 0)
  269. return 0;
  270. else
  271. return (m_sBorderThickness
  272. + ((m_sInvertedBorder == FALSE) ? m_sBorderThickness : 0) )
  273. ;// * ((m_sPressed == FALSE) ? 1 : 2);
  274. }
  275. //////////////////////////////////////////////////////////////////////////////
  276. // EOF
  277. //////////////////////////////////////////////////////////////////////////////