SelectedRect.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  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. if (CanRotate)
  272. {
  273. double centerX = drawRect.Left + drawRect.Width / 2;
  274. double centerY = drawRect.Top + drawRect.Height / 2;
  275. Pen PointPen = DrawParam.AnnotPointPen;
  276. drawDC.DrawLine(PointPen, new Point(centerX, drawRect.Top), new Point(centerX, drawRect.Top - rotateline));
  277. drawDC.DrawEllipse(PointPen.Brush, PointPen, new Point(centerX, drawRect.Top - rotateline), RotateSize, RotateSize);
  278. }
  279. }
  280. public void Draw()
  281. {
  282. Dispatcher.Invoke(() =>
  283. {
  284. Rect currentRect = SetDrawRect;
  285. drawDC = RenderOpen();
  286. PushRotate(drawDC);
  287. DrawRotate(drawDC);
  288. DrawNormal(drawDC);
  289. PopRotate(drawDC);
  290. drawDC?.Close();
  291. drawDC = null;
  292. });
  293. }
  294. private void GetMoveBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  295. {
  296. switch (selectedType)
  297. {
  298. case SelectedType.None:
  299. break;
  300. case SelectedType.Annot:
  301. colorBrush = DrawParam.AnnotMoveBrush;
  302. pen = DrawParam.AnnotMovePen;
  303. break;
  304. case SelectedType.PDFEdit:
  305. colorBrush = DrawParam.PDFEditMoveBrush;
  306. pen = DrawParam.PDFEditMovePen;
  307. break;
  308. default:
  309. break;
  310. }
  311. }
  312. private void GetPointBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  313. {
  314. switch (selectedType)
  315. {
  316. case SelectedType.None:
  317. break;
  318. case SelectedType.Annot:
  319. colorBrush = DrawParam.AnnotPointBorderBrush;
  320. pen = DrawParam.AnnotPointPen;
  321. break;
  322. case SelectedType.PDFEdit:
  323. if (isHover)
  324. {
  325. colorBrush = DrawParam.PDFEditRectFillHoverBrush;
  326. pen = DrawParam.PDFEditPointHoverPen;
  327. }
  328. else if (currentDrawPointType == DrawPointType.Crop)
  329. {
  330. colorBrush = DrawParam.SPDFEditCropBorderBrush;//new SolidColorBrush((DrawParam.SPDFEditPointPen.Brush as SolidColorBrush).Color);
  331. pen = DrawParam.SPDFEditPointPen.Clone();
  332. pen.DashStyle = DashStyles.Solid;
  333. }
  334. else
  335. {
  336. if (isSelected)
  337. {
  338. colorBrush = DrawParam.SPDFEditPointBorderBrush;
  339. pen = DrawParam.SPDFEditPointPen;
  340. }
  341. else
  342. {
  343. colorBrush = DrawParam.PDFEditPointBorderBrush;
  344. pen = DrawParam.PDFEditPointPen;
  345. }
  346. }
  347. break;
  348. default:
  349. break;
  350. }
  351. }
  352. private void GetBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  353. {
  354. switch (selectedType)
  355. {
  356. case SelectedType.None:
  357. break;
  358. case SelectedType.Annot:
  359. if (isHover)
  360. {
  361. colorBrush = DrawParam.AnnotRectFillBrush;
  362. pen = DrawParam.AnnotRectHoverPen;
  363. }
  364. else
  365. {
  366. colorBrush = DrawParam.AnnotRectFillBrush;
  367. pen = DrawParam.AnnotRectLinePen;
  368. }
  369. break;
  370. case SelectedType.PDFEdit:
  371. if (isHover)
  372. {
  373. colorBrush = DrawParam.PDFEditRectFillHoverBrush;
  374. pen = DrawParam.PDFEditRectLineHoverPen;
  375. }
  376. else
  377. {
  378. if (isSelected)
  379. {
  380. colorBrush = DrawParam.SPDFEditRectFillBrush;
  381. pen = DrawParam.SPDFEditRectLinePen;
  382. }
  383. else
  384. {
  385. colorBrush = DrawParam.PDFEditRectFillBrush;
  386. pen = DrawParam.PDFEditRectLinePen;
  387. }
  388. }
  389. break;
  390. default:
  391. break;
  392. }
  393. }
  394. public virtual void ClearDraw()
  395. {
  396. SetDrawRect = drawRect = new Rect();
  397. drawDC = RenderOpen();
  398. drawDC?.Close();
  399. drawDC = null;
  400. }
  401. /// <summary>
  402. /// Hide the drawing
  403. /// </summary>
  404. public virtual void HideDraw()
  405. {
  406. drawDC = RenderOpen();
  407. drawDC?.Close();
  408. }
  409. public void SetRect(Rect newRect,double zoom)
  410. {
  411. if(newRect == Rect.Empty || newRect == null)
  412. {
  413. return;
  414. }
  415. 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));
  416. currentZoom = zoom;
  417. SetDrawRect = drawRect = newRect;
  418. drawCenterPoint = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
  419. }
  420. /// <summary>
  421. /// Get the original set Rect, not the calculated fill
  422. /// </summary>
  423. /// <param name="newRect">
  424. /// The new rect to set
  425. /// </param>
  426. public Rect GetRect()
  427. {
  428. 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));
  429. return rect;
  430. }
  431. public void SetRectPadding(double rectPadding)
  432. {
  433. this.rectPadding = rectPadding;
  434. }
  435. public double GetRectPadding()
  436. {
  437. return rectPadding;
  438. }
  439. public Rect GetDrawRect()
  440. {
  441. return drawRect;
  442. }
  443. public void SetMaxRect(Rect rect)
  444. {
  445. maxRect = rect;
  446. }
  447. public Rect GetMaxRect()
  448. {
  449. return maxRect;
  450. }
  451. public void SetAnnotData(AnnotData annotData)
  452. {
  453. SetIgnorePoints(new List<PointControlType>());
  454. SetIsProportionalScaling(false);
  455. isProportionalScaling = false;
  456. switch (annotData.AnnotType)
  457. {
  458. case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
  459. case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
  460. case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
  461. case C_ANNOTATION_TYPE.C_ANNOTATION_STRIKEOUT:
  462. case C_ANNOTATION_TYPE.C_ANNOTATION_RICHMEDIA:
  463. case C_ANNOTATION_TYPE.C_ANNOTATION_MOVIE:
  464. case C_ANNOTATION_TYPE.C_ANNOTATION_REDACT:
  465. DisableAll();
  466. break;
  467. case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
  468. case C_ANNOTATION_TYPE.C_ANNOTATION_SOUND:
  469. SetIgnorePointsAll();
  470. break;
  471. case C_ANNOTATION_TYPE.C_ANNOTATION_STAMP:
  472. SetIsProportionalScaling(true);
  473. break;
  474. case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
  475. SetIgnorePointsAll();
  476. break;
  477. default:
  478. break;
  479. }
  480. SetMaxRect(annotData.PaintOffset);
  481. SetRect(annotData.PaintRect, annotData.CurrentZoom);
  482. selectedRectData = new SelectedAnnotData();
  483. selectedRectData.annotData = annotData;
  484. }
  485. public void SetIsProportionalScaling(bool isProportionalScaling)
  486. {
  487. this.isProportionalScaling = isProportionalScaling;
  488. ignorePoints.Clear();
  489. if (isProportionalScaling)
  490. {
  491. ignorePoints.Add(PointControlType.LeftMiddle);
  492. ignorePoints.Add(PointControlType.MiddlBottom);
  493. ignorePoints.Add(PointControlType.RightMiddle);
  494. ignorePoints.Add(PointControlType.MiddleTop);
  495. ignorePoints.Add(PointControlType.Rotate);
  496. }
  497. }
  498. public void SetDrawType(DrawPointType drawType)
  499. {
  500. currentDrawPointType = drawType;
  501. }
  502. public void SetDrawMoveType(DrawMoveType drawType)
  503. {
  504. currentDrawMoveType = drawType;
  505. }
  506. /// <summary>
  507. /// Set the types that need to be ignored
  508. /// </summary>
  509. /// <param name="types">
  510. /// The collection of point types that need to be ignored
  511. /// </param>
  512. public void SetIgnorePoints(List<PointControlType> types)
  513. {
  514. ignorePoints.Clear();
  515. foreach (PointControlType type in types)
  516. {
  517. ignorePoints.Add(type);
  518. }
  519. }
  520. /// <summary>
  521. /// Ignore all points
  522. /// </summary>
  523. public void SetIgnorePointsAll()
  524. {
  525. ignorePoints.Clear();
  526. ignorePoints.Add(PointControlType.LeftTop);
  527. ignorePoints.Add(PointControlType.LeftMiddle);
  528. ignorePoints.Add(PointControlType.LeftBottom);
  529. ignorePoints.Add(PointControlType.MiddlBottom);
  530. ignorePoints.Add(PointControlType.RightBottom);
  531. ignorePoints.Add(PointControlType.RightMiddle);
  532. ignorePoints.Add(PointControlType.RightTop);
  533. ignorePoints.Add(PointControlType.MiddleTop);
  534. }
  535. /// <summary>
  536. /// Disable all functions
  537. /// </summary>
  538. public void DisableAll()
  539. {
  540. ignorePoints.Clear();
  541. ignorePoints.Add(PointControlType.LeftTop);
  542. ignorePoints.Add(PointControlType.LeftMiddle);
  543. ignorePoints.Add(PointControlType.LeftBottom);
  544. ignorePoints.Add(PointControlType.MiddlBottom);
  545. ignorePoints.Add(PointControlType.RightBottom);
  546. ignorePoints.Add(PointControlType.RightMiddle);
  547. ignorePoints.Add(PointControlType.RightTop);
  548. ignorePoints.Add(PointControlType.MiddleTop);
  549. ignorePoints.Add(PointControlType.Rotate);
  550. ignorePoints.Add(PointControlType.Body);
  551. ignorePoints.Add(PointControlType.Line);
  552. }
  553. /// <summary>
  554. /// Set the left alignment in the set maximum rectangle
  555. /// </summary>
  556. public virtual void SetAlignLeftForMaxRect()
  557. {
  558. DrawAlignRect(AlignmentsHelp.SetAlignLeft(drawRect, maxRect));
  559. }
  560. /// <summary>
  561. /// Set horizontal center alignment in the set maximum rectangle
  562. /// </summary>
  563. public virtual void SetAlignHorizonCenterForMaxRect()
  564. {
  565. DrawAlignRect(AlignmentsHelp.SetAlignHorizonCenter(drawRect, maxRect));
  566. }
  567. /// <summary>
  568. /// Set horizontal right alignment in the set maximum rectangle
  569. /// </summary>
  570. public virtual void SetAlignRightForMaxRect()
  571. {
  572. DrawAlignRect(AlignmentsHelp.SetAlignRight(drawRect, maxRect));
  573. }
  574. /// <summary>
  575. /// Set the top alignment in the set maximum rectangle
  576. /// </summary>
  577. public virtual void SetAlignTopForMaxRect()
  578. {
  579. DrawAlignRect(AlignmentsHelp.SetAlignTop(drawRect, maxRect));
  580. }
  581. /// <summary>
  582. /// Set vertical center alignment in the set maximum rectangle
  583. /// </summary>
  584. public virtual void SetAlignVerticalCenterForMaxRect()
  585. {
  586. DrawAlignRect(AlignmentsHelp.SetAlignVerticalCenter(drawRect, maxRect));
  587. }
  588. /// <summary>
  589. /// Set vertical center alignment in the set maximum rectangle
  590. /// </summary>
  591. public virtual void SetAlignHorizonVerticalCenterForMaxRect()
  592. {
  593. DrawAlignRect(AlignmentsHelp.SetAlignHorizonVerticalCenter(drawRect, maxRect));
  594. }
  595. /// <summary>
  596. /// Set the bottom alignment in the set maximum rectangle
  597. /// </summary>
  598. public virtual void SetAlignBottomForMaxRect()
  599. {
  600. DrawAlignRect(AlignmentsHelp.SetAlignBottom(drawRect, maxRect));
  601. }
  602. /// <summary>
  603. /// Get which control point the coordinate is on
  604. /// </summary>
  605. /// <param name="clickPoint">
  606. /// The point to check
  607. /// </param>
  608. /// <returns>
  609. /// The control point type
  610. /// </returns>
  611. public PointControlType GetHitControlIndex(Point point, bool isIgnore = true)
  612. {
  613. if (CanRotate)
  614. {
  615. return GetRotateHitIndex(point,isIgnore);
  616. }
  617. return GetNormalHitIndex(point, isIgnore);
  618. }
  619. private PointControlType GetNormalHitIndex(Point point, bool isIgnore = true)
  620. {
  621. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  622. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  623. {
  624. List<PointControlType> ignoreList = GetIgnorePoints();
  625. List<Point> IgnorePointsList = new List<Point>();
  626. foreach (PointControlType type in ignoreList)
  627. {
  628. if ((int)type < controlPoints.Count)
  629. {
  630. IgnorePointsList.Add(controlPoints[(int)type]);
  631. }
  632. }
  633. for (int i = 0; i < controlPoints.Count; i++)
  634. {
  635. Point checkPoint = controlPoints[i];
  636. if (isIgnore && IgnorePointsList.Contains(checkPoint))
  637. {
  638. continue;
  639. }
  640. switch (currentDrawPointType)
  641. {
  642. case DrawPointType.Circle:
  643. Vector checkVector = checkPoint - point;
  644. if (checkVector.Length < pointSize)
  645. {
  646. return (PointControlType)i;
  647. }
  648. break;
  649. case DrawPointType.Square:
  650. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  651. if (checkRect.Contains(point))
  652. {
  653. return (PointControlType)i;
  654. }
  655. break;
  656. case DrawPointType.Crop:
  657. Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  658. if (cropRect.Contains(point))
  659. {
  660. return (PointControlType)i;
  661. }
  662. break;
  663. default:
  664. break;
  665. }
  666. }
  667. if (drawRect.Contains(point))
  668. {
  669. double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
  670. double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
  671. Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
  672. if (rect.Contains(point))
  673. {
  674. if (!ignoreList.Contains(PointControlType.Body))
  675. {
  676. return PointControlType.Body;
  677. }
  678. }
  679. if (!ignoreList.Contains(PointControlType.Body))
  680. {
  681. return PointControlType.Line;
  682. }
  683. }
  684. }
  685. return PointControlType.None;
  686. }
  687. private PointControlType GetRotateHitIndex(Point point, bool isIgnore = true)
  688. {
  689. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  690. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  691. {
  692. //旋转回去
  693. Point centerPoint = rotateCenter;
  694. Vector currentVector = point - centerPoint;
  695. Matrix matrix = new Matrix();
  696. matrix.Rotate(-angle);
  697. Vector transVector = matrix.Transform(currentVector);
  698. Point checkPos = new Point(centerPoint.X + transVector.X, centerPoint.Y + transVector.Y);
  699. point= checkPos;
  700. List<PointControlType> ignoreList = GetIgnorePoints();
  701. List<Point> IgnorePointsList = new List<Point>();
  702. foreach (PointControlType type in ignoreList)
  703. {
  704. if ((int)type < controlPoints.Count)
  705. {
  706. IgnorePointsList.Add(controlPoints[(int)type]);
  707. }
  708. }
  709. for (int i = 0; i < controlPoints.Count; i++)
  710. {
  711. Point checkPoint = controlPoints[i];
  712. if (isIgnore && IgnorePointsList.Contains(checkPoint))
  713. {
  714. continue;
  715. }
  716. switch (currentDrawPointType)
  717. {
  718. case DrawPointType.Circle:
  719. Vector checkCircle = checkPoint - point;
  720. if (checkCircle.Length < pointSize)
  721. {
  722. return (PointControlType)i;
  723. }
  724. break;
  725. case DrawPointType.Square:
  726. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  727. if (checkRect.Contains(point))
  728. {
  729. return (PointControlType)i;
  730. }
  731. break;
  732. case DrawPointType.Crop:
  733. Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  734. if (cropRect.Contains(point))
  735. {
  736. return (PointControlType)i;
  737. }
  738. break;
  739. default:
  740. break;
  741. }
  742. }
  743. if (drawRect.Contains(point))
  744. {
  745. double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
  746. double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
  747. Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
  748. if (rect.Contains(point))
  749. {
  750. if (!ignoreList.Contains(PointControlType.Body))
  751. {
  752. return PointControlType.Body;
  753. }
  754. }
  755. if (!ignoreList.Contains(PointControlType.Body))
  756. {
  757. return PointControlType.Line;
  758. }
  759. }
  760. double centerX = drawRect.Left + drawRect.Width / 2;
  761. double centerY = drawRect.Top + drawRect.Height / 2;
  762. Point rotatePoint = new Point(centerX, drawRect.Top - rotateline);
  763. Vector checkVector = point - rotatePoint;
  764. if (checkVector.Length <= RotateSize)
  765. {
  766. return PointControlType.Rotate;
  767. }
  768. }
  769. return PointControlType.None;
  770. }
  771. public void SetRotateAngle(double newAngle)
  772. {
  773. if (angle != newAngle)
  774. {
  775. angle = newAngle;
  776. Draw();
  777. }
  778. }
  779. }
  780. }