AngleControl.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using System;
  2. using System.Windows.Forms;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using FastReport.Utils;
  6. namespace FastReport.Controls
  7. {
  8. internal class AngleControl : ContainerControl
  9. {
  10. private int angle;
  11. private bool showBorder;
  12. private NumericUpDown udAngle;
  13. private bool changed;
  14. private bool updating;
  15. public event EventHandler AngleChanged;
  16. public int Angle
  17. {
  18. get { return angle; }
  19. set
  20. {
  21. updating = true;
  22. if (value < 0)
  23. value += 360;
  24. angle = value % 360;
  25. udAngle.Value = angle;
  26. Refresh();
  27. updating = false;
  28. }
  29. }
  30. public bool ShowBorder
  31. {
  32. get { return showBorder; }
  33. set
  34. {
  35. showBorder = value;
  36. Refresh();
  37. }
  38. }
  39. public bool Changed
  40. {
  41. get { return changed; }
  42. set { changed = value; }
  43. }
  44. private void RotateTo(int x, int y)
  45. {
  46. int size = Math.Min(Width, Height - this.LogicalToDevice(30));
  47. int cx = size / 2;
  48. int cy = cx;
  49. int r = x - cx == 0 ? (y > cy ? 90 : 270) : (int)(Math.Atan2((y - cy), (x - cx)) * 180 / Math.PI);
  50. Angle = (int)Math.Round(r / 15f) * 15;
  51. }
  52. private void udAngle_ValueChanged(object sender, EventArgs e)
  53. {
  54. if (updating)
  55. return;
  56. Angle = (int)udAngle.Value;
  57. Change();
  58. }
  59. private void Change()
  60. {
  61. changed = true;
  62. if (AngleChanged != null)
  63. AngleChanged(this, EventArgs.Empty);
  64. }
  65. protected override void OnPaint(PaintEventArgs e)
  66. {
  67. Graphics g = e.Graphics;
  68. // draw control border
  69. if (showBorder)
  70. this.DrawVisualStyleBorder(g, new Rectangle(0, 0, Width - 1, Height - 1));
  71. g.SmoothingMode = SmoothingMode.AntiAlias;
  72. int _4 = this.LogicalToDevice(4);
  73. int _10 = this.LogicalToDevice(10);
  74. int _20 = this.LogicalToDevice(20);
  75. int _30 = this.LogicalToDevice(30);
  76. int size = Math.Min(Width, Height - _30);
  77. int cx = size / 2;
  78. int cy = cx;
  79. int radius = size / 2 - _10;
  80. // draw ticks
  81. using (var p = new Pen(Color.Silver))
  82. {
  83. p.DashStyle = DashStyle.Dot;
  84. g.DrawEllipse(p, _10, _10, size - _20, size - _20);
  85. }
  86. for (int i = 0; i < 360; i += 45)
  87. {
  88. Rectangle rect = new Rectangle(
  89. cx + (int)(Math.Cos(Math.PI / 180 * i) * radius) - 2,
  90. cy + (int)(Math.Sin(Math.PI / 180 * i) * radius) - 2,
  91. _4,
  92. _4);
  93. g.FillEllipse(i == angle ? Brushes.DarkOrange : SystemBrushes.Window, rect);
  94. g.DrawEllipse(i == angle ? Pens.DarkOrange : Pens.Black, rect);
  95. }
  96. // draw sample
  97. using (StringFormat sf = new StringFormat())
  98. {
  99. sf.Alignment = StringAlignment.Center;
  100. sf.LineAlignment = StringAlignment.Center;
  101. StandardTextRenderer.Draw(Res.Get("Misc,Sample"), GdiGraphics.FromGraphics(g), Font, SystemBrushes.WindowText, null,
  102. new RectangleF(cx - radius + 1, cy - radius + 1, radius * 2, radius * 2),
  103. sf, angle, 1);
  104. }
  105. }
  106. protected override void OnMouseDown(MouseEventArgs e)
  107. {
  108. RotateTo(e.X, e.Y);
  109. }
  110. protected override void OnMouseMove(MouseEventArgs e)
  111. {
  112. if (e.Button == MouseButtons.Left)
  113. RotateTo(e.X, e.Y);
  114. }
  115. protected override void OnMouseUp(MouseEventArgs e)
  116. {
  117. Change();
  118. }
  119. public void UpdateDpiDependencies(Control owner)
  120. {
  121. #if MONO
  122. // WPF: fix issues with multi-monitor dpi. Dropdown will be scaled automatically
  123. owner = this;
  124. #endif
  125. if (owner == null)
  126. return;
  127. Size = owner.LogicalToDevice(new Size(100, 130));
  128. }
  129. public AngleControl()
  130. {
  131. udAngle = new NumericUpDown();
  132. udAngle.Maximum = 360;
  133. udAngle.Increment = 15;
  134. udAngle.ValueChanged += new EventHandler(udAngle_ValueChanged);
  135. udAngle.Dock = DockStyle.Bottom;
  136. Controls.Add(udAngle);
  137. showBorder = true;
  138. SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
  139. Size = new Size(100, 130);
  140. BackColor = SystemColors.Window;
  141. Padding = new Padding(4);
  142. }
  143. }
  144. }