MultiSelectedRect.cs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
  1. using ComPDFKit.Tool.SettingParam;
  2. using ComPDFKitViewer;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. using System.Windows.Controls;
  11. using System.Windows.Media;
  12. using static ComPDFKit.Tool.Help.ImportWin32;
  13. namespace ComPDFKit.Tool.DrawTool
  14. {
  15. public enum MulitiDrawMoveType
  16. {
  17. Default,
  18. Alone
  19. }
  20. public class MultiSelectedRect : DrawingVisual
  21. {
  22. /// <summary>
  23. /// Re-layout child elements
  24. /// </summary>
  25. public void Arrange()
  26. {
  27. foreach (Visual child in Children)
  28. {
  29. if (!(child is UIElement))
  30. {
  31. continue;
  32. }
  33. UIElement checkChild = child as UIElement;
  34. try
  35. {
  36. double left = Canvas.GetLeft(checkChild);
  37. double top = Canvas.GetTop(checkChild);
  38. double width = (double)checkChild.GetValue(FrameworkElement.WidthProperty);
  39. double height = (double)checkChild.GetValue(FrameworkElement.HeightProperty);
  40. checkChild.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
  41. checkChild.Arrange(new Rect(
  42. double.IsNaN(left) ? 0 : left,
  43. double.IsNaN(top) ? 0 : top,
  44. double.IsNaN(width) ? checkChild.DesiredSize.Width : width,
  45. double.IsNaN(height) ? checkChild.DesiredSize.Height : height));
  46. }
  47. catch (Exception ex)
  48. {
  49. }
  50. }
  51. }
  52. protected DefaultDrawParam drawParam = new DefaultDrawParam();
  53. protected DrawingContext drawDC { get; set; }
  54. /// <summary>
  55. /// DataChanging event
  56. /// </summary>
  57. public event EventHandler<Point> DataChanging;
  58. /// <summary>
  59. /// DataChanged event
  60. /// </summary>
  61. public event EventHandler<Point> DataChanged;
  62. protected SelectedType selectedType = SelectedType.None;
  63. /// <summary>
  64. /// Minimum width of the rectangle
  65. /// </summary>
  66. protected int rectMinWidth { get; set; } = 10;
  67. /// <summary>
  68. /// Minimum height of the rectangle
  69. /// </summary>
  70. protected int rectMinHeight { get; set; } = 10;
  71. /// <summary>
  72. /// Identify whether the mouse is pressed
  73. /// </summary>
  74. protected bool isMouseDown { get; set; }
  75. /// <summary>
  76. /// Current hit control point
  77. /// </summary>
  78. protected PointControlType hitControlType { get; set; }
  79. /// <summary>
  80. /// Location information recorded when the mouse is pressed
  81. /// </summary>
  82. protected Point mouseDownPoint { get; set; }
  83. /// <summary>
  84. /// Current set ignore points
  85. /// </summary>
  86. protected List<PointControlType> ignorePoints { get; set; } = new List<PointControlType>();
  87. /// <summary>
  88. /// Current control point coordinates
  89. /// </summary>
  90. protected List<Point> controlPoints { get; set; } = new List<Point>();
  91. /// <summary>
  92. /// Move offset
  93. /// </summary>
  94. protected Point moveOffset { get; set; } = new Point(0, 0);
  95. /// <summary>
  96. /// Current PDFVIewer's actual display width
  97. /// </summary>
  98. protected double PDFViewerActualWidth { get; set; } = 0;
  99. /// <summary>
  100. /// Current PDFVIewer's actual display height
  101. /// </summary>
  102. protected double PDFViewerActualHeight { get; set; } = 0;
  103. /// <summary>
  104. /// Current control point drawing style
  105. /// </summary>
  106. protected DrawPointType currentDrawPointType { get; set; }
  107. /// <summary>
  108. /// Current drag drawing style
  109. /// </summary>
  110. protected DrawMoveType currentDrawMoveType { get; set; }
  111. /// <summary>
  112. /// Current multi-select drawing style
  113. /// </summary>
  114. protected MulitiDrawMoveType currentDrawType { get; set; } = MulitiDrawMoveType.Default;
  115. /// <summary>
  116. /// Control point size
  117. /// </summary>
  118. protected int pointSize { get; set; } = 4;
  119. /// <summary>
  120. /// Current drawing rectangle (calculated during operation)
  121. /// </summary>
  122. protected Rect drawRect { get; set; } = new Rect(0, 0, 0, 0);
  123. /// <summary>
  124. /// Default outermost rectangle of the drawing style (calculated during operation)
  125. /// </summary>
  126. protected Rect drawDefaultRect { get; set; } = new Rect(0, 0, 0, 0);
  127. /// <summary>
  128. /// Padding between the border and the content
  129. /// </summary>
  130. protected double rectPadding = 5;
  131. /// <summary>
  132. /// Mouse down cache rectangle
  133. /// </summary>
  134. protected Rect cacheRect { get; set; } = new Rect(0, 0, 0, 0);
  135. /// <summary>
  136. /// Current set drawing rectangle (original data)
  137. /// </summary>
  138. protected Rect setDrawRect { get; set; } = new Rect(0, 0, 0, 0);
  139. /// <summary>
  140. /// Maximum drawable range
  141. /// </summary>
  142. protected Rect maxRect { get; set; } = new Rect(0, 0, 0, 0);
  143. /// <summary>
  144. /// Identify whether the mouse is pressed
  145. /// </summary>
  146. protected bool isProportionalScaling { get; set; } = false;
  147. /// <summary>
  148. /// Array passed from outside for multiple selection
  149. /// </summary>
  150. protected List<SelectedRect> selectedRects = new List<SelectedRect>();
  151. protected Dictionary<SelectedRect,KeyValuePair<int,int>> RelationDict=new Dictionary<SelectedRect, KeyValuePair<int, int>>();
  152. protected bool isHover = false;
  153. protected bool isSelected = false;
  154. public void SetIsHover(bool hover)
  155. {
  156. isHover = hover;
  157. }
  158. public bool GetIsHover()
  159. {
  160. return isHover;
  161. }
  162. public void SetIsSelected(bool selected)
  163. {
  164. isSelected = selected;
  165. }
  166. public bool GetIsSelected()
  167. {
  168. return isSelected;
  169. }
  170. public MultiSelectedRect(DefaultDrawParam defaultDrawParam, SelectedType type) : base()
  171. {
  172. drawParam = defaultDrawParam;
  173. currentDrawPointType = DrawPointType.Circle;
  174. selectedType = type;
  175. }
  176. public void SetMulitSelectedRect(SelectedRect selectedobject,int pageIndex,int editIndex)
  177. {
  178. selectedRects.Add(selectedobject);
  179. RelationDict[selectedobject] = new KeyValuePair<int, int>(pageIndex, editIndex);
  180. }
  181. public bool GetRelationKey(SelectedRect selectedobject,out int pageIndex,out int editIndex)
  182. {
  183. pageIndex = -1;
  184. editIndex = -1;
  185. if(RelationDict!=null && RelationDict.ContainsKey(selectedobject))
  186. {
  187. KeyValuePair<int, int> relateData = RelationDict[selectedobject];
  188. pageIndex = relateData.Key;
  189. editIndex = relateData.Value;
  190. return true;
  191. }
  192. return false;
  193. }
  194. /// <summary>
  195. /// delete
  196. /// </summary>
  197. /// <param name="selectedobject"></param>
  198. public void DelMulitSelectedRect(SelectedRect selectedobject)
  199. {
  200. selectedRects.Remove(selectedobject);
  201. RelationDict.Remove(selectedobject);
  202. }
  203. /// <summary>
  204. /// get selectedRects Index
  205. /// </summary>
  206. /// <param name="selectedobject"></param>
  207. /// <returns></returns>
  208. public int GetMulitSelectedRectIndex(SelectedRect selectedobject)
  209. {
  210. return selectedRects.IndexOf(selectedobject);
  211. }
  212. public List<SelectedRect> GetMulitSelectList()
  213. {
  214. return selectedRects==null ? new List<SelectedRect>() : selectedRects;
  215. }
  216. public SelectedType GetSelectedType()
  217. {
  218. return selectedType;
  219. }
  220. public void SetSelectedType(SelectedType type)
  221. {
  222. if (selectedType != type)
  223. {
  224. selectedRects.Clear();
  225. RelationDict.Clear();
  226. }
  227. selectedType = type;
  228. }
  229. public void CleanMulitSelectedRect()
  230. {
  231. selectedRects.Clear();
  232. RelationDict.Clear();
  233. }
  234. public virtual void OnMouseLeftButtonDown(Point downPoint)
  235. {
  236. isMouseDown = true;
  237. hitControlType = PointControlType.None;
  238. mouseDownPoint = downPoint;
  239. moveOffset = new Point(0, 0);
  240. HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
  241. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  242. {
  243. hitControlType = GetHitControlIndex(downPoint);
  244. if (hitControlType != PointControlType.None)
  245. {
  246. cacheRect = drawRect;
  247. }
  248. }
  249. }
  250. public virtual void OnMouseLeftButtonUp(Point upPoint)
  251. {
  252. if (isMouseDown && hitControlType != PointControlType.None)
  253. {
  254. isMouseDown = false;
  255. cacheRect = setDrawRect = drawRect;
  256. Draw();
  257. if ((int)upPoint.X != (int)mouseDownPoint.X || (int)upPoint.Y != (int)mouseDownPoint.Y)
  258. {
  259. InvokeDataChangEvent(true);
  260. }
  261. }
  262. moveOffset = new Point(0, 0);
  263. }
  264. public virtual void OnMouseMove(Point mousePoint, out bool Tag, double width, double height)
  265. {
  266. PDFViewerActualWidth = width;
  267. PDFViewerActualHeight = height;
  268. Tag = false;
  269. if (isMouseDown && hitControlType != PointControlType.None)
  270. {
  271. Tag = isMouseDown;
  272. if (CalcHitPointMove(mousePoint))
  273. {
  274. Draw();
  275. if ((int)mousePoint.X != (int)mouseDownPoint.X || (int)mousePoint.Y != (int)mouseDownPoint.Y)
  276. {
  277. InvokeDataChangEvent(false);
  278. }
  279. }
  280. }
  281. }
  282. public float GetZoomX()
  283. {
  284. return (float)(drawRect.Width / drawDefaultRect.Width);
  285. }
  286. public float GetZoomY()
  287. {
  288. return (float)(drawRect.Height / drawDefaultRect.Height);
  289. }
  290. public float GetChangeX()
  291. {
  292. return (float)(drawRect.Width - drawDefaultRect.Width);
  293. }
  294. public float GetChangeY()
  295. {
  296. return (float)(drawRect.Height - drawDefaultRect.Height);
  297. }
  298. public void Draw()
  299. {
  300. switch (currentDrawType)
  301. {
  302. case MulitiDrawMoveType.Default:
  303. Dispatcher.Invoke(() =>
  304. {
  305. if (drawDefaultRect.IsEmpty == false && drawDefaultRect.Width > 0 && drawDefaultRect.Height > 0)
  306. {
  307. drawDC = RenderOpen();
  308. CalcControlPoint(drawDefaultRect);
  309. SolidColorBrush solidColorBrush = drawParam.SPDFEditMultiRectFillBrush;
  310. Pen pen = drawParam.SPDFEditMultiRectLinePen;
  311. GetBrushAndPen(ref solidColorBrush, ref pen);
  312. if (selectedRects.Count >= 1)
  313. {
  314. foreach (SelectedRect item in selectedRects)
  315. {
  316. Rect rect = item.GetRect();
  317. rect.X -= rectPadding;
  318. rect.Y -= rectPadding;
  319. rect.Width += rectPadding;
  320. rect.Height += rectPadding;
  321. drawDC?.DrawRectangle(solidColorBrush, pen, rect);
  322. }
  323. }
  324. SolidColorBrush PointBrush = drawParam.PDFEditMultiPointBorderBrush;
  325. Pen PointPen = drawParam.PDFEditMultiPointPen;
  326. GetPointBrushAndPen(ref PointBrush, ref PointPen);
  327. switch (currentDrawMoveType)
  328. {
  329. case DrawMoveType.kDefault:
  330. break;
  331. case DrawMoveType.kReferenceLine:
  332. if (isMouseDown == true)
  333. {
  334. SolidColorBrush moveBrush = drawParam.PDFEditMultiMoveBrush;
  335. Pen movepen = drawParam.PDFEditMultiMovePen;
  336. GetMoveBrushAndPen(ref moveBrush, ref movepen);
  337. if (selectedType == SelectedType.PDFEdit)
  338. {
  339. DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect, drawParam.PDFEditMultiMoveRectPen);
  340. }
  341. else
  342. {
  343. DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect);
  344. }
  345. }
  346. drawDC?.DrawRectangle(solidColorBrush, pen, drawDefaultRect);
  347. break;
  348. default:
  349. break;
  350. }
  351. switch (currentDrawPointType)
  352. {
  353. case DrawPointType.Circle:
  354. if (selectedType == SelectedType.PDFEdit)
  355. {
  356. //Edit Settings Frame
  357. DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, new SolidColorBrush(Color.FromRgb(71, 126, 222)));
  358. }
  359. else
  360. {
  361. DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  362. }
  363. break;
  364. case DrawPointType.Square:
  365. DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
  366. break;
  367. }
  368. drawDC?.Close();
  369. drawDC = null;
  370. }
  371. });
  372. break;
  373. case MulitiDrawMoveType.Alone:
  374. CalcControlPoint(drawDefaultRect);
  375. foreach (SelectedRect selectRect in selectedRects)
  376. {
  377. selectRect.Draw();
  378. }
  379. break;
  380. default:
  381. break;
  382. }
  383. }
  384. private void GetMoveBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  385. {
  386. switch (selectedType)
  387. {
  388. case SelectedType.None:
  389. break;
  390. case SelectedType.Annot:
  391. //colorBrush = DrawParam.AnnotMoveBrush;
  392. //pen = DrawParam.AnnotMovePen;
  393. break;
  394. case SelectedType.PDFEdit:
  395. colorBrush = drawParam.PDFEditMultiMoveBrush;
  396. pen = drawParam.PDFEditMultiMovePen;
  397. break;
  398. default:
  399. break;
  400. }
  401. }
  402. private void GetBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  403. {
  404. switch (selectedType)
  405. {
  406. case SelectedType.None:
  407. break;
  408. case SelectedType.Annot:
  409. //if (isHover)
  410. //{
  411. // colorBrush = DrawParam.AnnotRectFillBrush;
  412. // pen = DrawParam.AnnotRectHoverPen;
  413. //}
  414. //else
  415. //{
  416. // colorBrush = DrawParam.AnnotRectFillBrush;
  417. // pen = DrawParam.AnnotRectLinePen;
  418. //}
  419. break;
  420. case SelectedType.PDFEdit:
  421. if (isHover)
  422. {
  423. colorBrush = drawParam.PDFEditMultiRectFillHoverBrush;
  424. pen = drawParam.PDFEditMultiRectLineHoverPen;
  425. }
  426. else
  427. {
  428. if (isSelected)
  429. {
  430. colorBrush = drawParam.SPDFEditMultiRectFillBrush;
  431. pen = drawParam.SPDFEditMultiRectLinePen;
  432. }
  433. else
  434. {
  435. colorBrush = drawParam.PDFEditMultiRectFillBrush;
  436. pen = drawParam.PDFEditMultiRectLinePen;
  437. }
  438. }
  439. break;
  440. default:
  441. break;
  442. }
  443. }
  444. private void GetPointBrushAndPen(ref SolidColorBrush colorBrush, ref Pen pen)
  445. {
  446. switch (selectedType)
  447. {
  448. case SelectedType.None:
  449. break;
  450. case SelectedType.Annot:
  451. //colorBrush = DrawParam.AnnotPointBorderBrush;
  452. //pen = DrawParam.AnnotPointPen;
  453. break;
  454. case SelectedType.PDFEdit:
  455. if (isHover)
  456. {
  457. colorBrush = drawParam.PDFEditMultiRectFillHoverBrush;
  458. pen = drawParam.PDFEditMultiPointHoverPen;
  459. }
  460. else
  461. {
  462. if (isSelected)
  463. {
  464. colorBrush = drawParam.SPDFEditMultiPointBorderBrush;
  465. pen = drawParam.SPDFEditMultiPointPen;
  466. }
  467. else
  468. {
  469. colorBrush = drawParam.PDFEditMultiPointBorderBrush;
  470. pen = drawParam.PDFEditMultiPointPen;
  471. }
  472. }
  473. break;
  474. default:
  475. break;
  476. }
  477. }
  478. /// <summary>
  479. /// Internal drawing circle point
  480. /// </summary>
  481. /// <param name="drawingContext">
  482. /// Drawing context
  483. /// </param>
  484. /// <param name="ignoreList">
  485. ///Collection of positions where points need to be drawn
  486. /// </param>
  487. /// <param name="PointSize">
  488. /// Point size
  489. /// </param>
  490. /// <param name="PointPen">
  491. /// Drawing point brush
  492. /// </param>
  493. /// <param name="BorderBrush">
  494. /// Brush for drawing point border
  495. /// </param>
  496. protected void DrawCirclePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  497. {
  498. GeometryGroup controlGroup = new GeometryGroup();
  499. controlGroup.FillRule = FillRule.Nonzero;
  500. List<Point> ignorePointsList = new List<Point>();
  501. // Get specific points
  502. foreach (PointControlType type in ignoreList)
  503. {
  504. if ((int)type < controlPoints.Count)
  505. {
  506. ignorePointsList.Add(controlPoints[(int)type]);
  507. }
  508. }
  509. for (int i = 0; i < controlPoints.Count; i++)
  510. {
  511. Point controlPoint = controlPoints[i];
  512. if (ignorePointsList.Contains(controlPoint))
  513. {
  514. continue;
  515. }
  516. EllipseGeometry circlPoint = new EllipseGeometry(controlPoint, PointSize, PointSize);
  517. controlGroup.Children.Add(circlPoint);
  518. }
  519. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  520. }
  521. /// <summary>
  522. /// Internal drawing square
  523. /// </summary>
  524. /// <param name="drawingContext">
  525. /// Drawing context
  526. /// </param>
  527. /// <param name="ControlPoints">
  528. /// Collection of positions where points need to be drawn
  529. /// </param>
  530. /// <param name="PointSize">
  531. /// Size of the point
  532. /// </param>
  533. /// <param name="PointPen">
  534. /// Brush for drawing point
  535. /// </param>
  536. /// <param name="BorderBrush">
  537. /// Border brush for drawing points
  538. /// </param>
  539. protected void DrawSquarePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  540. {
  541. GeometryGroup controlGroup = new GeometryGroup();
  542. controlGroup.FillRule = FillRule.Nonzero;
  543. List<Point> ignorePointsList = new List<Point>();
  544. // Get specific points
  545. foreach (PointControlType type in ignoreList)
  546. {
  547. if ((int)type < controlPoints.Count)
  548. {
  549. ignorePointsList.Add(controlPoints[(int)type]);
  550. }
  551. }
  552. for (int i = 0; i < controlPoints.Count; i++)
  553. {
  554. Point controlPoint = controlPoints[i];
  555. if (ignorePointsList.Contains(controlPoint))
  556. {
  557. continue;
  558. }
  559. RectangleGeometry rectPoint = new RectangleGeometry(new Rect(controlPoint.X - PointSize, controlPoint.Y - PointSize,
  560. PointSize * 2, PointSize * 2), 1, 1);
  561. controlGroup.Children.Add(rectPoint);
  562. }
  563. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  564. }
  565. /// <summary>
  566. /// Draw the reference line in the moving state
  567. /// </summary>
  568. /// <param name="drawDc">
  569. /// Drawing context
  570. /// </param>
  571. /// <param name="controltype">
  572. /// Drawing context
  573. /// </param>
  574. /// <param name="activePen">
  575. /// Drawing context
  576. /// </param>
  577. /// <param name="moveBrush">
  578. /// Move brush
  579. /// </param>
  580. /// <param name="moveRect">
  581. /// Move rectangle
  582. /// </param>
  583. protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect, Pen RectPen = null)
  584. {
  585. switch (controltype)
  586. {
  587. case PointControlType.LeftTop:
  588. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  589. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  590. break;
  591. case PointControlType.LeftMiddle:
  592. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  593. break;
  594. case PointControlType.LeftBottom:
  595. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  596. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  597. break;
  598. case PointControlType.MiddlBottom:
  599. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  600. break;
  601. case PointControlType.RightBottom:
  602. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  603. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  604. break;
  605. case PointControlType.RightMiddle:
  606. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  607. break;
  608. case PointControlType.RightTop:
  609. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  610. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  611. break;
  612. case PointControlType.MiddleTop:
  613. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  614. break;
  615. case PointControlType.Rotate:
  616. break;
  617. case PointControlType.Body:
  618. case PointControlType.Line:
  619. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(moveRect.Left, moveRect.Top));
  620. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  621. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Top), new Point(moveRect.Left, 0));
  622. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(moveRect.Right, 0));
  623. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(moveRect.Left, moveRect.Bottom));
  624. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  625. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Bottom), new Point(moveRect.Left, PDFViewerActualHeight));
  626. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(moveRect.Right, PDFViewerActualHeight));
  627. break;
  628. default:
  629. break;
  630. }
  631. drawDc?.DrawRectangle(moveBrush, RectPen, moveRect);
  632. }
  633. public virtual void ClearDraw()
  634. {
  635. drawDefaultRect = setDrawRect = drawRect = new Rect();
  636. drawDC = RenderOpen();
  637. drawDC?.Close();
  638. drawDC = null;
  639. }
  640. /// <summary>
  641. /// Calculate the current control point
  642. /// </summary>
  643. /// <param name="currentRect">
  644. /// Target rectangle where the control point is located
  645. /// </param>
  646. protected void CalcControlPoint(Rect currentRect)
  647. {
  648. controlPoints.Clear();
  649. int centerX = (int)(currentRect.Left + currentRect.Right) / 2;
  650. int centerY = (int)(currentRect.Top + currentRect.Bottom) / 2;
  651. controlPoints.Add(new Point(currentRect.Left, currentRect.Top));
  652. controlPoints.Add(new Point(currentRect.Left, centerY));
  653. controlPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
  654. controlPoints.Add(new Point(centerX, currentRect.Bottom));
  655. controlPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
  656. controlPoints.Add(new Point(currentRect.Right, centerY));
  657. controlPoints.Add(new Point(currentRect.Right, currentRect.Top));
  658. controlPoints.Add(new Point(centerX, currentRect.Top));
  659. }
  660. /// <summary>
  661. /// Get the original set Rect, not the one that has been calculated for padding
  662. /// </summary>
  663. public Rect GetRect()
  664. {
  665. Rect rect = new Rect(drawRect.X + rectPadding, drawRect.Y + rectPadding, Math.Max(0, drawRect.Width - 2 * rectPadding), Math.Max(0, drawRect.Height - 2 * rectPadding));
  666. return rect;
  667. }
  668. public void SetRect(Rect newRect)
  669. {
  670. newRect = new Rect(newRect.X - rectPadding, newRect.Y - rectPadding, newRect.Width + 2 * rectPadding, newRect.Height + 2 * rectPadding);
  671. if (drawDefaultRect != new Rect())
  672. {
  673. newRect.Union(drawDefaultRect);
  674. newRect.Intersect(maxRect);
  675. }
  676. drawDefaultRect = newRect;
  677. setDrawRect = drawRect = newRect;
  678. }
  679. public void SetRectPadding(double rectPadding)
  680. {
  681. this.rectPadding = rectPadding;
  682. }
  683. public double GetRectPadding()
  684. {
  685. return rectPadding;
  686. }
  687. public Rect GetDrawRect()
  688. {
  689. return drawRect;
  690. }
  691. public void SetMaxRect(Rect rect)
  692. {
  693. maxRect = rect;
  694. }
  695. public Rect GetMaxRect()
  696. {
  697. return maxRect;
  698. }
  699. public void SetIsProportionalScaling(bool isProportionalScaling)
  700. {
  701. this.isProportionalScaling = isProportionalScaling;
  702. }
  703. public void SetDrawType(DrawPointType drawType)
  704. {
  705. currentDrawPointType = drawType;
  706. }
  707. public void SetDrawMoveType(DrawMoveType drawType)
  708. {
  709. currentDrawMoveType = drawType;
  710. }
  711. /// <summary>
  712. /// Set the type that needs to be ignored
  713. /// </summary>
  714. /// <param name="types">
  715. /// Collection of point types that need to be shielded
  716. /// </param>
  717. public void SetIgnorePoints(List<PointControlType> types)
  718. {
  719. ignorePoints.Clear();
  720. foreach (PointControlType type in types)
  721. {
  722. ignorePoints.Add(type);
  723. }
  724. }
  725. /// <summary>
  726. /// Set all points to be ignored
  727. /// </summary>
  728. public void SetIgnorePointsAll()
  729. {
  730. ignorePoints.Clear();
  731. ignorePoints.Add(PointControlType.LeftTop);
  732. ignorePoints.Add(PointControlType.LeftMiddle);
  733. ignorePoints.Add(PointControlType.LeftBottom);
  734. ignorePoints.Add(PointControlType.MiddlBottom);
  735. ignorePoints.Add(PointControlType.RightBottom);
  736. ignorePoints.Add(PointControlType.RightMiddle);
  737. ignorePoints.Add(PointControlType.RightTop);
  738. ignorePoints.Add(PointControlType.MiddleTop);
  739. }
  740. /// <summary>
  741. /// Disable all functions
  742. /// </summary>
  743. public void DisableAll()
  744. {
  745. ignorePoints.Clear();
  746. ignorePoints.Add(PointControlType.LeftTop);
  747. ignorePoints.Add(PointControlType.LeftMiddle);
  748. ignorePoints.Add(PointControlType.LeftBottom);
  749. ignorePoints.Add(PointControlType.MiddlBottom);
  750. ignorePoints.Add(PointControlType.RightBottom);
  751. ignorePoints.Add(PointControlType.RightMiddle);
  752. ignorePoints.Add(PointControlType.RightTop);
  753. ignorePoints.Add(PointControlType.MiddleTop);
  754. ignorePoints.Add(PointControlType.Rotate);
  755. ignorePoints.Add(PointControlType.Body);
  756. ignorePoints.Add(PointControlType.Line);
  757. }
  758. /// <summary>
  759. /// Calculate the movement of the hit point
  760. /// </summary>
  761. /// <param name="mousePoint">
  762. /// Current mouse position
  763. /// </param>
  764. /// <returns></returns>
  765. protected bool CalcHitPointMove(Point mousePoint)
  766. {
  767. if (isMouseDown == false || hitControlType == PointControlType.None)
  768. {
  769. return false;
  770. }
  771. return NormalScaling(mousePoint);
  772. }
  773. /// <summary>
  774. /// Draw the algorithm of the normal scaling form (drag a point, only scale in one direction)
  775. /// </summary>
  776. /// <param name="mousePoint">
  777. /// Current mouse position
  778. /// </param>
  779. /// <returns></returns>
  780. protected bool NormalScaling(Point mousePoint)
  781. {
  782. double mLeft = cacheRect.Left;
  783. double mRight = cacheRect.Right;
  784. double mUp = cacheRect.Top;
  785. double mDown = cacheRect.Bottom;
  786. double TmpLeft = mLeft, TmpRight = mRight, TmpUp = mUp, TmpDown = mDown;
  787. Point centerPoint = new Point((cacheRect.Right + cacheRect.Left) / 2, (cacheRect.Bottom + cacheRect.Top) / 2);
  788. Point moveVector = (Point)(mousePoint - centerPoint);
  789. moveVector = ProportionalScalingOffsetPos(moveVector);
  790. switch (hitControlType)
  791. {
  792. case PointControlType.LeftTop:
  793. TmpLeft = centerPoint.X + moveVector.X;
  794. TmpRight = cacheRect.Right;
  795. if (TmpLeft + rectMinWidth > TmpRight)
  796. {
  797. TmpLeft = TmpRight - rectMinWidth;
  798. }
  799. TmpUp = centerPoint.Y + moveVector.Y;
  800. TmpDown = cacheRect.Bottom;
  801. if (TmpUp + rectMinHeight > TmpDown)
  802. {
  803. TmpUp = TmpDown - rectMinHeight;
  804. }
  805. break;
  806. case PointControlType.LeftMiddle:
  807. TmpLeft = centerPoint.X + moveVector.X;
  808. TmpRight = cacheRect.Right;
  809. if (TmpLeft + rectMinWidth > TmpRight)
  810. {
  811. TmpLeft = TmpRight - rectMinWidth;
  812. }
  813. TmpUp = cacheRect.Top;
  814. TmpDown = cacheRect.Bottom;
  815. break;
  816. case PointControlType.LeftBottom:
  817. TmpLeft = centerPoint.X + moveVector.X;
  818. TmpRight = cacheRect.Right;
  819. if (TmpLeft + rectMinWidth > TmpRight)
  820. {
  821. TmpLeft = TmpRight - rectMinWidth;
  822. }
  823. TmpUp = cacheRect.Top;
  824. TmpDown = centerPoint.Y + moveVector.Y;
  825. if (TmpUp + rectMinHeight > TmpDown)
  826. {
  827. TmpDown = TmpUp + rectMinHeight;
  828. }
  829. break;
  830. case PointControlType.MiddlBottom:
  831. TmpLeft = cacheRect.Left;
  832. TmpRight = cacheRect.Right;
  833. TmpUp = cacheRect.Top;
  834. TmpDown = centerPoint.Y + moveVector.Y;
  835. if (TmpUp + rectMinHeight > TmpDown)
  836. {
  837. TmpDown = TmpUp + rectMinHeight;
  838. }
  839. break;
  840. case PointControlType.RightBottom:
  841. TmpLeft = cacheRect.Left;
  842. TmpRight = centerPoint.X + moveVector.X;
  843. if (TmpLeft + rectMinWidth > TmpRight)
  844. {
  845. TmpRight = TmpLeft + rectMinWidth;
  846. }
  847. TmpUp = cacheRect.Top;
  848. TmpDown = centerPoint.Y + moveVector.Y;
  849. if (TmpUp + rectMinHeight > TmpDown)
  850. {
  851. TmpDown = TmpUp + rectMinHeight;
  852. }
  853. break;
  854. case PointControlType.RightMiddle:
  855. TmpLeft = cacheRect.Left;
  856. TmpRight = centerPoint.X + moveVector.X;
  857. if (TmpLeft + rectMinWidth > TmpRight)
  858. {
  859. TmpRight = TmpLeft + rectMinWidth;
  860. }
  861. TmpUp = cacheRect.Top;
  862. TmpDown = cacheRect.Bottom;
  863. break;
  864. case PointControlType.RightTop:
  865. TmpLeft = cacheRect.Left;
  866. TmpRight = centerPoint.X + moveVector.X;
  867. if (TmpLeft + rectMinWidth > TmpRight)
  868. {
  869. TmpRight = TmpLeft + rectMinWidth;
  870. }
  871. TmpUp = centerPoint.Y + moveVector.Y;
  872. TmpDown = cacheRect.Bottom;
  873. if (TmpUp + rectMinHeight > TmpDown)
  874. {
  875. TmpUp = TmpDown - rectMinHeight;
  876. }
  877. break;
  878. case PointControlType.MiddleTop:
  879. TmpLeft = cacheRect.Left;
  880. TmpRight = cacheRect.Right;
  881. TmpUp = centerPoint.Y + moveVector.Y;
  882. TmpDown = cacheRect.Bottom;
  883. if (TmpUp + rectMinHeight > TmpDown)
  884. {
  885. TmpUp = TmpDown - rectMinHeight;
  886. }
  887. break;
  888. case PointControlType.Body:
  889. case PointControlType.Line:
  890. Point OffsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), maxRect);
  891. TmpLeft = cacheRect.Left + OffsetPos.X;
  892. TmpRight = cacheRect.Right + OffsetPos.X;
  893. TmpUp = cacheRect.Top + OffsetPos.Y;
  894. TmpDown = cacheRect.Bottom + OffsetPos.Y;
  895. break;
  896. default:
  897. break;
  898. }
  899. if (TmpLeft < maxRect.Left)
  900. {
  901. TmpLeft = maxRect.Left;
  902. }
  903. if (TmpUp < maxRect.Top)
  904. {
  905. TmpUp = maxRect.Top;
  906. }
  907. if (TmpRight > maxRect.Right)
  908. {
  909. TmpRight = maxRect.Right;
  910. }
  911. if (TmpDown > maxRect.Bottom)
  912. {
  913. TmpDown = maxRect.Bottom;
  914. }
  915. if (TmpRight - TmpLeft < 0.0 || TmpDown - TmpUp < 0.0)
  916. {
  917. return false;
  918. }
  919. drawRect = new Rect(TmpLeft, TmpUp, TmpRight - TmpLeft, TmpDown - TmpUp);
  920. moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
  921. return true;
  922. }
  923. /// <summary>
  924. /// Proportional scaling offset calibration
  925. /// </summary>
  926. /// <param name="movePoint">
  927. /// Offset value
  928. /// </param>
  929. /// <returns>
  930. /// Offset value after calibration
  931. /// </returns>
  932. protected Point ProportionalScalingOffsetPos(Point movePoint)
  933. {
  934. if (isProportionalScaling)
  935. {
  936. Point offsetPos = movePoint;
  937. double ratioX = cacheRect.Width > 0 ? cacheRect.Height / cacheRect.Width : 1;
  938. double ratioY = cacheRect.Height > 0 ? cacheRect.Width / cacheRect.Height : 1;
  939. switch (hitControlType)
  940. {
  941. case PointControlType.LeftTop:
  942. case PointControlType.RightBottom:
  943. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  944. break;
  945. case PointControlType.LeftBottom:
  946. case PointControlType.RightTop:
  947. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  948. break;
  949. case PointControlType.LeftMiddle:
  950. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  951. break;
  952. case PointControlType.RightMiddle:
  953. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  954. break;
  955. case PointControlType.MiddlBottom:
  956. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? 1 : -1), movePoint.Y);
  957. break;
  958. case PointControlType.MiddleTop:
  959. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? -1 : 1), movePoint.Y);
  960. break;
  961. default:
  962. break;
  963. }
  964. return offsetPos;
  965. }
  966. else
  967. {
  968. return movePoint;
  969. }
  970. }
  971. /// <summary>
  972. /// Set left alignment within the set maximum rectangle
  973. /// </summary>
  974. public virtual void SetAlignLeftForMaxRect()
  975. {
  976. DrawAlignRect(AlignmentsHelp.SetAlignLeft(drawRect, maxRect));
  977. }
  978. /// <summary>
  979. /// Set horizontal center alignment within the set maximum rectangle
  980. /// </summary>
  981. public virtual void SetAlignHorizonCenterForMaxRect()
  982. {
  983. DrawAlignRect(AlignmentsHelp.SetAlignHorizonCenter(drawRect, maxRect));
  984. }
  985. /// <summary>
  986. /// Set right alignment within the set maximum rectangle
  987. /// </summary>
  988. public virtual void SetAlignRightForMaxRect()
  989. {
  990. DrawAlignRect(AlignmentsHelp.SetAlignRight(drawRect, maxRect));
  991. }
  992. /// <summary>
  993. /// Set top alignment within the set maximum rectangle
  994. /// </summary>
  995. public virtual void SetAlignTopForMaxRect()
  996. {
  997. DrawAlignRect(AlignmentsHelp.SetAlignTop(drawRect, maxRect));
  998. }
  999. /// <summary>
  1000. /// Set vertical center alignment within the set maximum rectangle
  1001. /// </summary>
  1002. public virtual void SetAlignVerticalCenterForMaxRect()
  1003. {
  1004. DrawAlignRect(AlignmentsHelp.SetAlignVerticalCenter(drawRect, maxRect));
  1005. }
  1006. /// <summary>
  1007. /// Set Align center within the set maximum rectangle
  1008. /// </summary>
  1009. public virtual void SetAlignHorizonVerticalCenterForMaxRect()
  1010. {
  1011. DrawAlignRect(AlignmentsHelp.SetAlignHorizonVerticalCenter(drawRect, maxRect));
  1012. }
  1013. /// <summary>
  1014. /// Set bottom alignment within the set maximum rectangle
  1015. /// </summary>
  1016. public virtual void SetAlignBottomForMaxRect()
  1017. {
  1018. DrawAlignRect(AlignmentsHelp.SetAlignBottom(drawRect, maxRect));
  1019. }
  1020. /// <summary>
  1021. /// Draw the rectangle of the alignment function
  1022. /// </summary>
  1023. /// <param name="RectMovePoint">
  1024. /// Move distance required for the rectangle obtained by the alignment algorithm
  1025. /// </param>
  1026. private void DrawAlignRect(Point RectMovePoint)
  1027. {
  1028. double TmpLeft, TmpRight, TmpUp, TmpDown;
  1029. Point OffsetPos = CalcMoveBound(drawRect, RectMovePoint, maxRect);
  1030. TmpLeft = drawRect.Left + OffsetPos.X;
  1031. TmpRight = drawRect.Right + OffsetPos.X;
  1032. TmpUp = drawRect.Top + OffsetPos.Y;
  1033. TmpDown = drawRect.Bottom + OffsetPos.Y;
  1034. setDrawRect = drawRect = new Rect(TmpLeft, TmpUp, TmpRight - TmpLeft, TmpDown - TmpUp);
  1035. Draw();
  1036. }
  1037. /// <summary>
  1038. /// Calculate the offset of the current rectangle within the maximum rectangle range
  1039. /// </summary>
  1040. /// <param name="currentRect">
  1041. /// The rectangle cached when pressed
  1042. /// </param>
  1043. /// <param name="offsetPoint">
  1044. /// The offset value equivalent to when pressed
  1045. /// </param>
  1046. /// <param name="maxRect">
  1047. /// The maximum rectangle range
  1048. /// </param>
  1049. /// <returns>
  1050. /// Offset value after calculation
  1051. /// </returns>
  1052. protected Point CalcMoveBound(Rect currentRect, Point offsetPoint, Rect maxRect)
  1053. {
  1054. double cLeft = currentRect.Left;
  1055. double cRight = currentRect.Right;
  1056. double cUp = currentRect.Top;
  1057. double cDown = currentRect.Bottom;
  1058. double TmpLeft = cLeft + offsetPoint.X;
  1059. double TmpRight = cRight + offsetPoint.X;
  1060. double TmpUp = cUp + offsetPoint.Y;
  1061. double TmpDown = cDown + offsetPoint.Y;
  1062. if (TmpLeft < maxRect.Left)
  1063. {
  1064. TmpRight = (cRight - cLeft) + maxRect.Left;
  1065. TmpLeft = maxRect.Left;
  1066. }
  1067. if (TmpUp < maxRect.Top)
  1068. {
  1069. TmpDown = (cDown - cUp) + maxRect.Top;
  1070. TmpUp = maxRect.Top;
  1071. }
  1072. if (TmpRight > maxRect.Right)
  1073. {
  1074. TmpLeft = maxRect.Right - (cRight - cLeft);
  1075. TmpRight = maxRect.Right;
  1076. }
  1077. if (TmpDown > maxRect.Bottom)
  1078. {
  1079. TmpUp = maxRect.Bottom - (cDown - cUp);
  1080. TmpDown = maxRect.Bottom;
  1081. }
  1082. offsetPoint = new Point(TmpLeft - cLeft, TmpUp - cUp);
  1083. return offsetPoint;
  1084. }
  1085. /// <summary>
  1086. /// Used for notification events during the drawing data process/completion.
  1087. /// </summary>
  1088. /// <param name="isFinish">
  1089. /// Identifies whether the data has been changed
  1090. /// </param>
  1091. protected void InvokeDataChangEvent(bool isFinish)
  1092. {
  1093. if (isFinish)
  1094. {
  1095. DataChanged?.Invoke(this, moveOffset);
  1096. }
  1097. else
  1098. {
  1099. DataChanging?.Invoke(this, moveOffset);
  1100. }
  1101. }
  1102. /// <summary>
  1103. /// Get the current set of ignored points
  1104. /// </summary>
  1105. /// <returns>
  1106. /// Dataset of ignored points
  1107. /// </returns>
  1108. private List<PointControlType> GetIgnorePoints()
  1109. {
  1110. List<PointControlType> IgnorePointsList = new List<PointControlType>();
  1111. foreach (PointControlType type in ignorePoints)
  1112. {
  1113. IgnorePointsList.Add(type);
  1114. }
  1115. return IgnorePointsList;
  1116. }
  1117. /// <summary>
  1118. /// Get which control point the coordinate is on
  1119. /// </summary>
  1120. /// <param name="clickPoint">
  1121. /// Coordinate point
  1122. /// </param>
  1123. /// <returns>
  1124. /// Control point type
  1125. /// </returns>
  1126. public PointControlType GetHitControlIndex(Point point)
  1127. {
  1128. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  1129. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  1130. {
  1131. List<PointControlType> ignoreList = GetIgnorePoints();
  1132. List<Point> IgnorePointsList = new List<Point>();
  1133. foreach (PointControlType type in ignoreList)
  1134. {
  1135. if ((int)type < controlPoints.Count)
  1136. {
  1137. IgnorePointsList.Add(controlPoints[(int)type]);
  1138. }
  1139. }
  1140. for (int i = 0; i < controlPoints.Count; i++)
  1141. {
  1142. Point checkPoint = controlPoints[i];
  1143. if (IgnorePointsList.Contains(checkPoint))
  1144. {
  1145. continue;
  1146. }
  1147. switch (currentDrawPointType)
  1148. {
  1149. case DrawPointType.Circle:
  1150. Vector checkVector = checkPoint - point;
  1151. if (checkVector.Length < pointSize)
  1152. {
  1153. return (PointControlType)i;
  1154. }
  1155. break;
  1156. case DrawPointType.Square:
  1157. Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
  1158. if (checkRect.Contains(point))
  1159. {
  1160. return (PointControlType)i;
  1161. }
  1162. break;
  1163. default:
  1164. break;
  1165. }
  1166. }
  1167. Rect defrect = drawRect;
  1168. defrect.X -= rectPadding;
  1169. defrect.Y -= rectPadding;
  1170. defrect.Width += rectPadding;
  1171. defrect.Height += rectPadding;
  1172. if (drawRect.Contains(point))
  1173. {
  1174. Rect rect = new Rect(
  1175. Math.Max(drawRect.X + rectPadding, 0),
  1176. Math.Max(drawRect.Y + rectPadding, 0),
  1177. drawRect.Width - 2 * rectPadding,
  1178. drawRect.Height - 2 * rectPadding);
  1179. if (rect.Contains(point))
  1180. {
  1181. if (!ignoreList.Contains(PointControlType.Body))
  1182. {
  1183. return PointControlType.Body;
  1184. }
  1185. }
  1186. if (!ignoreList.Contains(PointControlType.Body))
  1187. {
  1188. return PointControlType.Line;
  1189. }
  1190. }
  1191. }
  1192. return PointControlType.None;
  1193. }
  1194. /// <summary>
  1195. /// Get the rectangle where the current point is located
  1196. /// </summary>
  1197. /// <param name="clickPoint">
  1198. /// Coordinate point
  1199. /// </param>
  1200. /// <returns>
  1201. /// Control point type
  1202. /// </returns>
  1203. public SelectedRect GetHitControlRect(Point point)
  1204. {
  1205. HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  1206. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  1207. {
  1208. foreach (SelectedRect selectedRect in selectedRects) {
  1209. Rect defrect = selectedRect.GetRect();
  1210. defrect.X -= rectPadding;
  1211. defrect.Y -= rectPadding;
  1212. defrect.Width += rectPadding;
  1213. defrect.Height += rectPadding;
  1214. if (defrect.Contains(point))
  1215. {
  1216. Rect rect = new Rect(
  1217. Math.Max(defrect.X + rectPadding, 0),
  1218. Math.Max(defrect.Y + rectPadding, 0),
  1219. defrect.Width - 2 * rectPadding,
  1220. defrect.Height - 2 * rectPadding);
  1221. if (rect.Contains(point))
  1222. {
  1223. return selectedRect;
  1224. }
  1225. }
  1226. }
  1227. }
  1228. return null;
  1229. }
  1230. }
  1231. }