RotateNubRenderer.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using PaintDotNet.SystemLayer;
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. namespace PaintDotNet.Measurement
  6. {
  7. public class RotateNubRenderer : SurfaceBoxGraphicsRenderer
  8. {
  9. private const int size = 6;
  10. private PointF location;
  11. private float angle;
  12. public PointF Location
  13. {
  14. get
  15. {
  16. return this.location;
  17. }
  18. set
  19. {
  20. InvalidateOurself();
  21. this.location = value;
  22. InvalidateOurself();
  23. }
  24. }
  25. public float Angle
  26. {
  27. get
  28. {
  29. return this.angle;
  30. }
  31. set
  32. {
  33. InvalidateOurself();
  34. this.angle = value;
  35. InvalidateOurself();
  36. }
  37. }
  38. private RectangleF GetOurRectangle()
  39. {
  40. RectangleF rectF = new RectangleF(this.Location, new SizeF(0, 0));
  41. float ratio = 1.0f / (float)OwnerList.ScaleFactor.Ratio;
  42. float ourSize = UI.ScaleWidth(size);
  43. rectF.Inflate(ratio * ourSize, ratio * ourSize);
  44. return rectF;
  45. }
  46. private void InvalidateOurself()
  47. {
  48. RectangleF rectF = GetOurRectangle();
  49. Rectangle rect = Utility.RoundRectangle(rectF);
  50. rect.Inflate(2, 2);
  51. Invalidate(rect);
  52. }
  53. public bool IsPointTouching(Point pt)
  54. {
  55. RectangleF rectF = GetOurRectangle();
  56. Rectangle rect = Utility.RoundRectangle(rectF);
  57. return pt.X >= rect.Left && pt.Y >= rect.Top && pt.X < rect.Right && pt.Y < rect.Bottom;
  58. }
  59. protected override void OnVisibleChanged()
  60. {
  61. InvalidateOurself();
  62. }
  63. public override void RenderToGraphics(Graphics g, Point offset)
  64. {
  65. // We round these values to the nearest integer to avoid an interesting rendering
  66. // anomaly (or bug? what a surprise ... GDI+) where the nub appears to rotate
  67. // off-center, or the 'screw-line' is off-center
  68. float centerX = this.Location.X * (float)OwnerList.ScaleFactor.Ratio;
  69. float centerY = this.Location.Y * (float)OwnerList.ScaleFactor.Ratio;
  70. Point center = new Point((int)Math.Round(centerX), (int)Math.Round(centerY));
  71. g.SmoothingMode = SmoothingMode.AntiAlias;
  72. g.TranslateTransform(-center.X, -center.Y, MatrixOrder.Append);
  73. g.RotateTransform(this.angle, MatrixOrder.Append);
  74. g.TranslateTransform(center.X - offset.X, center.Y - offset.Y, MatrixOrder.Append);
  75. float ourSize = UI.ScaleWidth(size);
  76. using (Pen white = new Pen(Color.FromArgb(128, Color.White), -1.0f),
  77. black = new Pen(Color.FromArgb(128, Color.Black), -1.0f))
  78. {
  79. RectangleF rectF = new RectangleF(center, new SizeF(0, 0));
  80. rectF.Inflate(ourSize - 3, ourSize - 3);
  81. g.DrawEllipse(white, Rectangle.Truncate(rectF));
  82. rectF.Inflate(1, 1);
  83. g.DrawEllipse(black, Rectangle.Truncate(rectF));
  84. rectF.Inflate(1, 1);
  85. g.DrawEllipse(white, Rectangle.Truncate(rectF));
  86. rectF.Inflate(-2, -2);
  87. g.DrawLine(white, rectF.X + rectF.Width / 2.0f - 1.0f, rectF.Top, rectF.X + rectF.Width / 2.0f - 1.0f, rectF.Bottom);
  88. g.DrawLine(white, rectF.X + rectF.Width / 2.0f + 1.0f, rectF.Top, rectF.X + rectF.Width / 2.0f + 1.0f, rectF.Bottom);
  89. g.DrawLine(black, rectF.X + rectF.Width / 2.0f, rectF.Top, rectF.X + rectF.Width / 2.0f, rectF.Bottom);
  90. }
  91. }
  92. public RotateNubRenderer(SurfaceBoxRendererList ownerList)
  93. : base(ownerList)
  94. {
  95. this.location = new Point(0, 0);
  96. }
  97. }
  98. }