MultiSelectedRect.cs 53 KB

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