選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

ProPictureBox.cs 4.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4. namespace ProductionControl.UIExtend
  5. {
  6. public struct ProTransformation
  7. {
  8. public Point Translation { get { return _translation; } }
  9. public double Scale { get { return _scale; } }
  10. private readonly Point _translation;
  11. private readonly double _scale;
  12. public ProTransformation(Point translation, double scale)
  13. {
  14. _translation = translation;
  15. _scale = scale;
  16. }
  17. public Point ConvertToIm(Point p)
  18. {
  19. return new Point((int)(p.X * _scale + _translation.X), (int)(p.Y * _scale + _translation.Y));
  20. }
  21. public Size ConvertToIm(Size p)
  22. {
  23. return new Size((int)(p.Width * _scale), (int)(p.Height * _scale));
  24. }
  25. public Rectangle ConvertToIm(Rectangle r)
  26. {
  27. return new Rectangle(ConvertToIm(r.Location), ConvertToIm(r.Size));
  28. }
  29. public Point ConvertToPb(Point p)
  30. {
  31. return new Point((int)((p.X - _translation.X) / _scale), (int)((p.Y - _translation.Y) / _scale));
  32. }
  33. public Size ConvertToPb(Size p)
  34. {
  35. return new Size((int)(p.Width / _scale), (int)(p.Height / _scale));
  36. }
  37. public Rectangle ConvertToPb(Rectangle r)
  38. {
  39. return new Rectangle(ConvertToPb(r.Location), ConvertToPb(r.Size));
  40. }
  41. public ProTransformation SetTranslate(Point p)
  42. {
  43. return new ProTransformation(p, _scale);
  44. }
  45. public ProTransformation AddTranslate(Point p)
  46. {
  47. return SetTranslate(new Point(p.X + _translation.X, p.Y + _translation.Y));
  48. }
  49. public ProTransformation SetScale(double scale)
  50. {
  51. return new ProTransformation(_translation, scale);
  52. }
  53. }
  54. public class ProPictureBox : PictureBox
  55. {
  56. private Point? _clickedPoint;
  57. private ProTransformation _transformation;
  58. public ProTransformation Transformation
  59. {
  60. set
  61. {
  62. _transformation = FixTranslation(value);
  63. Invalidate();
  64. }
  65. get
  66. {
  67. return _transformation;
  68. }
  69. }
  70. public ProPictureBox()
  71. {
  72. _transformation = new ProTransformation(new Point(1000, 0), 0.5f);
  73. MouseDown += OnMouseDown;
  74. MouseMove += OnMouseMove;
  75. MouseUp += OnMouseUp;
  76. MouseWheel += OnMouseWheel;
  77. Resize += OnResize;
  78. }
  79. private ProTransformation FixTranslation(ProTransformation value)
  80. {
  81. var maxScale = Math.Max((double)Image.Width / ClientRectangle.Width, (double)Image.Height / ClientRectangle.Height);
  82. if (value.Scale > maxScale)
  83. value = value.SetScale(maxScale);
  84. if (value.Scale < 0.3)
  85. value = value.SetScale(0.3);
  86. var rectSize = value.ConvertToIm(ClientRectangle.Size);
  87. var max = new Size(Image.Width - rectSize.Width, Image.Height - rectSize.Height);
  88. value = value.SetTranslate((new Point(Math.Min(value.Translation.X, max.Width), Math.Min(value.Translation.Y, max.Height))));
  89. if (value.Translation.X < 0 || value.Translation.Y < 0)
  90. {
  91. value = value.SetTranslate(new Point(Math.Max(value.Translation.X, 0), Math.Max(value.Translation.Y, 0)));
  92. }
  93. return value;
  94. }
  95. private void OnResize(object sender, EventArgs eventArgs)
  96. {
  97. if (Image == null)
  98. return;
  99. Transformation = Transformation;
  100. }
  101. private void OnMouseWheel(object sender, MouseEventArgs e)
  102. {
  103. var transformation = _transformation;
  104. var pos1 = transformation.ConvertToIm(e.Location);
  105. if (e.Delta > 0)
  106. transformation = (transformation.SetScale(Transformation.Scale / 1.25));
  107. else
  108. transformation = (transformation.SetScale(Transformation.Scale * 1.25));
  109. var pos2 = transformation.ConvertToIm(e.Location);
  110. transformation = transformation.AddTranslate(pos1 - (Size)pos2);
  111. Transformation = transformation;
  112. }
  113. private void OnMouseUp(object sender, MouseEventArgs mouseEventArgs)
  114. {
  115. _clickedPoint = null;
  116. }
  117. private void OnMouseMove(object sender, MouseEventArgs e)
  118. {
  119. if (_clickedPoint == null)
  120. return;
  121. var p = _transformation.ConvertToIm((Size)e.Location);
  122. Transformation = _transformation.SetTranslate(_clickedPoint.Value - p);
  123. }
  124. private void OnMouseDown(object sender, MouseEventArgs e)
  125. {
  126. Focus();
  127. _clickedPoint = _transformation.ConvertToIm(e.Location);
  128. }
  129. protected override void OnPaint(PaintEventArgs e)
  130. {
  131. var imRect = Transformation.ConvertToIm(ClientRectangle);
  132. e.Graphics.DrawImage(Image, ClientRectangle, imRect, GraphicsUnit.Pixel);
  133. }
  134. public void DecideInitialTransformation()
  135. {
  136. Transformation = new ProTransformation(Point.Empty, int.MaxValue);
  137. }
  138. }
  139. }