diff --git a/DarkUI/Config/Enums.cs b/DarkUI/Config/Enums.cs index 2f7b317..2e4d0c7 100644 --- a/DarkUI/Config/Enums.cs +++ b/DarkUI/Config/Enums.cs @@ -53,4 +53,12 @@ Right, Bottom } + + public enum DarkSplitterType + { + Left, + Right, + Top, + Bottom + } } diff --git a/DarkUI/Docking/DarkDockPanel.cs b/DarkUI/Docking/DarkDockPanel.cs index ed8e582..5ed2fa6 100644 --- a/DarkUI/Docking/DarkDockPanel.cs +++ b/DarkUI/Docking/DarkDockPanel.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.ComponentModel; using System.Windows.Forms; namespace DarkUI @@ -14,14 +15,32 @@ namespace DarkUI #region Property Region + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IMessageFilter MessageFilter { get; private set; } + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List Splitters { get; private set; } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public MouseButtons MouseButtonState + { + get + { + var buttonState = MouseButtons; + return buttonState; + } + } + #endregion #region Constructor Region public DarkDockPanel() { + Splitters = new List(); MessageFilter = new DarkDockResizeFilter(this); _regions = new Dictionary(); diff --git a/DarkUI/Docking/DarkDockRegion.cs b/DarkUI/Docking/DarkDockRegion.cs index e1874ea..7b26095 100644 --- a/DarkUI/Docking/DarkDockRegion.cs +++ b/DarkUI/Docking/DarkDockRegion.cs @@ -11,6 +11,7 @@ namespace DarkUI #region Field Region private List _groups; + private DarkDockSplitter _splitter; #endregion @@ -32,6 +33,7 @@ namespace DarkUI DockArea = dockArea; BuildProperties(); + CreateSplitter(); } #endregion @@ -152,6 +154,38 @@ namespace DarkUI } } + private void CreateSplitter() + { + switch (DockArea) + { + case DarkDockArea.Left: + _splitter = new DarkDockSplitter(this, DarkSplitterType.Right); + break; + case DarkDockArea.Right: + _splitter = new DarkDockSplitter(this, DarkSplitterType.Left); + break; + case DarkDockArea.Bottom: + _splitter = new DarkDockSplitter(this, DarkSplitterType.Top); + break; + default: + return; + } + + DockPanel.Splitters.Add(_splitter); + } + + #endregion + + #region Event Handler Region + + protected override void OnLayout(LayoutEventArgs e) + { + base.OnLayout(e); + + if (_splitter != null) + _splitter.UpdateBounds(); + } + #endregion #region Paint Region diff --git a/DarkUI/Docking/Items/DarkDockSplitter.cs b/DarkUI/Docking/Items/DarkDockSplitter.cs index 49a2b6f..7696e03 100644 --- a/DarkUI/Docking/Items/DarkDockSplitter.cs +++ b/DarkUI/Docking/Items/DarkDockSplitter.cs @@ -1,6 +1,68 @@ -namespace DarkUI +using System.Drawing; +using System.Windows.Forms; + +namespace DarkUI { public class DarkDockSplitter { + #region Field Region + + private Control _control; + private DarkSplitterType _splitterType; + + #endregion + + #region Property Region + + public Rectangle Bounds { get; set; } + + public Cursor ResizeCursor { get; private set; } + + #endregion + + #region Constructor Region + + public DarkDockSplitter(Control control, DarkSplitterType splitterType) + { + _control = control; + _splitterType = splitterType; + + switch (_splitterType) + { + case DarkSplitterType.Left: + case DarkSplitterType.Right: + ResizeCursor = Cursors.SizeWE; + break; + case DarkSplitterType.Top: + case DarkSplitterType.Bottom: + ResizeCursor = Cursors.SizeNS; + break; + } + } + + #endregion + + #region Method Region + + public void UpdateBounds() + { + switch (_splitterType) + { + case DarkSplitterType.Left: + Bounds = new Rectangle(_control.Left - 2, _control.Top, 5, _control.Height); + break; + case DarkSplitterType.Right: + Bounds = new Rectangle(_control.Right - 3, _control.Top, 5, _control.Height); + break; + case DarkSplitterType.Top: + Bounds = new Rectangle(_control.Left, _control.Top - 2, _control.Width, 5); + break; + case DarkSplitterType.Bottom: + Bounds = new Rectangle(_control.Left, _control.Bottom - 5, _control.Width, 5); + break; + } + } + + #endregion } } diff --git a/DarkUI/Win32/DarkDockResizeFilter.cs b/DarkUI/Win32/DarkDockResizeFilter.cs index 666b6e1..9ad7c9e 100644 --- a/DarkUI/Win32/DarkDockResizeFilter.cs +++ b/DarkUI/Win32/DarkDockResizeFilter.cs @@ -1,4 +1,5 @@ -using System.Windows.Forms; +using System.Drawing; +using System.Windows.Forms; namespace DarkUI { @@ -8,6 +9,9 @@ namespace DarkUI private DarkDockPanel _dockPanel; + private bool _isDragging; + private DarkDockSplitter _activeSplitter; + #endregion #region Constructor Region @@ -23,9 +27,104 @@ namespace DarkUI public bool PreFilterMessage(ref Message m) { + // We only care about mouse events + if (!(m.Msg == (int)WM.MOUSEMOVE || + m.Msg == (int)WM.LBUTTONDOWN || m.Msg == (int)WM.LBUTTONUP || m.Msg == (int)WM.LBUTTONDBLCLK || + m.Msg == (int)WM.RBUTTONDOWN || m.Msg == (int)WM.RBUTTONUP || m.Msg == (int)WM.RBUTTONDBLCLK)) + return false; + + // Exit out early if we're simply releasing a drag over the area + if (m.Msg == (int)WM.LBUTTONUP && !_isDragging) + return false; + + // Force cursor if already dragging. + ForceDraggingCursor(); + + // Stop all events from going through if we're dragging a splitter. + if (_isDragging) + return true; + + // Return out early if we're dragging something that's not a splitter. + if (m.Msg == (int)WM.MOUSEMOVE && !_isDragging && _dockPanel.MouseButtonState != MouseButtons.None) + return false; + + // Try and create a control from the message handle. + var control = Control.FromHandle(m.HWnd); + + // Exit out if we didn't manage to create a control. + if (control == null) + return false; + + // Exit out if the control is not the dock panel or a child control. + if (!(control == _dockPanel || _dockPanel.Contains(control))) + return false; + + // Update the mouse cursor + CheckCursor(); + + // Start drag. + if (m.Msg == (int)WM.LBUTTONDOWN) + { + } + + // Stop drag. + if (m.Msg == (int)WM.LBUTTONUP) + { + } + + // Stop events passing through if we just started to drag something + if (_isDragging) + return true; + + // Stop events passing through if we're hovering over a splitter + foreach (var splitter in _dockPanel.Splitters) + { + if (splitter.Bounds.Contains(_dockPanel.PointToClient(Cursor.Position))) + return true; + } + return false; } #endregion + + #region Method Region + + private void ForceDraggingCursor() + { + if (_isDragging) + { + SetCursor(_activeSplitter.ResizeCursor); + return; + } + } + + private void ResetCursor() + { + Cursor.Current = Cursors.Default; + CheckCursor(); + } + + private void CheckCursor() + { + if (_isDragging) + return; + + foreach (var splitter in _dockPanel.Splitters) + { + if (splitter.Bounds.Contains(_dockPanel.PointToClient(Cursor.Position))) + { + SetCursor(splitter.ResizeCursor); + return; + } + } + } + + private void SetCursor(Cursor cursor) + { + Cursor.Current = cursor; + } + + #endregion } } \ No newline at end of file