SelectedRect.cs 38 KB

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