EllipseSelectTool.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /////////////////////////////////////////////////////////////////////////////////
  2. // Paint.NET //
  3. // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
  4. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
  5. // See src/Resources/Files/License.txt for full licensing and attribution //
  6. // details. //
  7. // . //
  8. /////////////////////////////////////////////////////////////////////////////////
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Drawing;
  12. using System.Drawing.Drawing2D;
  13. using System.Windows.Forms;
  14. namespace PaintDotNet.Measurement.Tools
  15. {
  16. public class EllipseSelectTool : SelectionTool
  17. {
  18. protected override List<Point> TrimShapePath(List<Point> tracePoints)
  19. {
  20. List<Point> array = new List<Point>();
  21. if (tracePoints.Count > 0)
  22. {
  23. array.Add(tracePoints[0]);
  24. if (tracePoints.Count > 1)
  25. {
  26. array.Add(tracePoints[tracePoints.Count - 1]);
  27. }
  28. }
  29. return array;
  30. }
  31. protected override List<PointF> CreateShape(List<Point> tracePoints)
  32. {
  33. Point a = tracePoints[0];
  34. Point b = tracePoints[tracePoints.Count - 1];
  35. Point dir = new Point(b.X - a.X, b.Y - a.Y);
  36. float len = (float)Math.Sqrt(dir.X * dir.X + dir.Y * dir.Y);
  37. RectangleF rectF;
  38. if ((ModifierKeys & Keys.Shift) != 0)
  39. {
  40. PointF center = new PointF((float)(a.X + b.X) / 2.0f, (float)(a.Y + b.Y) / 2.0f);
  41. float radius = len / 2;
  42. rectF = Rectangle.Truncate(Utility.RectangleFromCenter(center, radius));
  43. }
  44. else
  45. {
  46. rectF = Utility.PointsToRectangle(a, b);
  47. }
  48. Rectangle rect = Utility.RoundRectangle(rectF);
  49. PdnGraphicsPath path = new PdnGraphicsPath();
  50. path.AddEllipse(rect);
  51. // Avoid asymmetrical circles where the left or right side of the ellipse has a pixel jutting out
  52. using (Matrix m = new Matrix())
  53. {
  54. m.Reset();
  55. m.Translate(-0.5f, -0.5f, MatrixOrder.Append);
  56. path.Transform(m);
  57. }
  58. path.Flatten(Utility.IdentityMatrix, 0.1f);
  59. PointF[] pointsF = path.PathPoints;
  60. path.Dispose();
  61. return new List<PointF>(pointsF);
  62. }
  63. protected override void OnActivate()
  64. {
  65. SetCursors(
  66. "Cursors.EllipseSelectToolCursor.cur",
  67. "Cursors.EllipseSelectToolCursorMinus.cur",
  68. "Cursors.EllipseSelectToolCursorPlus.cur",
  69. "Cursors.EllipseSelectToolCursorMouseDown.cur");
  70. base.OnActivate();
  71. }
  72. protected override void OnDeactivate()
  73. {
  74. base.OnDeactivate();
  75. }
  76. public EllipseSelectTool(IDocumentWorkspace documentWorkspace)
  77. : base(documentWorkspace,
  78. PdnResources.GetImageResource("Icons.EllipseSelectToolIcon.png"),
  79. PdnResources.GetString("EllipseSelectTool.Name"),
  80. PdnResources.GetString("EllipseSelectTool.HelpText"),
  81. 's',
  82. ToolBarConfigItems.None)
  83. {
  84. }
  85. }
  86. }