drawtool.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:11k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // drawtool.cpp - implementation for drawing tools
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "drawcli.h"
  22. #include "drawdoc.h"
  23. #include "drawvw.h"
  24. #include "drawobj.h"
  25. #include "drawtool.h"
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CDrawTool implementation
  28. CPtrList CDrawTool::c_tools;
  29. static CSelectTool selectTool;
  30. static CRectTool lineTool(line);
  31. static CRectTool rectTool(rect);
  32. static CRectTool roundRectTool(roundRect);
  33. static CRectTool ellipseTool(ellipse);
  34. static CPolyTool polyTool;
  35. CPoint CDrawTool::c_down;
  36. UINT CDrawTool::c_nDownFlags;
  37. CPoint CDrawTool::c_last;
  38. DrawShape CDrawTool::c_drawShape = selection;
  39. CDrawTool::CDrawTool(DrawShape drawShape)
  40. {
  41. m_drawShape = drawShape;
  42. c_tools.AddTail(this);
  43. }
  44. CDrawTool* CDrawTool::FindTool(DrawShape drawShape)
  45. {
  46. POSITION pos = c_tools.GetHeadPosition();
  47. while (pos != NULL)
  48. {
  49. CDrawTool* pTool = (CDrawTool*)c_tools.GetNext(pos);
  50. if (pTool->m_drawShape == drawShape)
  51. return pTool;
  52. }
  53. return NULL;
  54. }
  55. void CDrawTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
  56. {
  57. // deactivate any in-place active item on this view!
  58. COleClientItem* pActiveItem = pView->GetDocument()->GetInPlaceActiveItem(pView);
  59. if (pActiveItem != NULL)
  60. {
  61. pActiveItem->Close();
  62. ASSERT(pView->GetDocument()->GetInPlaceActiveItem(pView) == NULL);
  63. }
  64. pView->SetCapture();
  65. c_nDownFlags = nFlags;
  66. c_down = point;
  67. c_last = point;
  68. }
  69. void CDrawTool::OnLButtonDblClk(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& /*point*/)
  70. {
  71. }
  72. void CDrawTool::OnLButtonUp(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& point)
  73. {
  74. ReleaseCapture();
  75. if (point == c_down)
  76. c_drawShape = selection;
  77. }
  78. void CDrawTool::OnMouseMove(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& point)
  79. {
  80. c_last = point;
  81. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
  82. }
  83. void CDrawTool::OnEditProperties(CDrawView* /*pView*/)
  84. {
  85. }
  86. void CDrawTool::OnCancel()
  87. {
  88. c_drawShape = selection;
  89. }
  90. ////////////////////////////////////////////////////////////////////////////
  91. // CResizeTool
  92. enum SelectMode
  93. {
  94. selnone,
  95. netSelect,
  96. move,
  97. size
  98. };
  99. SelectMode selectMode = selnone;
  100. int nDragHandle;
  101. CPoint lastPoint;
  102. CSelectTool::CSelectTool()
  103. : CDrawTool(selection)
  104. {
  105. }
  106. void CSelectTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
  107. {
  108. CPoint local = point;
  109. pView->ClientToDoc(local);
  110. CDrawObj* pObj;
  111. selectMode = selnone;
  112. ((CMainFrame*)AfxGetMainWnd())->m_bInUpdate = TRUE;
  113. // Check for resizing (only allowed on single selections)
  114. if (pView->m_selection.GetCount() == 1)
  115. {
  116. pObj = pView->m_selection.GetHead();
  117. nDragHandle = pObj->HitTest(local, pView, TRUE);
  118. if (nDragHandle != 0)
  119. selectMode = size;
  120. }
  121. // See if the click was on an object, select and start move if so
  122. if (selectMode == selnone)
  123. {
  124. pObj = pView->GetDocument()->ObjectAt(local);
  125. if (pObj != NULL)
  126. {
  127. selectMode = move;
  128. if (!pView->IsSelected(pObj))
  129. pView->Select(pObj, (nFlags & MK_SHIFT) != 0);
  130. // Ctrl+Click clones the selection...
  131. if ((nFlags & MK_CONTROL) != 0)
  132. pView->CloneSelection();
  133. }
  134. }
  135. // Click on background, start a net-selection
  136. if (selectMode == selnone)
  137. {
  138. if ((nFlags & MK_SHIFT) == 0)
  139. pView->Select(NULL);
  140. selectMode = netSelect;
  141. CClientDC dc(pView);
  142. CRect rect(point.x, point.y, point.x, point.y);
  143. rect.NormalizeRect();
  144. dc.DrawFocusRect(rect);
  145. }
  146. ((CMainFrame*)AfxGetMainWnd())->m_bInUpdate = FALSE;
  147. ((CMainFrame*)AfxGetMainWnd())->UpdatePropertyGridContent(pView);
  148. lastPoint = local;
  149. CDrawTool::OnLButtonDown(pView, nFlags, point);
  150. }
  151. void CSelectTool::OnLButtonDblClk(CDrawView* pView, UINT nFlags, const CPoint& point)
  152. {
  153. if ((nFlags & MK_SHIFT) != 0)
  154. {
  155. // Shift+DblClk deselects object...
  156. CPoint local = point;
  157. pView->ClientToDoc(local);
  158. CDrawObj* pObj = pView->GetDocument()->ObjectAt(local);
  159. if (pObj != NULL)
  160. pView->Deselect(pObj);
  161. }
  162. else
  163. {
  164. // "Normal" DblClk opens properties, or OLE server...
  165. if (pView->m_selection.GetCount() == 1)
  166. pView->m_selection.GetHead()->OnOpen(pView);
  167. }
  168. CDrawTool::OnLButtonDblClk(pView, nFlags, point);
  169. }
  170. void CSelectTool::OnEditProperties(CDrawView* pView)
  171. {
  172. if (pView->m_selection.GetCount() == 1)
  173. pView->m_selection.GetHead()->OnEditProperties();
  174. }
  175. void CSelectTool::OnLButtonUp(CDrawView* pView, UINT nFlags, const CPoint& point)
  176. {
  177. if (pView->GetCapture() == pView)
  178. {
  179. if (selectMode == netSelect)
  180. {
  181. CClientDC dc(pView);
  182. CRect rect(c_down.x, c_down.y, c_last.x, c_last.y);
  183. rect.NormalizeRect();
  184. dc.DrawFocusRect(rect);
  185. pView->SelectWithinRect(rect, TRUE);
  186. }
  187. else if (selectMode != selnone)
  188. {
  189. pView->GetDocument()->UpdateAllViews(pView);
  190. }
  191. }
  192. CDrawTool::OnLButtonUp(pView, nFlags, point);
  193. }
  194. void CSelectTool::OnMouseMove(CDrawView* pView, UINT nFlags, const CPoint& point)
  195. {
  196. if (pView->GetCapture() != pView)
  197. {
  198. if (c_drawShape == selection && pView->m_selection.GetCount() == 1)
  199. {
  200. CDrawObj* pObj = pView->m_selection.GetHead();
  201. CPoint local = point;
  202. pView->ClientToDoc(local);
  203. int nHandle = pObj->HitTest(local, pView, TRUE);
  204. if (nHandle != 0)
  205. {
  206. SetCursor(pObj->GetHandleCursor(nHandle));
  207. return; // bypass CDrawTool
  208. }
  209. }
  210. if (c_drawShape == selection)
  211. CDrawTool::OnMouseMove(pView, nFlags, point);
  212. return;
  213. }
  214. if (selectMode == netSelect)
  215. {
  216. CClientDC dc(pView);
  217. CRect rect(c_down.x, c_down.y, c_last.x, c_last.y);
  218. rect.NormalizeRect();
  219. dc.DrawFocusRect(rect);
  220. rect.SetRect(c_down.x, c_down.y, point.x, point.y);
  221. rect.NormalizeRect();
  222. dc.DrawFocusRect(rect);
  223. CDrawTool::OnMouseMove(pView, nFlags, point);
  224. return;
  225. }
  226. CPoint local = point;
  227. pView->ClientToDoc(local);
  228. CPoint delta = (CPoint)(local - lastPoint);
  229. POSITION pos = pView->m_selection.GetHeadPosition();
  230. while (pos != NULL)
  231. {
  232. CDrawObj* pObj = pView->m_selection.GetNext(pos);
  233. CRect position = pObj->m_position;
  234. if (selectMode == move)
  235. {
  236. position += delta;
  237. pObj->MoveTo(position, pView);
  238. }
  239. else if (nDragHandle != 0)
  240. {
  241. pObj->MoveHandleTo(nDragHandle, local, pView);
  242. }
  243. }
  244. lastPoint = local;
  245. if (selectMode == size && c_drawShape == selection)
  246. {
  247. c_last = point;
  248. SetCursor(pView->m_selection.GetHead()->GetHandleCursor(nDragHandle));
  249. return; // bypass CDrawTool
  250. }
  251. c_last = point;
  252. if (c_drawShape == selection)
  253. CDrawTool::OnMouseMove(pView, nFlags, point);
  254. }
  255. ////////////////////////////////////////////////////////////////////////////
  256. // CRectTool (does rectangles, round-rectangles, and ellipses)
  257. CRectTool::CRectTool(DrawShape drawShape)
  258. : CDrawTool(drawShape)
  259. {
  260. }
  261. void CRectTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
  262. {
  263. CDrawTool::OnLButtonDown(pView, nFlags, point);
  264. CPoint local = point;
  265. pView->ClientToDoc(local);
  266. CDrawRect* pObj = new CDrawRect(CRect(local, CSize(0, 0)));
  267. switch (m_drawShape)
  268. {
  269. default:
  270. ASSERT(FALSE); // unsuported shape!
  271. case rect:
  272. pObj->m_nShape = CDrawRect::rectangle;
  273. break;
  274. case roundRect:
  275. pObj->m_nShape = CDrawRect::roundRectangle;
  276. break;
  277. case ellipse:
  278. pObj->m_nShape = CDrawRect::ellipse;
  279. break;
  280. case line:
  281. pObj->m_nShape = CDrawRect::line;
  282. break;
  283. }
  284. pView->GetDocument()->Add(pObj);
  285. pView->Select(pObj);
  286. selectMode = size;
  287. nDragHandle = 1;
  288. lastPoint = local;
  289. }
  290. void CRectTool::OnLButtonDblClk(CDrawView* pView, UINT nFlags, const CPoint& point)
  291. {
  292. CDrawTool::OnLButtonDblClk(pView, nFlags, point);
  293. }
  294. void CRectTool::OnLButtonUp(CDrawView* pView, UINT nFlags, const CPoint& point)
  295. {
  296. if (point == c_down)
  297. {
  298. // Don't create empty objects...
  299. CDrawObj *pObj = pView->m_selection.GetTail();
  300. pView->GetDocument()->Remove(pObj);
  301. pObj->Remove();
  302. selectTool.OnLButtonDown(pView, nFlags, point); // try a select!
  303. }
  304. selectTool.OnLButtonUp(pView, nFlags, point);
  305. }
  306. void CRectTool::OnMouseMove(CDrawView* pView, UINT nFlags, const CPoint& point)
  307. {
  308. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
  309. selectTool.OnMouseMove(pView, nFlags, point);
  310. }
  311. ////////////////////////////////////////////////////////////////////////////
  312. // CPolyTool
  313. CPolyTool::CPolyTool()
  314. : CDrawTool(poly)
  315. {
  316. m_pDrawObj = NULL;
  317. }
  318. void CPolyTool::OnLButtonDown(CDrawView* pView, UINT nFlags, const CPoint& point)
  319. {
  320. CDrawTool::OnLButtonDown(pView, nFlags, point);
  321. CPoint local = point;
  322. pView->ClientToDoc(local);
  323. if (m_pDrawObj == NULL)
  324. {
  325. pView->SetCapture();
  326. m_pDrawObj = new CDrawPoly(CRect(local, CSize(0, 0)));
  327. pView->GetDocument()->Add(m_pDrawObj);
  328. pView->Select(m_pDrawObj);
  329. m_pDrawObj->AddPoint(local, pView);
  330. }
  331. else if (local == m_pDrawObj->m_points[0])
  332. {
  333. // Stop when the first point is repeated...
  334. ReleaseCapture();
  335. m_pDrawObj->m_nPoints -= 1;
  336. if (m_pDrawObj->m_nPoints < 2)
  337. {
  338. m_pDrawObj->Remove();
  339. }
  340. else
  341. {
  342. pView->InvalObj(m_pDrawObj);
  343. }
  344. m_pDrawObj = NULL;
  345. c_drawShape = selection;
  346. return;
  347. }
  348. local.x += 1; // adjacent points can't be the same!
  349. m_pDrawObj->AddPoint(local, pView);
  350. selectMode = size;
  351. nDragHandle = m_pDrawObj->GetHandleCount();
  352. lastPoint = local;
  353. }
  354. void CPolyTool::OnLButtonUp(CDrawView* /*pView*/, UINT /*nFlags*/, const CPoint& /*point*/)
  355. {
  356. // Don't release capture yet!
  357. }
  358. void CPolyTool::OnMouseMove(CDrawView* pView, UINT nFlags, const CPoint& point)
  359. {
  360. if (m_pDrawObj != NULL && (nFlags & MK_LBUTTON) != 0)
  361. {
  362. CPoint local = point;
  363. pView->ClientToDoc(local);
  364. m_pDrawObj->AddPoint(local);
  365. nDragHandle = m_pDrawObj->GetHandleCount();
  366. lastPoint = local;
  367. c_last = point;
  368. SetCursor(AfxGetApp()->LoadCursor(IDC_PENCIL));
  369. }
  370. else
  371. {
  372. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
  373. selectTool.OnMouseMove(pView, nFlags, point);
  374. }
  375. }
  376. void CPolyTool::OnLButtonDblClk(CDrawView* pView, UINT , const CPoint& )
  377. {
  378. ReleaseCapture();
  379. int nPoints = m_pDrawObj->m_nPoints;
  380. if (nPoints > 2 &&
  381. (m_pDrawObj->m_points[nPoints - 1] == m_pDrawObj->m_points[nPoints - 2] ||
  382. m_pDrawObj->m_points[nPoints - 1].x - 1 == m_pDrawObj->m_points[nPoints - 2].x &&
  383. m_pDrawObj->m_points[nPoints - 1].y == m_pDrawObj->m_points[nPoints - 2].y))
  384. {
  385. // Nuke the last point if it's the same as the next to last...
  386. m_pDrawObj->m_nPoints -= 1;
  387. pView->InvalObj(m_pDrawObj);
  388. }
  389. m_pDrawObj = NULL;
  390. c_drawShape = selection;
  391. }
  392. void CPolyTool::OnCancel()
  393. {
  394. CDrawTool::OnCancel();
  395. m_pDrawObj = NULL;
  396. }
  397. /////////////////////////////////////////////////////////////////////////////