DrawPolygonLine.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. using PaintDotNet.Annotation.Enum;
  2. using PaintDotNet.Base.SettingModel;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Globalization;
  8. using System.Windows.Forms;
  9. namespace PaintDotNet.Annotation.Label
  10. {
  11. using PointList = List<PointF>;
  12. /// <summary>
  13. /// 标注->曲线->折线
  14. /// </summary>
  15. public class DrawPolygonLine : DrawObject
  16. {
  17. /// <summary>
  18. /// 鼠标形状
  19. /// </summary>
  20. private static Cursor handleCursor = new Cursor(PdnResources.GetResourceStream("Cursors.AnnotationPolyHandle.cur"));
  21. /// <summary>
  22. /// 点集合
  23. /// </summary>
  24. public PointList pointArray;
  25. /// <summary>
  26. /// Graphic objects for hit test
  27. /// </summary>
  28. private GraphicsPath areaPath = null;
  29. private Pen areaPen = null;
  30. private Region areaRegion = null;
  31. /// <summary>
  32. /// 标注样式信息model
  33. /// </summary>
  34. private LabelStyleModel.Polyline labelPolylineStyleModel;
  35. public LabelStyleModel.Polyline LabelPolylineStyleModel
  36. {
  37. set
  38. {
  39. this.labelPolylineStyleModel = value;
  40. }
  41. }
  42. public DrawPolygonLine() : base()
  43. {
  44. this.objectType = DrawClass.Label;
  45. this.drawToolType = DrawToolType.DrawPolygonLine;
  46. pointArray = new PointList();
  47. Initialize();
  48. }
  49. public DrawPolygonLine(ISurfaceBox surfaceBox, int x1, int y1) : base()
  50. {
  51. this.objectType = DrawClass.Label;
  52. this.drawToolType = DrawToolType.DrawPolygonLine;
  53. labelPolylineStyleModel = surfaceBox.GetLabelStyleModel().polylineModel;
  54. pointArray = new PointList();
  55. startPoint.X = x1;
  56. startPoint.Y = y1;
  57. endPoint.X = x1 + 1;
  58. endPoint.Y = y1 + 1;
  59. pointArray.Add(new PointF(x1, y1));
  60. pointArray.Add(new PointF(x1 + 1, y1 + 1));
  61. Initialize();
  62. }
  63. public DrawPolygonLine(ISurfaceBox surfaceBox, List<PointF> points, ParentStyleModel parentStyleModel, Object content) : base()
  64. {
  65. this.objectType = DrawClass.Label;
  66. this.drawToolType = DrawToolType.DrawPolygonLine;
  67. this.ISurfaceBox = surfaceBox;
  68. labelPolylineStyleModel = (LabelStyleModel.Polyline)parentStyleModel;
  69. pointArray = points;
  70. startPoint = points[points.Count - 2];
  71. endPoint = points[points.Count - 1];
  72. }
  73. /// <summary>
  74. /// Clone this instance
  75. /// </summary>
  76. public override DrawObject Clone()
  77. {
  78. DrawPolygonLine drawPolygon = new DrawPolygonLine(ISurfaceBox, 0, 0);
  79. drawPolygon.objectType = DrawClass.Label;
  80. drawPolygon.drawToolType = DrawToolType.DrawPolygonLine;
  81. drawPolygon.ISurfaceBox = this.ISurfaceBox;
  82. drawPolygon.pointArray.Clear();
  83. foreach (PointF p in this.pointArray)
  84. {
  85. drawPolygon.pointArray.Add(p);
  86. }
  87. drawPolygon.startPoint = this.startPoint;
  88. drawPolygon.endPoint = this.endPoint;
  89. drawPolygon.labelPolylineStyleModel = this.labelPolylineStyleModel;
  90. FillDrawObjectFields(drawPolygon);
  91. return drawPolygon;
  92. }
  93. public override DrawObject Clone(ISurfaceBox surfaceBox)
  94. {
  95. DrawPolygonLine drawPolygon = new DrawPolygonLine(surfaceBox, 0, 0);
  96. drawPolygon.objectType = DrawClass.Label;
  97. drawPolygon.drawToolType = DrawToolType.DrawPolygonLine;
  98. drawPolygon.ISurfaceBox = surfaceBox;
  99. drawPolygon.pointArray.Clear();
  100. foreach (PointF p in this.pointArray)
  101. {
  102. drawPolygon.pointArray.Add(p);
  103. }
  104. drawPolygon.startPoint = this.startPoint;
  105. drawPolygon.endPoint = this.endPoint;
  106. drawPolygon.labelPolylineStyleModel = this.labelPolylineStyleModel;
  107. FillDrawObjectFields(drawPolygon);
  108. return drawPolygon;
  109. }
  110. public override void Draw(Graphics g)
  111. {
  112. /**
  113. int x1 = 0, y1 = 0; // previous pointscroll
  114. int x2, y2; // current pointscroll
  115. g.SmoothingMode = SmoothingMode.AntiAlias;
  116. Pen pen = new Pen(Color, PenWidth);
  117. PointEnumerator enumerator = pointArray.GetEnumerator();
  118. if (enumerator.MoveNext())
  119. {
  120. x1 = ((Point)enumerator.Current).X;
  121. y1 = ((Point)enumerator.Current).Y;
  122. }
  123. while (enumerator.MoveNext())
  124. {
  125. x2 = ((Point)enumerator.Current).X;
  126. y2 = ((Point)enumerator.Current).Y;
  127. g.DrawLine(pen, x1, y1, x2, y2);
  128. x1 = x2;
  129. y1 = y2;
  130. }
  131. pen.Dispose();
  132. **/
  133. if (HandleCount >= 2)
  134. {
  135. g.SmoothingMode = SmoothingMode.AntiAlias;
  136. Color color = Color.FromArgb(labelPolylineStyleModel.lineColor);
  137. int lineWidth = labelPolylineStyleModel.lineWidth;
  138. Pen pen = new Pen(color, lineWidth);
  139. pen.DashStyle = (DashStyle)this.labelPolylineStyleModel.lineStyle;
  140. g.DrawLines(pen, pointArray.ToArray()); //.DrawLine(pen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
  141. pen.Dispose();
  142. }
  143. }
  144. public void AddPoint(PointF point)
  145. {
  146. pointArray.Add(point);
  147. }
  148. public override int HandleCount
  149. {
  150. get
  151. {
  152. return pointArray.Count;
  153. }
  154. }
  155. /// <summary>
  156. /// Get handle pointscroll by 1-based number
  157. /// </summary>
  158. /// <param name="handleNumber"></param>
  159. /// <returns></returns>
  160. public override PointF GetHandle(int handleNumber)
  161. {
  162. if (handleNumber < 1)
  163. handleNumber = 1;
  164. if (handleNumber > pointArray.Count)
  165. handleNumber = pointArray.Count;
  166. return pointArray[handleNumber - 1];
  167. }
  168. public override Cursor GetHandleCursor(int handleNumber)
  169. {
  170. return handleCursor;
  171. }
  172. public override void MoveHandleTo(Point point, int handleNumber)
  173. {
  174. if (handleNumber < 1)
  175. handleNumber = 1;
  176. if (handleNumber > pointArray.Count)
  177. handleNumber = pointArray.Count;
  178. pointArray[handleNumber - 1] = point;
  179. Invalidate();
  180. }
  181. public override void Move(int deltaX, int deltaY)
  182. {
  183. int n = pointArray.Count;
  184. PointF point;
  185. for (int i = 0; i < n; i++)
  186. {
  187. point = new PointF(pointArray[i].X + ISurfaceBox.UnscaleScalar(deltaX), pointArray[i].Y + ISurfaceBox.UnscaleScalar(deltaY));
  188. pointArray[i] = point;
  189. }
  190. Invalidate();
  191. }
  192. /// <summary>
  193. /// 用于创建一个路径或者是闭合的范围
  194. /// 用于响应点击选中
  195. /// 需要咨询用户是仅点击线还是矩形选择
  196. /// </summary>
  197. protected virtual void CreateObjects()
  198. {
  199. if (AreaPath != null)
  200. return;
  201. AreaPath = new GraphicsPath();
  202. AreaPath.AddRectangle(GetBoundingBox());
  203. AreaPath.CloseFigure();
  204. AreaRegion = new Region(AreaPath);
  205. }
  206. /// <summary>
  207. /// Invalidate object.
  208. /// When object is invalidated, path used for hit test
  209. /// is released and should be created again.
  210. /// </summary>
  211. protected void Invalidate()
  212. {
  213. if (AreaPath != null)
  214. {
  215. AreaPath.Dispose();
  216. AreaPath = null;
  217. }
  218. if (AreaPen != null)
  219. {
  220. AreaPen.Dispose();
  221. AreaPen = null;
  222. }
  223. if (AreaRegion != null)
  224. {
  225. AreaRegion.Dispose();
  226. AreaRegion = null;
  227. }
  228. }
  229. protected GraphicsPath AreaPath
  230. {
  231. get
  232. {
  233. return areaPath;
  234. }
  235. set
  236. {
  237. areaPath = value;
  238. }
  239. }
  240. protected Pen AreaPen
  241. {
  242. get
  243. {
  244. return areaPen;
  245. }
  246. set
  247. {
  248. areaPen = value;
  249. }
  250. }
  251. protected Region AreaRegion
  252. {
  253. get
  254. {
  255. return areaRegion;
  256. }
  257. set
  258. {
  259. areaRegion = value;
  260. }
  261. }
  262. /// <summary>
  263. /// Draw tracker for selected object
  264. /// </summary>
  265. /// <param name="g"></param>
  266. public override void DrawTracker(Graphics g)
  267. {
  268. if (!Selected)
  269. return;
  270. SolidBrush brush = new SolidBrush(Color.FromArgb(MarkpointAreaColor));
  271. Pen pen = new Pen(Color.FromArgb(MarkpointLineColor), MarkpointLineWidth);
  272. for (int i = 1; i <= HandleCount; i++)
  273. {
  274. switch (MarkpointStyle)
  275. {
  276. case 0:
  277. g.FillRectangle(brush, GetHandleRectangle(i));
  278. g.DrawRectangle(pen, GetHandleRectangle(i));
  279. break;
  280. case 1:
  281. g.FillEllipse(brush, GetHandleRectangle(i));
  282. g.DrawEllipse(pen, GetHandleRectangle(i));
  283. break;
  284. case 2:
  285. g.FillPolygon(brush, GetHandlePoint(i));
  286. g.DrawPolygon(pen, GetHandlePoint(i));
  287. break;
  288. }
  289. }
  290. brush.Dispose();
  291. pen.Dispose();
  292. RectangleF rectangleF = GetBoundingBox();
  293. g.DrawRectangle(new Pen(Color.White), rectangleF.X, rectangleF.Y, rectangleF.Width, rectangleF.Height);
  294. }
  295. /// <summary>
  296. /// Hit test.
  297. /// Return value: -1 - no hit
  298. /// 0 - hit anywhere
  299. /// > 1 - handle number
  300. /// </summary>
  301. /// <param name="pointscroll"></param>
  302. /// <returns></returns>
  303. public override int HitTest(Point point)
  304. {
  305. if (Selected)
  306. {
  307. for (int i = 1; i <= HandleCount; i++)
  308. {
  309. if (GetHandleRectangle(i).Contains(point))
  310. return i;
  311. }
  312. }
  313. if (PointInObject(point))
  314. return 0;
  315. return -1;
  316. }
  317. protected override bool PointInObject(Point point)
  318. {
  319. CreateObjects();
  320. return AreaRegion.IsVisible(point);
  321. }
  322. public override bool IntersectsWith(Rectangle rectangle)
  323. {
  324. CreateObjects();
  325. return AreaRegion.IsVisible(rectangle);
  326. }
  327. public override RectangleF GetBoundingBox()
  328. {
  329. RectangleF rectangle;
  330. float minx = 0, maxx = 0, miny = 0, maxy = 0;
  331. for (int i = 0; i < pointArray.Count; i++)
  332. {
  333. if (i == 0)
  334. {
  335. minx = maxx = pointArray[i].X;
  336. miny = maxy = pointArray[i].Y;
  337. }
  338. else
  339. {
  340. if (pointArray[i].X > maxx) maxx = pointArray[i].X;
  341. if (pointArray[i].X < minx) minx = pointArray[i].X;
  342. if (pointArray[i].Y > maxy) maxy = pointArray[i].Y;
  343. if (pointArray[i].Y < miny) miny = pointArray[i].Y;
  344. }
  345. }
  346. rectangle = new RectangleF(minx, miny, maxx - minx, maxy - miny);
  347. return rectangle;
  348. }
  349. internal void setNextPoint(PointF p)
  350. {
  351. AddPoint(p);
  352. startPoint = endPoint;
  353. endPoint = p;
  354. }
  355. internal void setEndPoint(PointF p)
  356. {
  357. endPoint = p;
  358. }
  359. public override List<PointF> GetPoints()
  360. {
  361. return pointArray;
  362. }
  363. public override ParentStyleModel GetStyle()
  364. {
  365. return labelPolylineStyleModel;
  366. }
  367. }
  368. }