PageRenderTime 62ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/NuGenDimension/NuGenDimension/NuGenDimension/Controls/OptionTree/OptionTreeRadioButton.cpp

https://github.com/AnthonyNystrom/GenXSource
C++ | 422 lines | 240 code | 83 blank | 99 comment | 42 complexity | d3ade516860dd9862289551ab7b79cf6 MD5 | raw file
  1. // COptionTree
  2. //
  3. // License
  4. // -------
  5. // This code is provided "as is" with no expressed or implied warranty.
  6. //
  7. // You may use this code in a commercial product with or without acknowledgement.
  8. // However you may not sell this code or any modification of this code, this includes
  9. // commercial libraries and anything else for profit.
  10. //
  11. // I would appreciate a notification of any bugs or bug fixes to help the control grow.
  12. //
  13. // History:
  14. // --------
  15. // See License.txt for full history information.
  16. //
  17. //
  18. // Copyright (c) 1999-2002
  19. // ComputerSmarts.net
  20. // mattrmiller@computersmarts.net
  21. #include "stdafx.h"
  22. #include "OptionTreeRadioButton.h"
  23. // Added Headers
  24. #include "OptionTree.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. /////////////////////////////////////////////////////////////////////////////
  31. // COptionTreeRadioButton
  32. COptionTreeRadioButton::COptionTreeRadioButton()
  33. {
  34. // Initialize variables
  35. m_nAllNodes = NULL;
  36. m_otRadioOption = NULL;
  37. }
  38. COptionTreeRadioButton::~COptionTreeRadioButton()
  39. {
  40. // Delete all nodes
  41. Node_DeleteAll();
  42. }
  43. BEGIN_MESSAGE_MAP(COptionTreeRadioButton, CWnd)
  44. //{{AFX_MSG_MAP(COptionTreeRadioButton)
  45. ON_WM_ERASEBKGND()
  46. ON_WM_PAINT()
  47. ON_WM_LBUTTONUP()
  48. ON_WM_MOVE()
  49. ON_WM_SIZE()
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // COptionTreeRadioButton message handlers
  54. void COptionTreeRadioButton::Node_Insert(CString strText, BOOL bChecked)
  55. {
  56. // Declare variables
  57. OT_RADIO_NODE *NewNode = new OT_RADIO_NODE;
  58. // Set up the New Node structure
  59. NewNode->m_bChecked = bChecked;
  60. NewNode->m_strText = strText;
  61. NewNode->m_rcHitRect = CRect(0, 0, 0, 0);
  62. NewNode->m_nNextNode = NULL;
  63. // Add new node to list
  64. // -- Do have any other node?
  65. if (m_nAllNodes == NULL)
  66. {
  67. m_nAllNodes = NewNode;
  68. return;
  69. }
  70. // -- Find the end of the list to add the new node to
  71. OT_RADIO_NODE *curr = m_nAllNodes;
  72. OT_RADIO_NODE *last = NULL;
  73. while (curr != NULL)
  74. {
  75. // -- -- Save this node
  76. last = curr;
  77. // -- -- Follow the link to the next node
  78. curr = curr->m_nNextNode;
  79. }
  80. // -- Link the new nod to the place we found
  81. last->m_nNextNode = NewNode;
  82. }
  83. void COptionTreeRadioButton::Node_DeleteAll()
  84. {
  85. // Do have any other results
  86. if (m_nAllNodes == NULL)
  87. {
  88. return;
  89. }
  90. // Declare variables
  91. OT_RADIO_NODE *curr = m_nAllNodes;
  92. OT_RADIO_NODE *last = NULL;
  93. // Check to see if we have only 1
  94. if (m_nAllNodes->m_nNextNode == NULL)
  95. {
  96. // -- Delete m_AllResults (head)
  97. curr = m_nAllNodes;
  98. delete curr;
  99. m_nAllNodes = NULL;
  100. return;
  101. }
  102. // Find the end of the list to add the new result to
  103. while (curr->m_nNextNode != NULL)
  104. {
  105. // -- Save this node
  106. last = curr;
  107. // -- Follow the link to the next node
  108. curr = curr->m_nNextNode;
  109. }
  110. // Delete this node and set last->m_nNextNode to NULL
  111. delete curr;
  112. last->m_nNextNode = NULL;
  113. // Check to see if we are at second to beginning
  114. if (m_nAllNodes->m_nNextNode == last)
  115. {
  116. // -- Delete last (which is second to head)
  117. delete last;
  118. // -- Delete m_AllResults (head)
  119. curr = m_nAllNodes;
  120. delete curr;
  121. m_nAllNodes = NULL;
  122. }
  123. // Call this again
  124. Node_DeleteAll();
  125. }
  126. OT_RADIO_NODE * COptionTreeRadioButton::Node_FindNode(int nIndex)
  127. {
  128. // Declare variables
  129. int i = 0;
  130. // Cycle through all of the nodes
  131. OT_RADIO_NODE *curr = m_nAllNodes;
  132. while (curr != NULL)
  133. {
  134. // -- See if this is us
  135. if (i == nIndex)
  136. {
  137. return curr;
  138. }
  139. // -- Follow the link to the next node
  140. curr = curr->m_nNextNode;
  141. // -- Increase i
  142. i++;
  143. }
  144. return NULL;
  145. }
  146. OT_RADIO_NODE *COptionTreeRadioButton::Node_FindNode(CString strText)
  147. {
  148. // Cycle through all of the nodes
  149. OT_RADIO_NODE *curr = m_nAllNodes;
  150. while (curr != NULL)
  151. {
  152. // -- See if this is us
  153. if (curr->m_strText == strText)
  154. {
  155. return curr;
  156. }
  157. // -- Follow the link to the next node
  158. curr = curr->m_nNextNode;
  159. }
  160. return NULL;
  161. }
  162. BOOL COptionTreeRadioButton::OnEraseBkgnd(CDC* pDC)
  163. {
  164. // Naa, we like flicker free better
  165. return FALSE;
  166. }
  167. void COptionTreeRadioButton::OnPaint()
  168. {
  169. // Make sure options aren't NULL
  170. if (m_otRadioOption == NULL)
  171. {
  172. return;
  173. }
  174. // Declare variables
  175. CPaintDC dc(this);
  176. CDC* pDCMem = new CDC;
  177. CBitmap bpMem;
  178. CBitmap *bmOld;
  179. HGDIOBJ hOldBrush;
  180. int nOldBack;
  181. CRect rcText, rcRadio, rcClient;
  182. HGDIOBJ hOld;
  183. OT_RADIO_NODE *nNode = NULL;
  184. int nIndex = 0;
  185. long lLastRadio = 0;
  186. COLORREF crOld;
  187. // Get client rectangle
  188. GetClientRect(rcClient);
  189. // Create DC
  190. pDCMem->CreateCompatibleDC(&dc);
  191. // Create bitmap
  192. bpMem.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
  193. // Select bitmap
  194. bmOld = pDCMem->SelectObject(&bpMem);
  195. // Set background mode
  196. nOldBack = pDCMem->SetBkMode(TRANSPARENT);
  197. // Set text color
  198. crOld = pDCMem->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
  199. // Select font
  200. hOld = pDCMem->SelectObject(m_otRadioOption->GetNormalFont());
  201. // Draw control background
  202. if (m_otRadioOption->IsWindowEnabled() == FALSE)
  203. {
  204. hOldBrush = pDCMem->SelectObject(GetSysColorBrush(COLOR_BTNFACE));
  205. }
  206. else
  207. {
  208. hOldBrush = pDCMem->SelectObject(GetSysColorBrush(COLOR_WINDOW));
  209. }
  210. pDCMem->PatBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), PATCOPY);
  211. // Calculate radio rect
  212. rcRadio.left = rcClient.left;
  213. rcRadio.right = rcClient.left + (long) OT_RADIO_SIZE;
  214. // Go through and draw all nodes
  215. nNode = Node_FindNode(nIndex);
  216. while (nNode != NULL)
  217. {
  218. // -- Calculate radio rect
  219. rcRadio.top = lLastRadio + OT_RADIO_VSPACE;
  220. rcRadio.bottom = rcRadio.top + (long) OT_RADIO_SIZE;
  221. // -- Calculate text rect
  222. rcText.top = lLastRadio + OT_RADIO_VSPACE;
  223. rcText.bottom = rcRadio.top + (long) OT_RADIO_SIZE;
  224. rcText.left = rcRadio.right + OT_SPACE;
  225. rcText.right = rcClient.right;
  226. // -- Save last radio
  227. lLastRadio = rcRadio.bottom;
  228. // -- Draw the radio
  229. if (nNode->m_bChecked == TRUE)
  230. {
  231. pDCMem->DrawFrameControl(&rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO | DFCS_CHECKED);
  232. }
  233. else
  234. {
  235. pDCMem->DrawFrameControl(&rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO);
  236. }
  237. // -- Draw text
  238. pDCMem->DrawText(nNode->m_strText, rcText, DT_SINGLELINE | DT_VCENTER);
  239. pDCMem->DrawText(nNode->m_strText, rcText, DT_SINGLELINE | DT_VCENTER | DT_CALCRECT);
  240. // -- Set hit test rect
  241. nNode->m_rcHitRect.left = rcRadio.left;
  242. nNode->m_rcHitRect.top = rcRadio.top;
  243. nNode->m_rcHitRect.bottom = rcRadio.bottom;
  244. nNode->m_rcHitRect.right = rcText.right;
  245. // -- Increase index
  246. nIndex++;
  247. // -- Get next node
  248. nNode = Node_FindNode(nIndex);
  249. }
  250. // Copy to screen
  251. dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDCMem, 0, 0, SRCCOPY);
  252. // Restore GDI ojects
  253. pDCMem->SelectObject(bmOld);
  254. pDCMem->SelectObject(hOldBrush);
  255. pDCMem->SetBkMode(nOldBack);
  256. pDCMem->SelectObject(hOld);
  257. pDCMem->SetTextColor(crOld);
  258. // Delete objects
  259. if (pDCMem->GetSafeHdc() != NULL)
  260. {
  261. pDCMem->DeleteDC();
  262. }
  263. delete pDCMem;
  264. if (bpMem.GetSafeHandle() != NULL)
  265. {
  266. bpMem.DeleteObject();
  267. }
  268. }
  269. void COptionTreeRadioButton::SetRadioOptionsOwner(COptionTree *otOption)
  270. {
  271. // Save pointer
  272. m_otRadioOption = otOption;
  273. }
  274. void COptionTreeRadioButton::Node_UnCheckAll()
  275. {
  276. // Cycle through all of the nodes
  277. OT_RADIO_NODE *curr = m_nAllNodes;
  278. while (curr != NULL)
  279. {
  280. // -- Un Check
  281. curr->m_bChecked = FALSE;
  282. // -- Follow the link to the next node
  283. curr = curr->m_nNextNode;
  284. }
  285. }
  286. void COptionTreeRadioButton::OnLButtonUp(UINT nFlags, CPoint point)
  287. {
  288. // Run a hit test on all radios
  289. OT_RADIO_NODE *curr = m_nAllNodes;
  290. while (curr != NULL)
  291. {
  292. // -- See if checked
  293. if (curr->m_rcHitRect.PtInRect(point) == TRUE)
  294. {
  295. // -- -- Uncheck all
  296. Node_UnCheckAll();
  297. // -- -- Check this radio
  298. curr->m_bChecked = TRUE;
  299. // -- -- Force redaw
  300. Invalidate();
  301. // -- -- Update window
  302. UpdateWindow();
  303. break;
  304. }
  305. // -- Follow the link to the next node
  306. curr = curr->m_nNextNode;
  307. }
  308. CWnd::OnLButtonUp(nFlags, point);
  309. }
  310. void COptionTreeRadioButton::OnMove(int x, int y)
  311. {
  312. CWnd::OnMove(x, y);
  313. // TODO: Add your message handler code here
  314. }
  315. void COptionTreeRadioButton::OnSize(UINT nType, int cx, int cy)
  316. {
  317. CWnd::OnSize(nType, cx, cy);
  318. // TODO: Add your message handler code here
  319. }
  320. int COptionTreeRadioButton::Node_GetChecked()
  321. {
  322. // Declare variables
  323. int i = 0;
  324. // Cycle through all of the nodes
  325. OT_RADIO_NODE *curr = m_nAllNodes;
  326. while (curr != NULL)
  327. {
  328. // -- See if this is us
  329. if (curr->m_bChecked == TRUE)
  330. {
  331. return i;
  332. }
  333. // -- Follow the link to the next node
  334. curr = curr->m_nNextNode;
  335. // -- Increase i
  336. i++;
  337. }
  338. return -1;
  339. }