Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
14 KiB

  1. /******************************************************************************/
  2. /* T_FHSEL.CPP: IMPLEMENTATION OF THE CFreehandSelectTool CLASS */
  3. /* */
  4. /* */
  5. /******************************************************************************/
  6. /* */
  7. /* Methods in this file */
  8. /* */
  9. /******************************************************************************/
  10. /* */
  11. /******************************************************************************/
  12. #include "stdafx.h"
  13. #include "global.h"
  14. #include "pbrush.h"
  15. #include "pbrusdoc.h"
  16. #include "pbrusfrm.h"
  17. #include "bmobject.h"
  18. #include "imgsuprt.h"
  19. #include "imgbrush.h"
  20. #include "imgwnd.h"
  21. #include "imgwell.h"
  22. #include "t_fhsel.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static CHAR BASED_CODE THIS_FILE[] = __FILE__;
  26. #endif
  27. IMPLEMENT_DYNAMIC( CFreehandSelectTool, CPolygonTool )
  28. #include "memtrace.h"
  29. extern CSelectTool NEAR g_selectTool;
  30. CFreehandSelectTool NEAR g_freehandselectTool;
  31. /******************************************************************************/
  32. CFreehandSelectTool::CFreehandSelectTool()
  33. {
  34. m_bIsUndoable = FALSE;
  35. m_nCmdID = IDMB_PICKRGNTOOL;
  36. m_bCanBePrevTool = FALSE;
  37. m_bFilled = FALSE;
  38. m_bBorder = FALSE;
  39. m_nStrokeWidth = 1;
  40. m_pcRgnPoly = &(theImgBrush.m_cRgnPolyFreeHandSel);
  41. m_pcRgnPolyBorder = &(theImgBrush.m_cRgnPolyFreeHandSelBorder);
  42. }
  43. /******************************************************************************/
  44. CFreehandSelectTool::~CFreehandSelectTool()
  45. {
  46. }
  47. /******************************************************************************/
  48. void CFreehandSelectTool::AdjustPointsForZoom(int iZoom)
  49. {
  50. int iSize = (int)m_cObArrayPoints.GetSize();
  51. CPoint *pcPoint;
  52. for (int i = 0; i < iSize; i++)
  53. {
  54. pcPoint= (CPoint *)m_cObArrayPoints.GetAt(i);
  55. pcPoint->x *= iZoom;
  56. pcPoint->y *= iZoom;
  57. }
  58. }
  59. /******************************************************************************/
  60. BOOL CFreehandSelectTool::CreatePolyRegion( int iZoom )
  61. {
  62. BOOL bRC = TRUE;
  63. CPoint *pcPointArray;
  64. // cleanup old region if exists
  65. if (m_pcRgnPoly->GetSafeHandle())
  66. m_pcRgnPoly->DeleteObject();
  67. // cleanup old region if exists
  68. if (m_pcRgnPolyBorder->GetSafeHandle())
  69. m_pcRgnPolyBorder->DeleteObject();
  70. bRC = CopyPointsToMemArray( &pcPointArray, &m_iNumPoints );
  71. if (! bRC)
  72. {
  73. theApp.SetMemoryEmergency();
  74. return FALSE;
  75. }
  76. bRC = m_pcRgnPoly->CreatePolygonRgn( pcPointArray, m_iNumPoints, ALTERNATE );
  77. delete [] pcPointArray;
  78. if (! bRC) // offset for selection boundary
  79. {
  80. theApp.SetGdiEmergency();
  81. return FALSE;
  82. }
  83. m_pcRgnPoly->OffsetRgn( -m_cRectBounding.left,
  84. -m_cRectBounding.top );
  85. //
  86. // This adjustment appears to be unnecessary. removed it 5/1/1997
  87. // AdjustPointsForZoom( iZoom );
  88. bRC = CopyPointsToMemArray( &pcPointArray, &m_iNumPoints );
  89. if (bRC)
  90. {
  91. bRC = m_pcRgnPolyBorder->CreatePolygonRgn( pcPointArray, m_iNumPoints, ALTERNATE );
  92. delete [] pcPointArray;
  93. if (bRC) // offset for selection boundary
  94. m_pcRgnPolyBorder->OffsetRgn( -(m_cRectBounding.left * iZoom),
  95. -(m_cRectBounding.top * iZoom) );
  96. }
  97. if (! bRC)
  98. m_pcRgnPoly->DeleteObject();
  99. return bRC;
  100. }
  101. /******************************************************************************/
  102. BOOL CFreehandSelectTool::CreatePolyRegion( int iZoom, LPPOINT lpPoints, int iPoints )
  103. {
  104. if (! lpPoints || iPoints < 3)
  105. return FALSE;
  106. DeleteArrayContents();
  107. TRY {
  108. CPoint* pPt;
  109. for (int i = 0; i < iPoints; i++)
  110. {
  111. pPt = new CPoint( lpPoints[i] );
  112. m_cObArrayPoints.Add( (CObject *)pPt );
  113. }
  114. }
  115. CATCH( CMemoryException, e )
  116. {
  117. DeleteArrayContents();
  118. theApp.SetMemoryEmergency();
  119. return FALSE;
  120. }
  121. END_CATCH
  122. m_iNumPoints = iPoints;
  123. AdjustBoundingRect();
  124. rcPrev = m_cRectBounding;
  125. m_bMultPtOpInProgress = FALSE;
  126. theImgBrush.m_bMakingSelection = FALSE;
  127. theImgBrush.m_bMoveSel = FALSE;
  128. theImgBrush.m_bSmearSel = FALSE;
  129. if (! CreatePolyRegion( iZoom ))
  130. return FALSE;
  131. return TRUE;
  132. }
  133. /******************************************************************************/
  134. BOOL CFreehandSelectTool::ExpandPolyRegion( int iNewSizeX, int iNewSizeY )
  135. {
  136. CPoint* pcPointArray;
  137. int iNumPts;
  138. if (! CopyPointsToMemArray( &pcPointArray, &iNumPts ))
  139. return FALSE;
  140. int iWidth = m_cRectBounding.Width() + 1;
  141. int iHeight = m_cRectBounding.Height() + 1;
  142. int iDeltaX = ((iNewSizeX - iWidth ) * 10) / iWidth;
  143. int iDeltaY = ((iNewSizeY - iHeight) * 10) / iHeight;
  144. CPoint* pPtArray = pcPointArray;
  145. int iPts = iNumPts;
  146. while (iPts--)
  147. {
  148. pPtArray->x = (((pPtArray->x * 10) + (pPtArray->x * iDeltaX)) + 5) / 10;
  149. pPtArray->y = (((pPtArray->y * 10) + (pPtArray->y * iDeltaY)) + 5) / 10;
  150. pPtArray++;
  151. }
  152. BOOL bReturn = CreatePolyRegion( CImgWnd::GetCurrent()->GetZoom(),
  153. pcPointArray, iNumPts );
  154. delete [] pcPointArray;
  155. return bReturn;
  156. }
  157. /******************************************************************************/
  158. /* This routine is called before rendering onto the DC. It basically, calls */
  159. /* the default setup to setup the pen and brush, and then overrides the Pen if*/
  160. /* drawing in progress and drawing without any border. This case is necessary*/
  161. /* since if you do not have a border, you need to see something during the in */
  162. /* progress drawing mode. It uses the inverse (not) of the screen color as */
  163. /* the border in this mode. */
  164. BOOL CFreehandSelectTool::SetupPenBrush(HDC hDC, BOOL bLeftButton, BOOL bSetup, BOOL bCtrlDown)
  165. {
  166. static int iOldROP2Code;
  167. static BOOL bCurrentlySetup = FALSE;
  168. m_nStrokeWidth = 1; // override any changes
  169. BOOL bRC = CClosedFormTool::SetupPenBrush(hDC, bLeftButton, bSetup, bCtrlDown);
  170. // for multipt operations in progress (e.g. drawing outline, not fill yet
  171. // if there is no border, use the not of the screen color for the border.
  172. // When bMultiptopinprogress == FALSE, final drawing, we will use a null
  173. // pen and thus have no border.
  174. if (bSetup)
  175. {
  176. if (bCurrentlySetup)
  177. bRC = FALSE;
  178. else
  179. {
  180. bCurrentlySetup = TRUE;
  181. iOldROP2Code = SetROP2(hDC, R2_NOT);
  182. }
  183. }
  184. else
  185. {
  186. if (bCurrentlySetup)
  187. {
  188. bCurrentlySetup = FALSE;
  189. // if no border, restore drawing mode
  190. SetROP2(hDC, iOldROP2Code);
  191. }
  192. else
  193. // Error: Cannot Free/cleanup Brush/Pen -- Never allocated.
  194. bRC = FALSE;
  195. }
  196. return bRC;
  197. }
  198. /******************************************************************************/
  199. /* Call the line's adjustpointsforconstraint member function */
  200. void CFreehandSelectTool::AdjustPointsForConstraint(MTI *pmti)
  201. {
  202. CClosedFormTool::AdjustPointsForConstraint(pmti);
  203. }
  204. /******************************************************************************/
  205. // ptDown must be anchor point for our line, not where we did mouse button down
  206. void CFreehandSelectTool::PreProcessPoints(MTI *pmti)
  207. {
  208. CClosedFormTool::PreProcessPoints(pmti);
  209. }
  210. /***************************************************************************/
  211. void CFreehandSelectTool::OnPaintOptions ( CDC* pDC,
  212. const CRect& paintRect,
  213. const CRect& optionsRect )
  214. {
  215. g_selectTool.OnPaintOptions( pDC, paintRect, optionsRect );
  216. }
  217. /******************************************************************************/
  218. void CFreehandSelectTool::OnClickOptions ( CImgToolWnd* pWnd,
  219. const CRect& optionsRect,
  220. const CPoint& clickPoint )
  221. {
  222. g_selectTool.OnClickOptions(pWnd, optionsRect, clickPoint);
  223. }
  224. /******************************************************************************/
  225. void CFreehandSelectTool::OnStartDrag( CImgWnd* pImgWnd, MTI* pmti )
  226. {
  227. HideBrush();
  228. OnActivate( FALSE );
  229. // CommitSelection( TRUE );
  230. pImgWnd->EraseTracker();
  231. theImgBrush.m_bMakingSelection = TRUE;
  232. // simulate multipt op in progress, until button up or asked. This will
  233. // allow us to draw differently for duration and end.
  234. m_bMultPtOpInProgress = TRUE;
  235. DeleteArrayContents();
  236. CClosedFormTool::OnStartDrag( pImgWnd, pmti );
  237. }
  238. /******************************************************************************/
  239. void CFreehandSelectTool::OnEndDrag( CImgWnd* pImgWnd, MTI* pmti )
  240. {
  241. int iZoom = pImgWnd->GetZoom();
  242. theImgBrush.m_bMakingSelection = FALSE;
  243. theImgBrush.m_bMoveSel = theImgBrush.m_bSmearSel = FALSE;
  244. OnDrag(pImgWnd, pmti); // one last time to refresh display in prep for final render
  245. Render( CDC::FromHandle(pImgWnd->m_pImg->hDC), m_cRectBounding, pmti->fLeft, TRUE, pmti->fCtrlDown );
  246. m_iNumPoints = (int)m_cObArrayPoints.GetSize();
  247. if (m_iNumPoints > 2)
  248. if (! CreatePolyRegion( iZoom ))
  249. return;
  250. if (pmti->ptDown.x == pmti->pt.x
  251. && pmti->ptDown.y == pmti->pt.y)
  252. {
  253. if (m_iNumPoints > 3) // 3 is min points. If click down/up get 2
  254. {
  255. // must fool selectTool.OnEndDrag to think width of selection is
  256. // greater than 0. If 0, thinks selection is done/place it (i.e.
  257. // just clicked down/up. We only do this if the end point is the
  258. // same as the beginning point. This case will have width=height=0,
  259. // but number of points > 2
  260. pmti->pt.x++;
  261. pmti->pt.y++;
  262. }
  263. }
  264. pmti->ptDown = m_cRectBounding.TopLeft();
  265. pmti->pt = m_cRectBounding.BottomRight();
  266. g_selectTool.OnEndDrag(pImgWnd, pmti);
  267. }
  268. /******************************************************************************/
  269. void CFreehandSelectTool::OnDrag( CImgWnd* pImgWnd, MTI* pmti )
  270. {
  271. // Must set rcPrev to m_cRectBoundingRect prior to calling SetCurrentPoint
  272. // Since SetCurrentPoint will adjust m_cRectBounding, and we want the
  273. // previous bounding rect.
  274. rcPrev = m_cRectBounding;
  275. if (pmti->pt.x > pImgWnd->m_pImg->cxWidth)
  276. pmti->pt.x = pImgWnd->m_pImg->cxWidth;
  277. if (pmti->pt.y > pImgWnd->m_pImg->cyHeight)
  278. pmti->pt.y = pImgWnd->m_pImg->cyHeight;
  279. if (pmti->pt.x < 0)
  280. pmti->pt.x = 0;
  281. if (pmti->pt.y < 0)
  282. pmti->pt.y = 0;
  283. TRY {
  284. AddPoint(pmti->pt);
  285. }
  286. CATCH(CMemoryException,e)
  287. {
  288. theApp.SetMemoryEmergency();
  289. return;
  290. }
  291. END_CATCH
  292. CClosedFormTool::OnDrag(pImgWnd, pmti);
  293. }
  294. /******************************************************************************/
  295. void CFreehandSelectTool::OnCancel(CImgWnd* pImgWnd)
  296. {
  297. // We were not selecting or dragging, just cancel the select tool...
  298. CommitSelection( TRUE );
  299. //render one last time to turn off/invert the line if any drawn
  300. if (theImgBrush.m_bMakingSelection)
  301. {
  302. Render( CDC::FromHandle( pImgWnd->m_pImg->hDC ), m_cRectBounding,
  303. TRUE, TRUE, FALSE );
  304. }
  305. theImgBrush.TopLeftHandle();
  306. g_bCustomBrush = FALSE;
  307. theImgBrush.m_pImg = NULL;
  308. theImgBrush.m_bMoveSel = FALSE;
  309. theImgBrush.m_bSmearSel = FALSE;
  310. theImgBrush.m_bMakingSelection = FALSE;
  311. InvalImgRect( pImgWnd->m_pImg, NULL );
  312. DeleteArrayContents();
  313. CPolygonTool::OnCancel(pImgWnd);
  314. }
  315. /***************************************************************************/
  316. BOOL CFreehandSelectTool::IsToolModal(void)
  317. {
  318. if (theImgBrush.m_pImg)
  319. {
  320. return(TRUE);
  321. }
  322. return(CPolygonTool::IsToolModal());
  323. }
  324. /******************************************************************************/
  325. void CFreehandSelectTool::OnActivate(BOOL bActivate)
  326. {
  327. g_selectTool.OnActivate(bActivate);
  328. }
  329. /******************************************************************************/
  330. /* this class really isn't a multipt operation, but is derived from one thus */
  331. /* we can always end the multipt operation if anyone asks */
  332. BOOL CFreehandSelectTool::CanEndMultiptOperation(MTI* pmti )
  333. {
  334. m_bMultPtOpInProgress = FALSE;
  335. return (CClosedFormTool::CanEndMultiptOperation(pmti));
  336. }
  337. /******************************************************************************/
  338.