SelectedRect.cs 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  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 ComPDFKit.Tool.Help.ImportWin32;
  21. using static System.Net.Mime.MediaTypeNames;
  22. namespace ComPDFKit.Tool.DrawTool
  23. {
  24. public enum PointControlType
  25. {
  26. None = -1,
  27. LeftTop,
  28. LeftMiddle,
  29. LeftBottom,
  30. MiddlBottom,
  31. RightBottom,
  32. RightMiddle,
  33. RightTop,
  34. MiddleTop,
  35. Rotate,
  36. Body,
  37. Line
  38. }
  39. public enum SelectedType
  40. {
  41. None = -1,
  42. Annot,
  43. PDFEdit
  44. }
  45. public enum DrawPointType
  46. {
  47. Circle,
  48. Square,
  49. Crop
  50. }
  51. public enum DrawMoveType
  52. {
  53. kDefault,
  54. /// <summary>
  55. /// 移动画线
  56. /// </summary>
  57. kReferenceLine,
  58. }
  59. public class SelectedAnnotData
  60. {
  61. /// <summary>
  62. /// Current size of the rectangle
  63. /// </summary>
  64. public Rect Square { get; set; }
  65. /// <summary>
  66. /// Current points of the rectangle
  67. /// </summary>
  68. public PointCollection Points { get; set; }
  69. public AnnotData annotData { get; set; }
  70. public double Angle { get; set; }
  71. }
  72. public partial class SelectedRect : DrawingVisual
  73. {
  74. /// <summary>
  75. /// Re-layout child elements
  76. /// </summary>
  77. public void Arrange()
  78. {
  79. foreach (Visual child in Children)
  80. {
  81. if (!(child is UIElement))
  82. {
  83. continue;
  84. }
  85. UIElement checkChild = child as UIElement;
  86. try
  87. {
  88. double left = Canvas.GetLeft(checkChild);
  89. double top = Canvas.GetTop(checkChild);
  90. double width = (double)checkChild.GetValue(FrameworkElement.WidthProperty);
  91. double height = (double)checkChild.GetValue(FrameworkElement.HeightProperty);
  92. checkChild.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
  93. checkChild.Arrange(new Rect(
  94. double.IsNaN(left) ? 0 : left,
  95. double.IsNaN(top) ? 0 : top,
  96. double.IsNaN(width) ? checkChild.DesiredSize.Width : width,
  97. double.IsNaN(height) ? checkChild.DesiredSize.Height : height));
  98. }
  99. catch (Exception ex)
  100. {
  101. }
  102. }
  103. }
  104. protected DefaultDrawParam DrawParam = new DefaultDrawParam();
  105. protected DrawingContext drawDC { get; set; }
  106. /// <summary>
  107. /// Data changing event
  108. /// </summary>
  109. public event EventHandler<SelectedAnnotData> DataChanging;
  110. /// <summary>
  111. /// Data changed event
  112. /// </summary>
  113. public event EventHandler<SelectedAnnotData> DataChanged;
  114. protected bool isHover = false;
  115. protected bool isSelected = false;
  116. protected SelectedType selectedType = SelectedType.None;
  117. public bool CanRotate { get; set; }
  118. private double angle = 0;
  119. private Point rotateCenter = new Point(0, 0);
  120. private int rotateline = 25;
  121. public SelectedType GetSelectedType()
  122. {
  123. return selectedType;
  124. }
  125. public void SetIsHover(bool hover)
  126. {
  127. isHover = hover;
  128. }
  129. public bool GetIsHover()
  130. {
  131. return isHover;
  132. }
  133. public void SetIsSelected(bool selected)
  134. {
  135. isSelected = selected;
  136. }
  137. public bool GetIsSelected()
  138. {
  139. return isSelected;
  140. }
  141. public void SetCurrentDrawPointType(DrawPointType type)
  142. {
  143. currentDrawPointType = type;
  144. }
  145. public DrawPointType GetCurrentDrawPointType()
  146. {
  147. return currentDrawPointType;
  148. }
  149. public virtual void OnMouseLeftButtonDown(Point downPoint)
  150. {
  151. isMouseDown = true;
  152. hitControlType = PointControlType.None;
  153. mouseDownPoint = downPoint;
  154. moveOffset = new Point(0, 0);
  155. HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
  156. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  157. {
  158. //Crop judgment point
  159. if (currentDrawPointType == DrawPointType.Crop)
  160. {
  161. hitControlType = GetHitCropControlIndex(downPoint);
  162. }
  163. else
  164. {
  165. hitControlType = GetHitControlIndex(downPoint);
  166. }
  167. if (hitControlType != PointControlType.None)
  168. {
  169. cacheRect = drawRect;
  170. }
  171. rotateCenter = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
  172. }
  173. }
  174. public virtual void OnMouseLeftButtonUp(Point upPoint)
  175. {
  176. if (isMouseDown && hitControlType != PointControlType.None)
  177. {
  178. isMouseDown = false;
  179. cacheRect = SetDrawRect = drawRect;
  180. Draw();
  181. if ((int)upPoint.X != (int)mouseDownPoint.X || (int)upPoint.Y != (int)mouseDownPoint.Y)
  182. {
  183. InvokeDataChangEvent(true);
  184. }
  185. }
  186. moveOffset = new Point(0, 0);
  187. }
  188. public virtual void OnMouseMove(Point mousePoint, out bool Tag, double width, double height)
  189. {
  190. PDFViewerActualWidth = width;
  191. PDFViewerActualHeight = height;
  192. Tag = false;
  193. if (isMouseDown && hitControlType != PointControlType.None)
  194. {
  195. Tag = isMouseDown;
  196. if (CalcHitPointMove(mousePoint))
  197. {
  198. Draw();
  199. if ((int)mousePoint.X != (int)mouseDownPoint.X || (int)mousePoint.Y != (int)mouseDownPoint.Y)
  200. {
  201. InvokeDataChangEvent(false);
  202. }
  203. }
  204. }
  205. }
  206. public Cursor GetCursor(Point downPoint, Cursor cursor)
  207. {
  208. if (isMouseDown)
  209. {
  210. return cursor;
  211. }
  212. hitControlType = GetHitControlIndex(downPoint);
  213. switch (hitControlType)
  214. {
  215. case PointControlType.LeftTop:
  216. case PointControlType.RightBottom:
  217. return Cursors.SizeNWSE;
  218. case PointControlType.LeftMiddle:
  219. case PointControlType.RightMiddle:
  220. return Cursors.SizeWE;
  221. case PointControlType.LeftBottom:
  222. case PointControlType.RightTop:
  223. return Cursors.SizeNESW;
  224. case PointControlType.MiddlBottom:
  225. case PointControlType.MiddleTop:
  226. return Cursors.SizeNS;
  227. case PointControlType.Body:
  228. return Cursors.Arrow;
  229. case PointControlType.Line:
  230. return Cursors.SizeAll;
  231. case PointControlType.Rotate:
  232. return Cursors.Arrow;
  233. default:
  234. return Cursors.Arrow;
  235. }
  236. }
  237. public SelectedRect(DefaultDrawParam defaultDrawParam, SelectedType type) : base()
  238. {
  239. DrawParam = defaultDrawParam;
  240. currentDrawPointType = DrawPointType.Square;
  241. selectedType = type;
  242. }
  243. private void DrawNormal(DrawingContext drawDC)
  244. {
  245. Rect currentRect = SetDrawRect;
  246. switch (currentDrawMoveType)
  247. {
  248. case DrawMoveType.kDefault:
  249. currentRect = drawRect;
  250. CalcControlPoint(currentRect);
  251. break;
  252. case DrawMoveType.kReferenceLine:
  253. CalcControlPoint(currentRect);
  254. if (isMouseDown == true)
  255. {
  256. SolidColorBrush moveBrush = DrawParam.AnnotMoveBrush;
  257. Pen movepen = DrawParam.AnnotMovePen;
  258. GetMoveBrushAndPen(ref moveBrush, ref movepen);
  259. DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect);
  260. }
  261. break;
  262. default:
  263. break;
  264. }
  265. SolidColorBrush solidColorBrush = DrawParam.AnnotRectFillBrush;
  266. Pen pen = DrawParam.AnnotRectLinePen;
  267. GetBrushAndPen(ref solidColorBrush, ref pen);
  268. drawDC?.DrawRectangle(solidColorBrush, pen, currentRect);
  269. SolidColorBrush PointBrush = DrawParam.AnnotPointBorderBrush;
  270. Pen PointPen = DrawParam.AnnotPointPen;
  271. GetPointBrushAndPen(ref PointBrush, ref PointPen);
  272. switch (currentDrawPointType)
  273. {
  274. case DrawPointType.Circle:
  275. DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  276. break;
  277. case DrawPointType.Square:
  278. DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  279. break;
  280. case DrawPointType.Crop:
  281. DrawCropPoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  282. break;
  283. }
  284. }
  285. private void PushRotate(DrawingContext drawDC)
  286. {
  287. if (CanRotate)
  288. {
  289. RotateTransform transform = new RotateTransform();
  290. transform.Angle = angle;
  291. // if(hitControlType==PointControlType.Body || hitControlType==PointControlType.Line)
  292. {
  293. rotateCenter.X = drawRect.Left + drawRect.Width / 2;
  294. rotateCenter.Y = drawRect.Top + drawRect.Height / 2;
  295. }
  296. transform.CenterX = rotateCenter.X;
  297. transform.CenterY = rotateCenter.Y;
  298. drawDC.PushTransform(transform);
  299. }
  300. }
  301. private void PopRotate(DrawingContext drawDC)
  302. {
  303. if (CanRotate)
  304. {
  305. drawDC.Pop();
  306. }
  307. }
  308. private void DrawRotate(DrawingContext drawDC)
  309. {
  310. if (CanRotate)
  311. {
  312. double centerX = drawRect.Left + drawRect.Width / 2;
  313. double centerY = drawRect.Top + drawRect.Height / 2;
  314. Pen PointPen = DrawParam.AnnotPointPen;
  315. drawDC.DrawLine(PointPen, new Point(centerX, drawRect.Top), new Point(centerX, drawRect.Top - rotateline));
  316. drawDC.DrawEllipse(PointPen.Brush, PointPen, new Point(centerX, drawRect.Top - rotateline), RotateSize, RotateSize);
  317. }
  318. }
  319. public void Draw()
  320. {
  321. Dispatcher.Invoke(() =>
  322. {
  323. Rect currentRect = SetDrawRect;
  324. drawDC = RenderOpen();
  325. PushRotate(drawDC);
  326. DrawRotate(drawDC);
  327. DrawNormal(drawDC);
  328. PopRotate(drawDC);
  329. drawDC?.Close();
  330. drawDC = null;
  331. });
  332. }
  333. private void GetMoveBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  334. {
  335. switch (selectedType)
  336. {
  337. case SelectedType.None:
  338. break;
  339. case SelectedType.Annot:
  340. colorBrush = DrawParam.AnnotMoveBrush;
  341. pen = DrawParam.AnnotMovePen;
  342. break;
  343. case SelectedType.PDFEdit:
  344. colorBrush = DrawParam.PDFEditMoveBrush;
  345. pen = DrawParam.PDFEditMovePen;
  346. break;
  347. default:
  348. break;
  349. }
  350. }
  351. private void GetPointBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  352. {
  353. switch (selectedType)
  354. {
  355. case SelectedType.None:
  356. break;
  357. case SelectedType.Annot:
  358. colorBrush = DrawParam.AnnotPointBorderBrush;
  359. pen = DrawParam.AnnotPointPen;
  360. break;
  361. case SelectedType.PDFEdit:
  362. if (isHover)
  363. {
  364. colorBrush = DrawParam.PDFEditRectFillHoverBrush;
  365. pen = DrawParam.PDFEditPointHoverPen;
  366. }
  367. else if (currentDrawPointType == DrawPointType.Crop)
  368. {
  369. colorBrush = DrawParam.SPDFEditCropBorderBrush;//new SolidColorBrush((DrawParam.SPDFEditPointPen.Brush as SolidColorBrush).Color);
  370. pen = DrawParam.SPDFEditPointPen.Clone();
  371. pen.DashStyle = DashStyles.Solid;
  372. }
  373. else
  374. {
  375. if (isSelected)
  376. {
  377. colorBrush = DrawParam.SPDFEditPointBorderBrush;
  378. pen = DrawParam.SPDFEditPointPen;
  379. }
  380. else
  381. {
  382. colorBrush = DrawParam.PDFEditPointBorderBrush;
  383. pen = DrawParam.PDFEditPointPen;
  384. }
  385. }
  386. break;
  387. default:
  388. break;
  389. }
  390. }
  391. private void GetBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  392. {
  393. switch (selectedType)
  394. {
  395. case SelectedType.None:
  396. break;
  397. case SelectedType.Annot:
  398. if (isHover)
  399. {
  400. colorBrush = DrawParam.AnnotRectFillBrush;
  401. pen = DrawParam.AnnotRectHoverPen;
  402. }
  403. else
  404. {
  405. colorBrush = DrawParam.AnnotRectFillBrush;
  406. pen = DrawParam.AnnotRectLinePen;
  407. }
  408. break;
  409. case SelectedType.PDFEdit:
  410. if (isHover)
  411. {
  412. colorBrush = DrawParam.PDFEditRectFillHoverBrush;
  413. pen = editHoverPen;//DrawParam.PDFEditRectLineHoverPen;
  414. }
  415. else
  416. {
  417. if (isSelected)
  418. {
  419. colorBrush = DrawParam.SPDFEditRectFillBrush;
  420. pen = DrawParam.SPDFEditRectLinePen;
  421. }
  422. else
  423. {
  424. colorBrush = DrawParam.PDFEditRectFillBrush;
  425. //init Color
  426. if (showCreatTextRect)
  427. {
  428. pen = DrawParam.PDFEditRectLinePen;
  429. }
  430. else
  431. {
  432. pen = editPen;
  433. }
  434. // editPen; //editPen;//// DrawParam.PDFEditRectLinePen;
  435. }
  436. }
  437. break;
  438. default:
  439. break;
  440. }
  441. }
  442. public void SetShowCreatTextRect(bool ShowCreatTextRect)
  443. {
  444. showCreatTextRect = ShowCreatTextRect;
  445. }
  446. public void SetEditPen(Pen editPen = null, Pen editHoverPen = null)
  447. {
  448. if (editPen == null)
  449. {
  450. this.editPen = DrawParam.PDFEditRectLinePen;
  451. }
  452. else
  453. {
  454. this.editPen = new Pen(editPen.Brush, editPen.Thickness);
  455. }
  456. if (editHoverPen == null)
  457. {
  458. this.editHoverPen = DrawParam.PDFEditRectLineHoverPen;
  459. }
  460. else
  461. {
  462. this.editHoverPen = editHoverPen;
  463. }
  464. }
  465. public virtual void ClearDraw()
  466. {
  467. SetDrawRect = drawRect = new Rect();
  468. drawDC = RenderOpen();
  469. drawDC?.Close();
  470. drawDC = null;
  471. }
  472. /// <summary>
  473. /// Hide the drawing
  474. /// </summary>
  475. public virtual void HideDraw()
  476. {
  477. drawDC = RenderOpen();
  478. drawDC?.Close();
  479. }
  480. public void SetRect(Rect newRect, double zoom)
  481. {
  482. if (newRect == Rect.Empty || newRect == null)
  483. {
  484. return;
  485. }
  486. 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));
  487. currentZoom = zoom;
  488. SetDrawRect = drawRect = newRect;
  489. drawCenterPoint = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
  490. }
  491. /// <summary>
  492. /// Get the original set Rect, not the calculated fill
  493. /// </summary>
  494. /// <param name="newRect">
  495. /// The new rect to set
  496. /// </param>
  497. public Rect GetRect()
  498. {
  499. 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));
  500. return rect;
  501. }
  502. public void SetRectPadding(double rectPadding)
  503. {
  504. this.rectPadding = rectPadding;
  505. }
  506. public double GetRectPadding()
  507. {
  508. return rectPadding;
  509. }
  510. public Rect GetDrawRect()
  511. {
  512. return drawRect;
  513. }
  514. /// <summary>
  515. /// Obtain cropped and actual region margin
  516. /// </summary>
  517. /// <returns></returns>
  518. public Thickness GetClipThickness()
  519. {
  520. return clipThickness;
  521. }
  522. /// <summary>
  523. /// Get ClipRect
  524. /// </summary>
  525. /// <returns></returns>
  526. public Rect GetClipRect()
  527. {
  528. Rect drawrect = new Rect(0, 0, 0, 0);
  529. drawrect.X = SetDrawRect.X - clipThickness.Left * currentZoom;
  530. drawrect.Y = SetDrawRect.Y - clipThickness.Top * currentZoom;
  531. drawrect.Width = SetDrawRect.Width - clipThickness.Right * currentZoom + clipThickness.Left * currentZoom;
  532. drawrect.Height = SetDrawRect.Height - clipThickness.Bottom * currentZoom + clipThickness.Top * currentZoom;
  533. return drawrect;
  534. }
  535. /// <summary>
  536. /// Set cropping and actual area margins
  537. /// </summary>
  538. /// <returns></returns>
  539. public void SetClipThickness(Thickness rect)
  540. {
  541. try
  542. {
  543. Rect drawrect = new Rect(0, 0, 0, 0);
  544. drawrect.X = SetDrawRect.X - rect.Left * currentZoom;
  545. drawrect.Y = SetDrawRect.Y - rect.Top * currentZoom;
  546. drawrect.Width = SetDrawRect.Width - rect.Right * currentZoom + rect.Left * currentZoom;
  547. drawrect.Height = SetDrawRect.Height - rect.Bottom * currentZoom + rect.Top * currentZoom;
  548. drawRect = drawrect;
  549. clipThickness = rect;
  550. }
  551. catch { }
  552. }
  553. public void SetMaxRect(Rect rect)
  554. {
  555. maxRect = rect;
  556. }
  557. public Rect GetMaxRect()
  558. {
  559. return maxRect;
  560. }
  561. public void UpdateAnnotData(AnnotData annotData)
  562. {
  563. if (selectedRectData != null)
  564. {
  565. selectedRectData.annotData = annotData;
  566. }
  567. }
  568. public void SetAnnotData(AnnotData annotData)
  569. {
  570. SetIgnorePoints(new List<PointControlType>());
  571. SetIsProportionalScaling(false);
  572. isProportionalScaling = false;
  573. switch (annotData.AnnotType)
  574. {
  575. case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
  576. case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
  577. case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
  578. case C_ANNOTATION_TYPE.C_ANNOTATION_STRIKEOUT:
  579. case C_ANNOTATION_TYPE.C_ANNOTATION_RICHMEDIA:
  580. case C_ANNOTATION_TYPE.C_ANNOTATION_MOVIE:
  581. case C_ANNOTATION_TYPE.C_ANNOTATION_REDACT:
  582. DisableAll();
  583. break;
  584. case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
  585. case C_ANNOTATION_TYPE.C_ANNOTATION_SOUND:
  586. SetIgnorePointsAll();
  587. break;
  588. case C_ANNOTATION_TYPE.C_ANNOTATION_STAMP:
  589. SetIsProportionalScaling(true);
  590. break;
  591. case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
  592. SetIgnorePointsAll();
  593. break;
  594. default:
  595. break;
  596. }
  597. SetMaxRect(annotData.PaintOffset);
  598. SetRect(annotData.PaintRect, annotData.CurrentZoom);
  599. selectedRectData = new SelectedAnnotData();
  600. selectedRectData.annotData = annotData;
  601. }
  602. public void SetIsProportionalScaling(bool isProportionalScaling)
  603. {
  604. this.isProportionalScaling = isProportionalScaling;
  605. ignorePoints.Clear();
  606. if (isProportionalScaling)
  607. {
  608. ignorePoints.Add(PointControlType.LeftMiddle);
  609. ignorePoints.Add(PointControlType.MiddlBottom);
  610. ignorePoints.Add(PointControlType.RightMiddle);
  611. ignorePoints.Add(PointControlType.MiddleTop);
  612. ignorePoints.Add(PointControlType.Rotate);
  613. }
  614. }
  615. public void SetDrawType(DrawPointType drawType)
  616. {
  617. currentDrawPointType = drawType;
  618. }
  619. public void SetDrawMoveType(DrawMoveType drawType)
  620. {
  621. currentDrawMoveType = drawType;
  622. }
  623. /// <summary>
  624. /// Set the types that need to be ignored
  625. /// </summary>
  626. /// <param name="types">
  627. /// The collection of point types that need to be ignored
  628. /// </param>
  629. public void SetIgnorePoints(List<PointControlType> types)
  630. {
  631. ignorePoints.Clear();
  632. foreach (PointControlType type in types)
  633. {
  634. ignorePoints.Add(type);
  635. }
  636. }
  637. /// <summary>
  638. /// Set Edit that need to be ignored
  639. /// </summary>
  640. /// <param name="types">
  641. /// The collection of point types that need to be ignored
  642. /// </param>
  643. public void SetEditIgnorePoints(List<PointControlType> ignoreTextPoints, List<PointControlType> ignoreImagePoints, DrawPointType drawEditPointType, bool IsText = true)
  644. {
  645. SetCurrentDrawPointType(drawEditPointType);
  646. if (IsText)
  647. {
  648. ignorePoints.Clear();
  649. foreach (PointControlType type in ignoreTextPoints)
  650. {
  651. ignorePoints.Add(type);
  652. }
  653. }
  654. else
  655. {
  656. ignorePoints.Clear();
  657. foreach (PointControlType type in ignoreImagePoints)
  658. {
  659. ignorePoints.Add(type);
  660. }
  661. }
  662. }
  663. /// <summary>
  664. /// Ignore all points
  665. /// </summary>
  666. public void SetIgnorePointsAll()
  667. {
  668. ignorePoints.Clear();
  669. ignorePoints.Add(PointControlType.LeftTop);
  670. ignorePoints.Add(PointControlType.LeftMiddle);
  671. ignorePoints.Add(PointControlType.LeftBottom);
  672. ignorePoints.Add(PointControlType.MiddlBottom);
  673. ignorePoints.Add(PointControlType.RightBottom);
  674. ignorePoints.Add(PointControlType.RightMiddle);
  675. ignorePoints.Add(PointControlType.RightTop);
  676. ignorePoints.Add(PointControlType.MiddleTop);
  677. }
  678. /// <summary>
  679. /// Disable all functions
  680. /// </summary>
  681. public void DisableAll()
  682. {
  683. ignorePoints.Clear();
  684. ignorePoints.Add(PointControlType.LeftTop);
  685. ignorePoints.Add(PointControlType.LeftMiddle);
  686. ignorePoints.Add(PointControlType.LeftBottom);
  687. ignorePoints.Add(PointControlType.MiddlBottom);
  688. ignorePoints.Add(PointControlType.RightBottom);
  689. ignorePoints.Add(PointControlType.RightMiddle);
  690. ignorePoints.Add(PointControlType.RightTop);
  691. ignorePoints.Add(PointControlType.MiddleTop);
  692. ignorePoints.Add(PointControlType.Rotate);
  693. ignorePoints.Add(PointControlType.Body);
  694. ignorePoints.Add(PointControlType.Line);
  695. }
  696. /// <summary>
  697. /// Set the left alignment in the set maximum rectangle
  698. /// </summary>
  699. public virtual void SetAlignLeftForMaxRect()
  700. {
  701. DrawAlignRect(AlignmentsHelp.SetAlignLeft(drawRect, maxRect));
  702. }
  703. /// <summary>
  704. /// Set horizontal center alignment in the set maximum rectangle
  705. /// </summary>
  706. public virtual void SetAlignHorizonCenterForMaxRect()
  707. {
  708. DrawAlignRect(AlignmentsHelp.SetAlignHorizonCenter(drawRect, maxRect));
  709. }
  710. /// <summary>
  711. /// Set horizontal right alignment in the set maximum rectangle
  712. /// </summary>
  713. public virtual void SetAlignRightForMaxRect()
  714. {
  715. DrawAlignRect(AlignmentsHelp.SetAlignRight(drawRect, maxRect));
  716. }
  717. /// <summary>
  718. /// Set the top alignment in the set maximum rectangle
  719. /// </summary>
  720. public virtual void SetAlignTopForMaxRect()
  721. {
  722. DrawAlignRect(AlignmentsHelp.SetAlignTop(drawRect, maxRect));
  723. }
  724. /// <summary>
  725. /// Set vertical center alignment in the set maximum rectangle
  726. /// </summary>
  727. public virtual void SetAlignVerticalCenterForMaxRect()
  728. {
  729. DrawAlignRect(AlignmentsHelp.SetAlignVerticalCenter(drawRect, maxRect));
  730. }
  731. /// <summary>
  732. /// Set vertical center alignment in the set maximum rectangle
  733. /// </summary>
  734. public virtual void SetAlignHorizonVerticalCenterForMaxRect()
  735. {
  736. DrawAlignRect(AlignmentsHelp.SetAlignHorizonVerticalCenter(drawRect, maxRect));
  737. }
  738. /// <summary>
  739. /// Set the bottom alignment in the set maximum rectangle
  740. /// </summary>
  741. public virtual void SetAlignBottomForMaxRect()
  742. {
  743. DrawAlignRect(AlignmentsHelp.SetAlignBottom(drawRect, maxRect));
  744. }
  745. /// <summary>
  746. /// Get which control point the coordinate is on
  747. /// </summary>
  748. /// <param name="clickPoint">
  749. /// The point to check
  750. /// </param>
  751. /// <returns>
  752. /// The control point type
  753. /// </returns>
  754. public PointControlType GetHitControlIndex(Point point, bool isIgnore = true)
  755. {
  756. if (CanRotate)
  757. {
  758. return GetRotateHitIndex(point, isIgnore);
  759. }
  760. return GetNormalHitIndex(point, isIgnore);
  761. }
  762. private PointControlType GetNormalHitIndex(Point point, bool isIgnore = true)
  763. {
  764. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  765. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  766. {
  767. List<PointControlType> ignoreList = GetIgnorePoints();
  768. List<Point> IgnorePointsList = new List<Point>();
  769. foreach (PointControlType type in ignoreList)
  770. {
  771. if ((int)type < controlPoints.Count)
  772. {
  773. IgnorePointsList.Add(controlPoints[(int)type]);
  774. }
  775. }
  776. for (int i = 0; i < controlPoints.Count; i++)
  777. {
  778. Point checkPoint = controlPoints[i];
  779. if (isIgnore && IgnorePointsList.Contains(checkPoint))
  780. {
  781. continue;
  782. }
  783. switch (currentDrawPointType)
  784. {
  785. case DrawPointType.Circle:
  786. if (IgnorePointsList.Contains(checkPoint))
  787. {
  788. continue;
  789. }
  790. Vector checkVector = checkPoint - point;
  791. double wlen = drawRect.Width;
  792. if (wlen > 50)
  793. {
  794. wlen = 20;
  795. }
  796. else
  797. {
  798. wlen = wlen / 3;
  799. }
  800. double hlen = drawRect.Height;
  801. if (hlen > 50)
  802. {
  803. hlen = 20;
  804. }
  805. else
  806. {
  807. hlen = wlen / 3;
  808. }
  809. if ((PointControlType)i == PointControlType.RightMiddle)
  810. {
  811. if (Math.Abs(point.X - checkPoint.X) < wlen && checkVector.Length < drawRect.Height / 3)
  812. {
  813. return (PointControlType)i;
  814. }
  815. }
  816. if ((PointControlType)i == PointControlType.LeftMiddle)
  817. {
  818. if (Math.Abs(point.X - checkPoint.X) < wlen && checkVector.Length < drawRect.Height / 3)
  819. {
  820. return (PointControlType)i;
  821. }
  822. }
  823. if ((PointControlType)i == PointControlType.MiddleTop)
  824. {
  825. if (Math.Abs(point.Y - checkPoint.Y) < hlen && checkVector.Length < drawRect.Width / 3)
  826. {
  827. return (PointControlType)i;
  828. }
  829. }
  830. if ((PointControlType)i == PointControlType.MiddlBottom)
  831. {
  832. if (Math.Abs(point.Y - checkPoint.Y) < hlen && checkVector.Length < drawRect.Width / 3)
  833. {
  834. return (PointControlType)i;
  835. }
  836. }
  837. if (checkVector.Length < pointSize)
  838. {
  839. return (PointControlType)i;
  840. }
  841. break;
  842. case DrawPointType.Square:
  843. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  844. if (checkRect.Contains(point))
  845. {
  846. return (PointControlType)i;
  847. }
  848. break;
  849. case DrawPointType.Crop:
  850. Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  851. if (cropRect.Contains(point))
  852. {
  853. return (PointControlType)i;
  854. }
  855. break;
  856. default:
  857. break;
  858. }
  859. }
  860. if (drawRect.Contains(point))
  861. {
  862. double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
  863. double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
  864. Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
  865. if (rect.Contains(point))
  866. {
  867. if (!ignoreList.Contains(PointControlType.Body))
  868. {
  869. return PointControlType.Body;
  870. }
  871. }
  872. if (!ignoreList.Contains(PointControlType.Body))
  873. {
  874. return PointControlType.Line;
  875. }
  876. }
  877. }
  878. return PointControlType.None;
  879. }
  880. private PointControlType GetRotateHitIndex(Point point, bool isIgnore = true)
  881. {
  882. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  883. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  884. {
  885. //旋转回去
  886. Point centerPoint = rotateCenter;
  887. Vector currentVector = point - centerPoint;
  888. Matrix matrix = new Matrix();
  889. matrix.Rotate(-angle);
  890. Vector transVector = matrix.Transform(currentVector);
  891. Point checkPos = new Point(centerPoint.X + transVector.X, centerPoint.Y + transVector.Y);
  892. point = checkPos;
  893. List<PointControlType> ignoreList = GetIgnorePoints();
  894. List<Point> IgnorePointsList = new List<Point>();
  895. foreach (PointControlType type in ignoreList)
  896. {
  897. if ((int)type < controlPoints.Count)
  898. {
  899. IgnorePointsList.Add(controlPoints[(int)type]);
  900. }
  901. }
  902. for (int i = 0; i < controlPoints.Count; i++)
  903. {
  904. Point checkPoint = controlPoints[i];
  905. if (isIgnore && IgnorePointsList.Contains(checkPoint))
  906. {
  907. continue;
  908. }
  909. switch (currentDrawPointType)
  910. {
  911. case DrawPointType.Circle:
  912. Vector checkCircle = checkPoint - point;
  913. if (checkCircle.Length < pointSize)
  914. {
  915. return (PointControlType)i;
  916. }
  917. break;
  918. case DrawPointType.Square:
  919. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  920. if (checkRect.Contains(point))
  921. {
  922. return (PointControlType)i;
  923. }
  924. break;
  925. case DrawPointType.Crop:
  926. Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  927. if (cropRect.Contains(point))
  928. {
  929. return (PointControlType)i;
  930. }
  931. break;
  932. default:
  933. break;
  934. }
  935. }
  936. if (drawRect.Contains(point))
  937. {
  938. double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
  939. double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
  940. Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
  941. if (rect.Contains(point))
  942. {
  943. if (!ignoreList.Contains(PointControlType.Body))
  944. {
  945. return PointControlType.Body;
  946. }
  947. }
  948. if (!ignoreList.Contains(PointControlType.Body))
  949. {
  950. return PointControlType.Line;
  951. }
  952. }
  953. double centerX = drawRect.Left + drawRect.Width / 2;
  954. double centerY = drawRect.Top + drawRect.Height / 2;
  955. Point rotatePoint = new Point(centerX, drawRect.Top - rotateline);
  956. Vector checkVector = point - rotatePoint;
  957. if (checkVector.Length <= RotateSize)
  958. {
  959. return PointControlType.Rotate;
  960. }
  961. }
  962. return PointControlType.None;
  963. }
  964. public void SetRotateAngle(double newAngle)
  965. {
  966. if (angle != newAngle)
  967. {
  968. angle = newAngle;
  969. Draw();
  970. }
  971. }
  972. /// <summary>
  973. /// The position of the points in the cropping box
  974. /// </summary>
  975. /// <param name="point"></param>
  976. /// <param name="isIgnore"></param>
  977. /// <returns></returns>
  978. public PointControlType GetHitCropControlIndex(Point point, bool isIgnore = true)
  979. {
  980. List<Point> controlCurrentPoints = GetControlPoint(drawRect);
  981. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  982. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  983. {
  984. List<PointControlType> ignoreList = GetIgnorePoints();
  985. List<Point> IgnorePointsList = new List<Point>();
  986. foreach (PointControlType type in ignoreList)
  987. {
  988. if ((int)type < controlCurrentPoints.Count)
  989. {
  990. IgnorePointsList.Add(controlCurrentPoints[(int)type]);
  991. }
  992. }
  993. for (int i = 0; i < controlCurrentPoints.Count; i++)
  994. {
  995. Point checkPoint = controlCurrentPoints[i];
  996. if (isIgnore && IgnorePointsList.Contains(checkPoint))
  997. {
  998. continue;
  999. }
  1000. switch (currentDrawPointType)
  1001. {
  1002. case DrawPointType.Circle:
  1003. Vector checkVector = checkPoint - point;
  1004. if (checkVector.Length < pointSize)
  1005. {
  1006. return (PointControlType)i;
  1007. }
  1008. break;
  1009. case DrawPointType.Square:
  1010. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  1011. if (checkRect.Contains(point))
  1012. {
  1013. return (PointControlType)i;
  1014. }
  1015. break;
  1016. case DrawPointType.Crop:
  1017. Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  1018. if (cropRect.Contains(point))
  1019. {
  1020. return (PointControlType)i;
  1021. }
  1022. break;
  1023. default:
  1024. break;
  1025. }
  1026. }
  1027. if (drawRect.Contains(point))
  1028. {
  1029. double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
  1030. double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
  1031. Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
  1032. if (rect.Contains(point))
  1033. {
  1034. if (!ignoreList.Contains(PointControlType.Body))
  1035. {
  1036. return PointControlType.Body;
  1037. }
  1038. }
  1039. if (!ignoreList.Contains(PointControlType.Body))
  1040. {
  1041. return PointControlType.Line;
  1042. }
  1043. }
  1044. }
  1045. return PointControlType.None;
  1046. }
  1047. }
  1048. }