1 using System.Windows.Forms; 2 using System.Drawing; 3 using System.ComponentModel; 4 5 namespace WeifenLuo.WinFormsUI.Docking 6 { 7 /// <summary> 8 /// Dock window base class. 9 /// </summary> 10 [ToolboxItem(false)] 11 public partial class DockWindow : Panel, INestedPanesContainer, ISplitterHost 12 { 13 private DockPanel m_dockPanel; 14 private DockState m_dockState; 15 private SplitterBase m_splitter; 16 private NestedPaneCollection m_nestedPanes; 17 DockWindow(DockPanel dockPanel, DockState dockState)18 protected internal DockWindow(DockPanel dockPanel, DockState dockState) 19 { 20 m_nestedPanes = new NestedPaneCollection(this); 21 m_dockPanel = dockPanel; 22 m_dockState = dockState; 23 Visible = false; 24 25 SuspendLayout(); 26 27 if (DockState == DockState.DockLeft || DockState == DockState.DockRight || 28 DockState == DockState.DockTop || DockState == DockState.DockBottom) 29 { 30 m_splitter = DockPanel.Theme.Extender.WindowSplitterControlFactory.CreateSplitterControl(this); 31 Controls.Add(m_splitter); 32 } 33 34 if (DockState == DockState.DockLeft) 35 { 36 Dock = DockStyle.Left; 37 m_splitter.Dock = DockStyle.Right; 38 } 39 else if (DockState == DockState.DockRight) 40 { 41 Dock = DockStyle.Right; 42 m_splitter.Dock = DockStyle.Left; 43 } 44 else if (DockState == DockState.DockTop) 45 { 46 Dock = DockStyle.Top; 47 m_splitter.Dock = DockStyle.Bottom; 48 } 49 else if (DockState == DockState.DockBottom) 50 { 51 Dock = DockStyle.Bottom; 52 m_splitter.Dock = DockStyle.Top; 53 } 54 else if (DockState == DockState.Document) 55 { 56 Dock = DockStyle.Fill; 57 } 58 59 ResumeLayout(); 60 } 61 62 public bool IsDockWindow 63 { 64 get { return true; } 65 } 66 67 public VisibleNestedPaneCollection VisibleNestedPanes 68 { 69 get { return NestedPanes.VisibleNestedPanes; } 70 } 71 72 public NestedPaneCollection NestedPanes 73 { 74 get { return m_nestedPanes; } 75 } 76 77 public DockPanel DockPanel 78 { 79 get { return m_dockPanel; } 80 } 81 82 public DockState DockState 83 { 84 get { return m_dockState; } 85 } 86 87 public bool IsFloat 88 { 89 get { return DockState == DockState.Float; } 90 } 91 92 internal DockPane DefaultPane 93 { 94 get { return VisibleNestedPanes.Count == 0 ? null : VisibleNestedPanes[0]; } 95 } 96 97 public virtual Rectangle DisplayingRectangle 98 { 99 get 100 { 101 Rectangle rect = ClientRectangle; 102 // if DockWindow is document, exclude the border 103 if (DockState == DockState.Document) 104 { 105 rect.X += 1; 106 rect.Y += 1; 107 rect.Width -= 2; 108 rect.Height -= 2; 109 } 110 // exclude the splitter 111 else if (DockState == DockState.DockLeft) 112 rect.Width -= DockPanel.Theme.Measures.SplitterSize; 113 else if (DockState == DockState.DockRight) 114 { 115 rect.X += DockPanel.Theme.Measures.SplitterSize; 116 rect.Width -= DockPanel.Theme.Measures.SplitterSize; 117 } 118 else if (DockState == DockState.DockTop) 119 rect.Height -= DockPanel.Theme.Measures.SplitterSize; 120 else if (DockState == DockState.DockBottom) 121 { 122 rect.Y += DockPanel.Theme.Measures.SplitterSize; 123 rect.Height -= DockPanel.Theme.Measures.SplitterSize; 124 } 125 126 return rect; 127 } 128 } 129 OnLayout(LayoutEventArgs levent)130 protected override void OnLayout(LayoutEventArgs levent) 131 { 132 VisibleNestedPanes.Refresh(); 133 if (VisibleNestedPanes.Count == 0) 134 { 135 if (Visible) 136 Visible = false; 137 } 138 else if (!Visible) 139 { 140 Visible = true; 141 VisibleNestedPanes.Refresh(); 142 } 143 144 base.OnLayout (levent); 145 } 146 147 #region ISplitterDragSource Members 148 ISplitterDragSource.BeginDrag(Rectangle rectSplitter)149 void ISplitterDragSource.BeginDrag(Rectangle rectSplitter) 150 { 151 } 152 ISplitterDragSource.EndDrag()153 void ISplitterDragSource.EndDrag() 154 { 155 } 156 157 bool ISplitterDragSource.IsVertical 158 { 159 get { return (DockState == DockState.DockLeft || DockState == DockState.DockRight); } 160 } 161 162 Rectangle ISplitterDragSource.DragLimitBounds 163 { 164 get 165 { 166 Rectangle rectLimit = DockPanel.DockArea; 167 Point location; 168 if ((Control.ModifierKeys & Keys.Shift) == 0) 169 location = Location; 170 else 171 location = DockPanel.DockArea.Location; 172 173 if (((ISplitterDragSource)this).IsVertical) 174 { 175 rectLimit.X += MeasurePane.MinSize; 176 rectLimit.Width -= 2 * MeasurePane.MinSize; 177 rectLimit.Y = location.Y; 178 if ((Control.ModifierKeys & Keys.Shift) == 0) 179 rectLimit.Height = Height; 180 } 181 else 182 { 183 rectLimit.Y += MeasurePane.MinSize; 184 rectLimit.Height -= 2 * MeasurePane.MinSize; 185 rectLimit.X = location.X; 186 if ((Control.ModifierKeys & Keys.Shift) == 0) 187 rectLimit.Width = Width; 188 } 189 190 return DockPanel.RectangleToScreen(rectLimit); 191 } 192 } 193 ISplitterDragSource.MoveSplitter(int offset)194 void ISplitterDragSource.MoveSplitter(int offset) 195 { 196 if ((Control.ModifierKeys & Keys.Shift) != 0) 197 SendToBack(); 198 199 Rectangle rectDockArea = DockPanel.DockArea; 200 if (DockState == DockState.DockLeft && rectDockArea.Width > 0) 201 { 202 if (DockPanel.DockLeftPortion > 1) 203 DockPanel.DockLeftPortion = Width + offset; 204 else 205 DockPanel.DockLeftPortion += ((double)offset) / (double)rectDockArea.Width; 206 } 207 else if (DockState == DockState.DockRight && rectDockArea.Width > 0) 208 { 209 if (DockPanel.DockRightPortion > 1) 210 DockPanel.DockRightPortion = Width - offset; 211 else 212 DockPanel.DockRightPortion -= ((double)offset) / (double)rectDockArea.Width; 213 } 214 else if (DockState == DockState.DockBottom && rectDockArea.Height > 0) 215 { 216 if (DockPanel.DockBottomPortion > 1) 217 DockPanel.DockBottomPortion = Height - offset; 218 else 219 DockPanel.DockBottomPortion -= ((double)offset) / (double)rectDockArea.Height; 220 } 221 else if (DockState == DockState.DockTop && rectDockArea.Height > 0) 222 { 223 if (DockPanel.DockTopPortion > 1) 224 DockPanel.DockTopPortion = Height + offset; 225 else 226 DockPanel.DockTopPortion += ((double)offset) / (double)rectDockArea.Height; 227 } 228 } 229 230 #region IDragSource Members 231 232 Control IDragSource.DragControl 233 { 234 get { return this; } 235 } 236 237 #endregion 238 #endregion 239 } 240 241 /// <summary> 242 /// Dock window of Visual Studio 2003/2005 theme. 243 /// </summary> 244 [ToolboxItem(false)] 245 internal class DefaultDockWindow : DockWindow 246 { DefaultDockWindow(DockPanel dockPanel, DockState dockState)247 internal DefaultDockWindow(DockPanel dockPanel, DockState dockState) : base(dockPanel, dockState) 248 { 249 } 250 OnPaint(PaintEventArgs e)251 protected override void OnPaint(PaintEventArgs e) 252 { 253 // if DockWindow is document, draw the border 254 if (DockState == DockState.Document) 255 e.Graphics.DrawRectangle(SystemPens.ControlDark, ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1); 256 257 base.OnPaint(e); 258 } 259 } 260 } 261