1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Windows.Forms;
5 using System.Drawing;
6 using System.Drawing.Drawing2D;
7 using System.ComponentModel;
8 
9 namespace WeifenLuo.WinFormsUI.Docking
10 {
11     partial class DockPanel
12     {
13         private sealed class SplitterDragHandler : DragHandler
14         {
15             private class SplitterOutline
16             {
SplitterOutline()17                 public SplitterOutline()
18                 {
19                     m_dragForm = new DragForm();
20                     SetDragForm(Rectangle.Empty);
21                     DragForm.BackColor = Color.Black;
22                     DragForm.Opacity = 0.7;
23                     DragForm.Show(false);
24                 }
25 
26                 DragForm m_dragForm;
27                 private DragForm DragForm
28                 {
29                     get { return m_dragForm; }
30                 }
31 
Show(Rectangle rect)32                 public void Show(Rectangle rect)
33                 {
34                     SetDragForm(rect);
35                 }
36 
Close()37                 public void Close()
38                 {
39                     DragForm.Bounds = Rectangle.Empty;
40                     DragForm.Close();
41                 }
42 
SetDragForm(Rectangle rect)43                 private void SetDragForm(Rectangle rect)
44                 {
45                     DragForm.Bounds = rect;
46                     if (rect == Rectangle.Empty)
47                         DragForm.Region = new Region(Rectangle.Empty);
48                     else if (DragForm.Region != null)
49                         DragForm.Region = null;
50                 }
51             }
52 
SplitterDragHandler(DockPanel dockPanel)53             public SplitterDragHandler(DockPanel dockPanel)
54                 : base(dockPanel)
55             {
56             }
57 
58             public new ISplitterDragSource DragSource
59             {
60                 get { return base.DragSource as ISplitterDragSource; }
61                 private set { base.DragSource = value; }
62             }
63 
64             private SplitterOutline m_outline;
65             private SplitterOutline Outline
66             {
67                 get { return m_outline; }
68                 set { m_outline = value; }
69             }
70 
71             private Rectangle m_rectSplitter;
72             private Rectangle RectSplitter
73             {
74                 get { return m_rectSplitter; }
75                 set { m_rectSplitter = value; }
76             }
77 
BeginDrag(ISplitterDragSource dragSource, Rectangle rectSplitter)78             public void BeginDrag(ISplitterDragSource dragSource, Rectangle rectSplitter)
79             {
80                 DragSource = dragSource;
81                 RectSplitter = rectSplitter;
82 
83                 if (!BeginDrag())
84                 {
85                     DragSource = null;
86                     return;
87                 }
88 
89                 Outline = new SplitterOutline();
90                 Outline.Show(rectSplitter);
91                 DragSource.BeginDrag(rectSplitter);
92             }
93 
OnDragging()94             protected override void OnDragging()
95             {
96                 Outline.Show(GetSplitterOutlineBounds(Control.MousePosition));
97             }
98 
OnEndDrag(bool abort)99             protected override void OnEndDrag(bool abort)
100             {
101                 DockPanel.SuspendLayout(true);
102 
103                 Outline.Close();
104 
105                 if (!abort)
106                     DragSource.MoveSplitter(GetMovingOffset(Control.MousePosition));
107 
108                 DragSource.EndDrag();
109                 DockPanel.ResumeLayout(true, true);
110             }
111 
GetMovingOffset(Point ptMouse)112             private int GetMovingOffset(Point ptMouse)
113             {
114                 Rectangle rect = GetSplitterOutlineBounds(ptMouse);
115                 if (DragSource.IsVertical)
116                     return rect.X - RectSplitter.X;
117                 else
118                     return rect.Y - RectSplitter.Y;
119             }
120 
GetSplitterOutlineBounds(Point ptMouse)121             private Rectangle GetSplitterOutlineBounds(Point ptMouse)
122             {
123                 Rectangle rectLimit = DragSource.DragLimitBounds;
124 
125                 Rectangle rect = RectSplitter;
126                 if (rectLimit.Width <= 0 || rectLimit.Height <= 0)
127                     return rect;
128 
129                 if (DragSource.IsVertical)
130                 {
131                     rect.X += ptMouse.X - StartMousePosition.X;
132                     rect.Height = rectLimit.Height;
133                 }
134                 else
135                 {
136                     rect.Y += ptMouse.Y - StartMousePosition.Y;
137                     rect.Width = rectLimit.Width;
138                 }
139 
140                 if (rect.Left < rectLimit.Left)
141                     rect.X = rectLimit.X;
142                 if (rect.Top < rectLimit.Top)
143                     rect.Y = rectLimit.Y;
144                 if (rect.Right > rectLimit.Right)
145                     rect.X -= rect.Right - rectLimit.Right;
146                 if (rect.Bottom > rectLimit.Bottom)
147                     rect.Y -= rect.Bottom - rectLimit.Bottom;
148 
149                 return rect;
150             }
151         }
152 
153         private SplitterDragHandler m_splitterDragHandler = null;
GetSplitterDragHandler()154         private SplitterDragHandler GetSplitterDragHandler()
155         {
156             if (m_splitterDragHandler == null)
157                 m_splitterDragHandler = new SplitterDragHandler(this);
158             return m_splitterDragHandler;
159         }
160 
BeginDrag(ISplitterDragSource dragSource, Rectangle rectSplitter)161         public void BeginDrag(ISplitterDragSource dragSource, Rectangle rectSplitter)
162         {
163             GetSplitterDragHandler().BeginDrag(dragSource, rectSplitter);
164         }
165     }
166 }
167