SelectedRect.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. using ComPDFKit.PDFAnnotation;
  2. using ComPDFKit.Tool.SettingParam;
  3. using ComPDFKit.Viewer.Layer;
  4. using ComPDFKitViewer;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.ComponentModel;
  8. using System.Diagnostics;
  9. using System.Linq;
  10. using System.Reflection;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows;
  14. using System.Windows.Controls;
  15. using System.Windows.Controls.Primitives;
  16. using System.Windows.Input;
  17. using System.Windows.Media;
  18. using System.Windows.Media.Media3D;
  19. using System.Xml.Linq;
  20. using static System.Net.Mime.MediaTypeNames;
  21. namespace ComPDFKit.Tool.DrawTool
  22. {
  23. public enum PointControlType
  24. {
  25. None = -1,
  26. LeftTop,
  27. LeftMiddle,
  28. LeftBottom,
  29. MiddlBottom,
  30. RightBottom,
  31. RightMiddle,
  32. RightTop,
  33. MiddleTop,
  34. Rotate,
  35. Body,
  36. Line
  37. }
  38. public enum SelectedType
  39. {
  40. None = -1,
  41. Annot,
  42. PDFEdit
  43. }
  44. public enum DrawPointType
  45. {
  46. Circle,
  47. Square,
  48. Crop
  49. }
  50. public enum DrawMoveType
  51. {
  52. kDefault,
  53. /// <summary>
  54. /// 移动画线
  55. /// </summary>
  56. kReferenceLine,
  57. }
  58. public class SelectedAnnotData
  59. {
  60. /// <summary>
  61. /// Current size of the rectangle
  62. /// </summary>
  63. public Rect Square { get; set; }
  64. /// <summary>
  65. /// Current points of the rectangle
  66. /// </summary>
  67. public PointCollection Points { get; set; }
  68. public AnnotData annotData { get; set; }
  69. public double Angle { get; set; }
  70. }
  71. public partial class SelectedRect : DrawingVisual
  72. {
  73. protected DefaultDrawParam DrawParam = new DefaultDrawParam();
  74. protected DrawingContext drawDC { get; set; }
  75. /// <summary>
  76. /// Data changing event
  77. /// </summary>
  78. public event EventHandler<SelectedAnnotData> DataChanging;
  79. /// <summary>
  80. /// Data changed event
  81. /// </summary>
  82. public event EventHandler<SelectedAnnotData> DataChanged;
  83. protected bool isHover = false;
  84. protected bool isSelected = false;
  85. protected SelectedType selectedType = SelectedType.None;
  86. public bool CanRotate { get; set; }
  87. private double angle = 0;
  88. private Point rotateCenter= new Point(0,0);
  89. private int rotateline = 25;
  90. public SelectedType GetSelectedType()
  91. {
  92. return selectedType;
  93. }
  94. public void SetIsHover(bool hover)
  95. {
  96. isHover = hover;
  97. }
  98. public bool GetIsHover()
  99. {
  100. return isHover;
  101. }
  102. public void SetIsSelected(bool selected)
  103. {
  104. isSelected = selected;
  105. }
  106. public bool GetIsSelected()
  107. {
  108. return isSelected;
  109. }
  110. public void SetCurrentDrawPointType(DrawPointType type)
  111. {
  112. currentDrawPointType = type;
  113. }
  114. public DrawPointType GetCurrentDrawPointType()
  115. {
  116. return currentDrawPointType;
  117. }
  118. public virtual void OnMouseLeftButtonDown(Point downPoint)
  119. {
  120. isMouseDown = true;
  121. hitControlType = PointControlType.None;
  122. mouseDownPoint = downPoint;
  123. moveOffset = new Point(0, 0);
  124. HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
  125. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  126. {
  127. hitControlType = GetHitControlIndex(downPoint);
  128. if (hitControlType != PointControlType.None)
  129. {
  130. cacheRect = drawRect;
  131. }
  132. rotateCenter = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
  133. }
  134. }
  135. public virtual void OnMouseLeftButtonUp(Point upPoint)
  136. {
  137. if (isMouseDown && hitControlType != PointControlType.None)
  138. {
  139. isMouseDown = false;
  140. cacheRect = SetDrawRect = drawRect;
  141. Draw();
  142. if ((int)upPoint.X != (int)mouseDownPoint.X || (int)upPoint.Y != (int)mouseDownPoint.Y)
  143. {
  144. InvokeDataChangEvent(true);
  145. }
  146. }
  147. moveOffset = new Point(0, 0);
  148. }
  149. public virtual void OnMouseMove(Point mousePoint, out bool Tag, double width, double height)
  150. {
  151. PDFViewerActualWidth = width;
  152. PDFViewerActualHeight = height;
  153. Tag = false;
  154. if (isMouseDown && hitControlType != PointControlType.None)
  155. {
  156. Tag = isMouseDown;
  157. if (CalcHitPointMove(mousePoint))
  158. {
  159. Draw();
  160. if ((int)mousePoint.X != (int)mouseDownPoint.X || (int)mousePoint.Y != (int)mouseDownPoint.Y)
  161. {
  162. InvokeDataChangEvent(false);
  163. }
  164. }
  165. }
  166. }
  167. public Cursor GetCursor(Point downPoint, Cursor cursor)
  168. {
  169. if (isMouseDown)
  170. {
  171. return cursor;
  172. }
  173. hitControlType = GetHitControlIndex(downPoint);
  174. switch (hitControlType)
  175. {
  176. case PointControlType.LeftTop:
  177. case PointControlType.RightBottom:
  178. return Cursors.SizeNWSE;
  179. case PointControlType.LeftMiddle:
  180. case PointControlType.RightMiddle:
  181. return Cursors.SizeWE;
  182. case PointControlType.LeftBottom:
  183. case PointControlType.RightTop:
  184. return Cursors.SizeNESW;
  185. case PointControlType.MiddlBottom:
  186. case PointControlType.MiddleTop:
  187. return Cursors.SizeNS;
  188. case PointControlType.Body:
  189. return Cursors.Arrow;
  190. case PointControlType.Line:
  191. return Cursors.SizeAll;
  192. case PointControlType.Rotate:
  193. return Cursors.Arrow;
  194. default:
  195. return Cursors.Arrow;
  196. }
  197. }
  198. public SelectedRect(DefaultDrawParam defaultDrawParam, SelectedType type) : base()
  199. {
  200. DrawParam = defaultDrawParam;
  201. currentDrawPointType = DrawPointType.Square;
  202. selectedType = type;
  203. }
  204. private void DrawNormal(DrawingContext drawDC)
  205. {
  206. Rect currentRect = SetDrawRect;
  207. switch (currentDrawMoveType)
  208. {
  209. case DrawMoveType.kDefault:
  210. currentRect = drawRect;
  211. CalcControlPoint(currentRect);
  212. break;
  213. case DrawMoveType.kReferenceLine:
  214. CalcControlPoint(currentRect);
  215. if (isMouseDown == true)
  216. {
  217. SolidColorBrush moveBrush = DrawParam.AnnotMoveBrush;
  218. Pen movepen = DrawParam.AnnotMovePen;
  219. GetMoveBrushAndPen(ref moveBrush, ref movepen);
  220. DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect);
  221. }
  222. break;
  223. default:
  224. break;
  225. }
  226. SolidColorBrush solidColorBrush = DrawParam.AnnotRectFillBrush;
  227. Pen pen = DrawParam.AnnotRectLinePen;
  228. GetBrushAndPen(ref solidColorBrush, ref pen);
  229. drawDC?.DrawRectangle(solidColorBrush, pen, currentRect);
  230. SolidColorBrush PointBrush = DrawParam.AnnotPointBorderBrush;
  231. Pen PointPen = DrawParam.AnnotPointPen;
  232. GetPointBrushAndPen(ref PointBrush, ref PointPen);
  233. switch (currentDrawPointType)
  234. {
  235. case DrawPointType.Circle:
  236. DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  237. break;
  238. case DrawPointType.Square:
  239. DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  240. break;
  241. case DrawPointType.Crop:
  242. DrawCropPoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  243. break;
  244. }
  245. }
  246. private void PushRotate(DrawingContext drawDC)
  247. {
  248. if (CanRotate)
  249. {
  250. RotateTransform transform = new RotateTransform();
  251. transform.Angle = angle;
  252. if(hitControlType==PointControlType.Body || hitControlType==PointControlType.Line)
  253. {
  254. rotateCenter.X = drawRect.Left + drawRect.Width / 2;
  255. rotateCenter.Y = drawRect.Top + drawRect.Height / 2;
  256. }
  257. transform.CenterX = rotateCenter.X;
  258. transform.CenterY = rotateCenter.Y;
  259. drawDC.PushTransform(transform);
  260. }
  261. }
  262. private void PopRotate(DrawingContext drawDC)
  263. {
  264. if (CanRotate)
  265. {
  266. drawDC.Pop();
  267. }
  268. }
  269. private void DrawRotate(DrawingContext drawDC)
  270. {
  271. double centerX = drawRect.Left + drawRect.Width / 2;
  272. double centerY = drawRect.Top + drawRect.Height / 2;
  273. Pen PointPen = DrawParam.AnnotPointPen;
  274. drawDC.DrawLine(PointPen, new Point(centerX, drawRect.Top), new Point(centerX, drawRect.Top - rotateline));
  275. drawDC.DrawEllipse(PointPen.Brush, PointPen, new Point(centerX, drawRect.Top - rotateline), pointSize * 2, pointSize * 2);
  276. }
  277. public void Draw()
  278. {
  279. Dispatcher.Invoke(() =>
  280. {
  281. Rect currentRect = SetDrawRect;
  282. drawDC = RenderOpen();
  283. PushRotate(drawDC);
  284. DrawRotate(drawDC);
  285. DrawNormal(drawDC);
  286. PopRotate(drawDC);
  287. drawDC?.Close();
  288. drawDC = null;
  289. });
  290. }
  291. private void GetMoveBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  292. {
  293. switch (selectedType)
  294. {
  295. case SelectedType.None:
  296. break;
  297. case SelectedType.Annot:
  298. colorBrush = DrawParam.AnnotMoveBrush;
  299. pen = DrawParam.AnnotMovePen;
  300. break;
  301. case SelectedType.PDFEdit:
  302. colorBrush = DrawParam.PDFEditMoveBrush;
  303. pen = DrawParam.PDFEditMovePen;
  304. break;
  305. default:
  306. break;
  307. }
  308. }
  309. private void GetPointBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  310. {
  311. switch (selectedType)
  312. {
  313. case SelectedType.None:
  314. break;
  315. case SelectedType.Annot:
  316. colorBrush = DrawParam.AnnotPointBorderBrush;
  317. pen = DrawParam.AnnotPointPen;
  318. break;
  319. case SelectedType.PDFEdit:
  320. if (isHover)
  321. {
  322. colorBrush = DrawParam.PDFEditRectFillHoverBrush;
  323. pen = DrawParam.PDFEditPointHoverPen;
  324. }
  325. else if (currentDrawPointType == DrawPointType.Crop)
  326. {
  327. colorBrush = DrawParam.SPDFEditCropBorderBrush;//new SolidColorBrush((DrawParam.SPDFEditPointPen.Brush as SolidColorBrush).Color);
  328. pen = DrawParam.SPDFEditPointPen.Clone();
  329. pen.DashStyle = DashStyles.Solid;
  330. }
  331. else
  332. {
  333. if (isSelected)
  334. {
  335. colorBrush = DrawParam.SPDFEditPointBorderBrush;
  336. pen = DrawParam.SPDFEditPointPen;
  337. }
  338. else
  339. {
  340. colorBrush = DrawParam.PDFEditPointBorderBrush;
  341. pen = DrawParam.PDFEditPointPen;
  342. }
  343. }
  344. break;
  345. default:
  346. break;
  347. }
  348. }
  349. private void GetBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  350. {
  351. switch (selectedType)
  352. {
  353. case SelectedType.None:
  354. break;
  355. case SelectedType.Annot:
  356. if (isHover)
  357. {
  358. colorBrush = DrawParam.AnnotRectFillBrush;
  359. pen = DrawParam.AnnotRectHoverPen;
  360. }
  361. else
  362. {
  363. colorBrush = DrawParam.AnnotRectFillBrush;
  364. pen = DrawParam.AnnotRectLinePen;
  365. }
  366. break;
  367. case SelectedType.PDFEdit:
  368. if (isHover)
  369. {
  370. colorBrush = DrawParam.PDFEditRectFillHoverBrush;
  371. pen = DrawParam.PDFEditRectLineHoverPen;
  372. }
  373. else
  374. {
  375. if (isSelected)
  376. {
  377. colorBrush = DrawParam.SPDFEditRectFillBrush;
  378. pen = DrawParam.SPDFEditRectLinePen;
  379. }
  380. else
  381. {
  382. colorBrush = DrawParam.PDFEditRectFillBrush;
  383. pen = DrawParam.PDFEditRectLinePen;
  384. }
  385. }
  386. break;
  387. default:
  388. break;
  389. }
  390. }
  391. public virtual void ClearDraw()
  392. {
  393. SetDrawRect = drawRect = new Rect();
  394. drawDC = RenderOpen();
  395. drawDC?.Close();
  396. drawDC = null;
  397. }
  398. /// <summary>
  399. /// Hide the drawing
  400. /// </summary>
  401. public virtual void HideDraw()
  402. {
  403. drawDC = RenderOpen();
  404. drawDC?.Close();
  405. }
  406. public void SetRect(Rect newRect,double zoom)
  407. {
  408. if(newRect == Rect.Empty || newRect == null)
  409. {
  410. return;
  411. }
  412. newRect = new Rect((int)(newRect.X - rectPadding* zoom), (int)(newRect.Y - rectPadding* zoom),(int)( newRect.Width + 2 * rectPadding* zoom), (int)(newRect.Height + 2 * rectPadding* zoom));
  413. currentZoom = zoom;
  414. SetDrawRect = drawRect = newRect;
  415. drawCenterPoint = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
  416. }
  417. /// <summary>
  418. /// Get the original set Rect, not the calculated fill
  419. /// </summary>
  420. /// <param name="newRect">
  421. /// The new rect to set
  422. /// </param>
  423. public Rect GetRect()
  424. {
  425. Rect rect = new Rect(drawRect.X + rectPadding * currentZoom, drawRect.Y + rectPadding * currentZoom, Math.Max(rectMinWidth, drawRect.Width - 2 * rectPadding * currentZoom), Math.Max(RectMinHeight, drawRect.Height - 2 * rectPadding * currentZoom));
  426. return rect;
  427. }
  428. public void SetRectPadding(double rectPadding)
  429. {
  430. this.rectPadding = rectPadding;
  431. }
  432. public double GetRectPadding()
  433. {
  434. return rectPadding;
  435. }
  436. public Rect GetDrawRect()
  437. {
  438. return drawRect;
  439. }
  440. public void SetMaxRect(Rect rect)
  441. {
  442. maxRect = rect;
  443. }
  444. public Rect GetMaxRect()
  445. {
  446. return maxRect;
  447. }
  448. public void SetAnnotData(AnnotData annotData)
  449. {
  450. SetIgnorePoints(new List<PointControlType>());
  451. SetIsProportionalScaling(false);
  452. isProportionalScaling = false;
  453. switch (annotData.AnnotType)
  454. {
  455. case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
  456. case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
  457. case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
  458. case C_ANNOTATION_TYPE.C_ANNOTATION_STRIKEOUT:
  459. case C_ANNOTATION_TYPE.C_ANNOTATION_RICHMEDIA:
  460. case C_ANNOTATION_TYPE.C_ANNOTATION_MOVIE:
  461. case C_ANNOTATION_TYPE.C_ANNOTATION_REDACT:
  462. DisableAll();
  463. break;
  464. case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
  465. case C_ANNOTATION_TYPE.C_ANNOTATION_SOUND:
  466. SetIgnorePointsAll();
  467. break;
  468. case C_ANNOTATION_TYPE.C_ANNOTATION_STAMP:
  469. SetIsProportionalScaling(true);
  470. break;
  471. case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
  472. SetIgnorePointsAll();
  473. break;
  474. default:
  475. break;
  476. }
  477. SetMaxRect(annotData.PaintOffset);
  478. SetRect(annotData.PaintRect, annotData.CurrentZoom);
  479. selectedRectData = new SelectedAnnotData();
  480. selectedRectData.annotData = annotData;
  481. }
  482. public void SetIsProportionalScaling(bool isProportionalScaling)
  483. {
  484. this.isProportionalScaling = isProportionalScaling;
  485. ignorePoints.Clear();
  486. if (isProportionalScaling)
  487. {
  488. ignorePoints.Add(PointControlType.LeftMiddle);
  489. ignorePoints.Add(PointControlType.MiddlBottom);
  490. ignorePoints.Add(PointControlType.RightMiddle);
  491. ignorePoints.Add(PointControlType.MiddleTop);
  492. ignorePoints.Add(PointControlType.Rotate);
  493. }
  494. }
  495. public void SetDrawType(DrawPointType drawType)
  496. {
  497. currentDrawPointType = drawType;
  498. }
  499. public void SetDrawMoveType(DrawMoveType drawType)
  500. {
  501. currentDrawMoveType = drawType;
  502. }
  503. /// <summary>
  504. /// Set the types that need to be ignored
  505. /// </summary>
  506. /// <param name="types">
  507. /// The collection of point types that need to be ignored
  508. /// </param>
  509. public void SetIgnorePoints(List<PointControlType> types)
  510. {
  511. ignorePoints.Clear();
  512. foreach (PointControlType type in types)
  513. {
  514. ignorePoints.Add(type);
  515. }
  516. }
  517. /// <summary>
  518. /// Ignore all points
  519. /// </summary>
  520. public void SetIgnorePointsAll()
  521. {
  522. ignorePoints.Clear();
  523. ignorePoints.Add(PointControlType.LeftTop);
  524. ignorePoints.Add(PointControlType.LeftMiddle);
  525. ignorePoints.Add(PointControlType.LeftBottom);
  526. ignorePoints.Add(PointControlType.MiddlBottom);
  527. ignorePoints.Add(PointControlType.RightBottom);
  528. ignorePoints.Add(PointControlType.RightMiddle);
  529. ignorePoints.Add(PointControlType.RightTop);
  530. ignorePoints.Add(PointControlType.MiddleTop);
  531. }
  532. /// <summary>
  533. /// Disable all functions
  534. /// </summary>
  535. public void DisableAll()
  536. {
  537. ignorePoints.Clear();
  538. ignorePoints.Add(PointControlType.LeftTop);
  539. ignorePoints.Add(PointControlType.LeftMiddle);
  540. ignorePoints.Add(PointControlType.LeftBottom);
  541. ignorePoints.Add(PointControlType.MiddlBottom);
  542. ignorePoints.Add(PointControlType.RightBottom);
  543. ignorePoints.Add(PointControlType.RightMiddle);
  544. ignorePoints.Add(PointControlType.RightTop);
  545. ignorePoints.Add(PointControlType.MiddleTop);
  546. ignorePoints.Add(PointControlType.Rotate);
  547. ignorePoints.Add(PointControlType.Body);
  548. ignorePoints.Add(PointControlType.Line);
  549. }
  550. /// <summary>
  551. /// Set the left alignment in the set maximum rectangle
  552. /// </summary>
  553. public virtual void SetAlignLeftForMaxRect()
  554. {
  555. DrawAlignRect(AlignmentsHelp.SetAlignLeft(drawRect, maxRect));
  556. }
  557. /// <summary>
  558. /// Set horizontal center alignment in the set maximum rectangle
  559. /// </summary>
  560. public virtual void SetAlignHorizonCenterForMaxRect()
  561. {
  562. DrawAlignRect(AlignmentsHelp.SetAlignHorizonCenter(drawRect, maxRect));
  563. }
  564. /// <summary>
  565. /// Set horizontal right alignment in the set maximum rectangle
  566. /// </summary>
  567. public virtual void SetAlignRightForMaxRect()
  568. {
  569. DrawAlignRect(AlignmentsHelp.SetAlignRight(drawRect, maxRect));
  570. }
  571. /// <summary>
  572. /// Set the top alignment in the set maximum rectangle
  573. /// </summary>
  574. public virtual void SetAlignTopForMaxRect()
  575. {
  576. DrawAlignRect(AlignmentsHelp.SetAlignTop(drawRect, maxRect));
  577. }
  578. /// <summary>
  579. /// Set vertical center alignment in the set maximum rectangle
  580. /// </summary>
  581. public virtual void SetAlignVerticalCenterForMaxRect()
  582. {
  583. DrawAlignRect(AlignmentsHelp.SetAlignVerticalCenter(drawRect, maxRect));
  584. }
  585. /// <summary>
  586. /// Set vertical center alignment in the set maximum rectangle
  587. /// </summary>
  588. public virtual void SetAlignHorizonVerticalCenterForMaxRect()
  589. {
  590. DrawAlignRect(AlignmentsHelp.SetAlignHorizonVerticalCenter(drawRect, maxRect));
  591. }
  592. /// <summary>
  593. /// Set the bottom alignment in the set maximum rectangle
  594. /// </summary>
  595. public virtual void SetAlignBottomForMaxRect()
  596. {
  597. DrawAlignRect(AlignmentsHelp.SetAlignBottom(drawRect, maxRect));
  598. }
  599. /// <summary>
  600. /// Get which control point the coordinate is on
  601. /// </summary>
  602. /// <param name="clickPoint">
  603. /// The point to check
  604. /// </param>
  605. /// <returns>
  606. /// The control point type
  607. /// </returns>
  608. public PointControlType GetHitControlIndex(Point point, bool isIgnore = true)
  609. {
  610. if (CanRotate)
  611. {
  612. return GetRotateHitIndex(point,isIgnore);
  613. }
  614. return GetNormalHitIndex(point, isIgnore);
  615. }
  616. private PointControlType GetNormalHitIndex(Point point, bool isIgnore = true)
  617. {
  618. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  619. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  620. {
  621. List<PointControlType> ignoreList = GetIgnorePoints();
  622. List<Point> IgnorePointsList = new List<Point>();
  623. foreach (PointControlType type in ignoreList)
  624. {
  625. if ((int)type < controlPoints.Count)
  626. {
  627. IgnorePointsList.Add(controlPoints[(int)type]);
  628. }
  629. }
  630. for (int i = 0; i < controlPoints.Count; i++)
  631. {
  632. Point checkPoint = controlPoints[i];
  633. if (isIgnore && IgnorePointsList.Contains(checkPoint))
  634. {
  635. continue;
  636. }
  637. switch (currentDrawPointType)
  638. {
  639. case DrawPointType.Circle:
  640. Vector checkVector = checkPoint - point;
  641. if (checkVector.Length < pointSize)
  642. {
  643. return (PointControlType)i;
  644. }
  645. break;
  646. case DrawPointType.Square:
  647. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  648. if (checkRect.Contains(point))
  649. {
  650. return (PointControlType)i;
  651. }
  652. break;
  653. case DrawPointType.Crop:
  654. Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  655. if (cropRect.Contains(point))
  656. {
  657. return (PointControlType)i;
  658. }
  659. break;
  660. default:
  661. break;
  662. }
  663. }
  664. if (drawRect.Contains(point))
  665. {
  666. double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
  667. double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
  668. Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
  669. if (rect.Contains(point))
  670. {
  671. if (!ignoreList.Contains(PointControlType.Body))
  672. {
  673. return PointControlType.Body;
  674. }
  675. }
  676. if (!ignoreList.Contains(PointControlType.Body))
  677. {
  678. return PointControlType.Line;
  679. }
  680. }
  681. }
  682. return PointControlType.None;
  683. }
  684. private PointControlType GetRotateHitIndex(Point point, bool isIgnore = true)
  685. {
  686. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  687. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  688. {
  689. //旋转回去
  690. Point centerPoint = rotateCenter;
  691. Vector currentVector = point - centerPoint;
  692. Matrix matrix = new Matrix();
  693. matrix.Rotate(-angle);
  694. Vector transVector = matrix.Transform(currentVector);
  695. Point checkPos = new Point(centerPoint.X + transVector.X, centerPoint.Y + transVector.Y);
  696. point= checkPos;
  697. List<PointControlType> ignoreList = GetIgnorePoints();
  698. List<Point> IgnorePointsList = new List<Point>();
  699. foreach (PointControlType type in ignoreList)
  700. {
  701. if ((int)type < controlPoints.Count)
  702. {
  703. IgnorePointsList.Add(controlPoints[(int)type]);
  704. }
  705. }
  706. for (int i = 0; i < controlPoints.Count; i++)
  707. {
  708. Point checkPoint = controlPoints[i];
  709. if (isIgnore && IgnorePointsList.Contains(checkPoint))
  710. {
  711. continue;
  712. }
  713. switch (currentDrawPointType)
  714. {
  715. case DrawPointType.Circle:
  716. Vector checkCircle = checkPoint - point;
  717. if (checkCircle.Length < pointSize)
  718. {
  719. return (PointControlType)i;
  720. }
  721. break;
  722. case DrawPointType.Square:
  723. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  724. if (checkRect.Contains(point))
  725. {
  726. return (PointControlType)i;
  727. }
  728. break;
  729. case DrawPointType.Crop:
  730. Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  731. if (cropRect.Contains(point))
  732. {
  733. return (PointControlType)i;
  734. }
  735. break;
  736. default:
  737. break;
  738. }
  739. }
  740. if (drawRect.Contains(point))
  741. {
  742. double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
  743. double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
  744. Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
  745. if (rect.Contains(point))
  746. {
  747. if (!ignoreList.Contains(PointControlType.Body))
  748. {
  749. return PointControlType.Body;
  750. }
  751. }
  752. if (!ignoreList.Contains(PointControlType.Body))
  753. {
  754. return PointControlType.Line;
  755. }
  756. }
  757. double centerX = drawRect.Left + drawRect.Width / 2;
  758. double centerY = drawRect.Top + drawRect.Height / 2;
  759. Point rotatePoint = new Point(centerX, drawRect.Top - rotateline);
  760. Vector checkVector = point - rotatePoint;
  761. if (checkVector.Length <= pointSize * 2)
  762. {
  763. return PointControlType.Rotate;
  764. }
  765. }
  766. return PointControlType.None;
  767. }
  768. }
  769. }