Splitter.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. namespace System.Windows.Forms
  2. {
  3. public class Splitter : Control
  4. {
  5. private Control indicator;
  6. private System.Drawing.Point mouseDownPoint;
  7. public override DockStyle Dock
  8. {
  9. get => base.Dock;
  10. set
  11. {
  12. base.Dock = value;
  13. Cursor = value == DockStyle.Left || value == DockStyle.Right ? Cursors.VSplit : Cursors.HSplit;
  14. if (value == DockStyle.Left || value == DockStyle.Right)
  15. Width = 3;
  16. else
  17. Height = 3;
  18. }
  19. }
  20. public int MinSize { get; set; } // TODO: check
  21. public int MinExtra { get; set; } // TODO?
  22. public event SplitterEventHandler SplitterMoved;
  23. private Control GetResizableControl()
  24. {
  25. for (int i = Parent.Controls.Count - 1; i >= 0; i--)
  26. {
  27. var c = Parent.Controls[i];
  28. if (c != this && c.Dock == this.Dock)
  29. return c;
  30. }
  31. return null;
  32. }
  33. protected virtual void OnSplitterMoved(SplitterEventArgs e) => SplitterMoved?.Invoke(this, e);
  34. protected override void OnMouseDown(MouseEventArgs e)
  35. {
  36. base.OnMouseDown(e);
  37. if (GetResizableControl() == null)
  38. return;
  39. mouseDownPoint = e.Location;
  40. indicator = new Control();
  41. indicator.BackColor = System.Drawing.Color.Black;
  42. indicator.Parent = this.Parent;
  43. indicator.Location = this.Location;
  44. indicator.Size = this.Size;
  45. indicator.BringToFront();
  46. }
  47. protected override void OnMouseMove(MouseEventArgs e)
  48. {
  49. base.OnMouseMove(e);
  50. if (e.Button == MouseButtons.Left)
  51. {
  52. if (indicator == null)
  53. return;
  54. if (Dock == DockStyle.Left || Dock == DockStyle.Right)
  55. {
  56. int x = Left + e.X - mouseDownPoint.X;
  57. if (x >= 0 && x < Parent.Width - Width && x >= MinSize)
  58. indicator.Left = x;
  59. }
  60. else
  61. {
  62. int y = Top + e.Y - mouseDownPoint.Y;
  63. if (y >= 0 && y < Parent.Height - Height && y >= MinSize)
  64. indicator.Top = y;
  65. }
  66. }
  67. }
  68. protected override void OnMouseUp(MouseEventArgs e)
  69. {
  70. base.OnMouseUp(e);
  71. if (indicator == null)
  72. return;
  73. Control resizableControl = GetResizableControl();
  74. if (resizableControl == null)
  75. return;
  76. if (Dock == DockStyle.Left)
  77. resizableControl.Width -= Left - indicator.Left;
  78. else if (Dock == DockStyle.Right)
  79. resizableControl.Width += Left - indicator.Left;
  80. else if (Dock == DockStyle.Top)
  81. resizableControl.Height -= Top - indicator.Top;
  82. else if (Dock == DockStyle.Bottom)
  83. resizableControl.Height += Top - indicator.Top;
  84. indicator.Dispose();
  85. // TODO: check arguments
  86. OnSplitterMoved(new SplitterEventArgs(0, 0, resizableControl.Width, resizableControl.Height));
  87. }
  88. public Splitter()
  89. {
  90. Dock = DockStyle.Left;
  91. }
  92. }
  93. }