Can now drag tool windows between groups.

This commit is contained in:
Robin 2016-01-02 06:52:48 +00:00
parent 89853f1a6e
commit 7e43827bee
10 changed files with 233 additions and 11 deletions

View File

@ -178,11 +178,12 @@
<DesignTime>True</DesignTime>
<DependentUpon>TreeViewIcons.resx</DependentUpon>
</Compile>
<Compile Include="Win32\DarkControlScrollFilter.cs" />
<Compile Include="Win32\ControlScrollFilter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Renderers\DarkMenuRenderer.cs" />
<Compile Include="Renderers\DarkToolStripRenderer.cs" />
<Compile Include="Win32\DarkDockResizeFilter.cs" />
<Compile Include="Win32\DockResizeFilter.cs" />
<Compile Include="Win32\DockContentDragFilter.cs" />
<Compile Include="Win32\Native.cs" />
<Compile Include="Win32\WindowsMessages.cs" />
</ItemGroup>

View File

@ -529,7 +529,9 @@ namespace DarkUI.Docking
{
DockPanel.ActiveContent = tab.DockContent;
EnsureVisible();
_dragTab = tab;
return;
}
}

View File

@ -78,7 +78,11 @@ namespace DarkUI.Docking
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IMessageFilter MessageFilter { get; private set; }
public DockContentDragFilter DockContentDragFilter { get; private set; }
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public DockResizeFilter DockResizeFilter { get; private set; }
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
@ -95,6 +99,16 @@ namespace DarkUI.Docking
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<DarkDockRegion> Regions
{
get
{
return _regions.Values.ToList();
}
}
#endregion
#region Constructor Region
@ -102,7 +116,8 @@ namespace DarkUI.Docking
public DarkDockPanel()
{
Splitters = new List<DarkDockSplitter>();
MessageFilter = new DarkDockResizeFilter(this);
DockContentDragFilter = new DockContentDragFilter(this);
DockResizeFilter = new DockResizeFilter(this);
_regions = new Dictionary<DarkDockArea, DarkDockRegion>();
_contents = new List<DarkDockContent>();
@ -129,6 +144,9 @@ namespace DarkUI.Docking
dockContent.DockPanel = this;
_contents.Add(dockContent);
if (dockGroup != null)
dockContent.DockArea = dockGroup.DockArea;
if (dockContent.DockArea == DarkDockArea.None)
dockContent.DockArea = dockContent.DefaultDockArea;
@ -194,6 +212,11 @@ namespace DarkUI.Docking
leftRegion.TabIndex = 3;
}
public void DragContent(DarkDockContent content)
{
DockContentDragFilter.StartDrag(content);
}
#endregion
#region Serialization Region

View File

@ -37,6 +37,14 @@ namespace DarkUI.Docking
}
}
public List<DarkDockGroup> Groups
{
get
{
return _groups.ToList();
}
}
#endregion
#region Constructor Region
@ -92,6 +100,8 @@ namespace DarkUI.Docking
var group = dockContent.DockGroup;
group.RemoveContent(dockContent);
dockContent.DockArea = DarkDockArea.None;
// If that was the final content in the group then remove the group
if (group.ContentCount == 0)
RemoveGroup(group);
@ -250,6 +260,9 @@ namespace DarkUI.Docking
private void CreateSplitter()
{
if (_splitter != null && DockPanel.Splitters.Contains(_splitter))
DockPanel.Splitters.Remove(_splitter);
switch (DockArea)
{
case DarkDockArea.Left:

View File

@ -15,6 +15,9 @@ namespace DarkUI.Docking
private bool _closeButtonHot = false;
private bool _closeButtonPressed = false;
private Rectangle _headerRect;
private bool _shouldDrag;
#endregion
#region Property Region
@ -56,6 +59,14 @@ namespace DarkUI.Docking
private void UpdateCloseButton()
{
_headerRect = new Rectangle
{
X = ClientRectangle.Left,
Y = ClientRectangle.Top,
Width = ClientRectangle.Width,
Height = Consts.ToolWindowHeaderSize
};
_closeButtonRect = new Rectangle
{
X = ClientRectangle.Right - DockIcons.tw_close.Width - 5 - 3,
@ -95,6 +106,12 @@ namespace DarkUI.Docking
_closeButtonHot = false;
Invalidate();
}
if (_shouldDrag)
{
DockPanel.DragContent(this);
return;
}
}
}
@ -107,6 +124,13 @@ namespace DarkUI.Docking
_closeButtonPressed = true;
_closeButtonHot = true;
Invalidate();
return;
}
if (_headerRect.Contains(e.Location))
{
_shouldDrag = true;
return;
}
}
@ -120,6 +144,8 @@ namespace DarkUI.Docking
_closeButtonPressed = false;
_closeButtonHot = false;
_shouldDrag = false;
Invalidate();
}

View File

@ -3,7 +3,7 @@ using System.Windows.Forms;
namespace DarkUI.Win32
{
public class DarkControlScrollFilter : IMessageFilter
public class ControlScrollFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{

View File

@ -0,0 +1,149 @@
using DarkUI.Config;
using DarkUI.Docking;
using DarkUI.Forms;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace DarkUI.Win32
{
public class DockContentDragFilter : IMessageFilter
{
#region Field Region
private DarkDockPanel _dockPanel;
private DarkDockContent _dragContent;
private DarkTranslucentForm _highlightForm;
private DarkDockGroup _targetGroup;
private Dictionary<DarkDockGroup, Rectangle> _groupDropAreas = new Dictionary<DarkDockGroup, Rectangle>();
#endregion
#region Constructor Region
public DockContentDragFilter(DarkDockPanel dockPanel)
{
_dockPanel = dockPanel;
_highlightForm = new DarkTranslucentForm(Colors.BlueSelection);
}
#endregion
#region IMessageFilter Region
public bool PreFilterMessage(ref Message m)
{
// Exit out early if we're not dragging any content
if (_dragContent == null)
return false;
// 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;
// Move content
if (m.Msg == (int)WM.MOUSEMOVE)
{
HandleDrag();
return false;
}
// Drop content
if (m.Msg == (int)WM.LBUTTONUP)
{
if (_targetGroup != null)
_dockPanel.AddContent(_dragContent, _targetGroup);
StopDrag();
return false;
}
return true;
}
#endregion
#region Method Region
public void StartDrag(DarkDockContent content)
{
_groupDropAreas = new Dictionary<DarkDockGroup, Rectangle>();
foreach (var region in _dockPanel.Regions)
{
foreach (var group in region.Groups)
{
var rect = new Rectangle
{
X = group.PointToScreen(Point.Empty).X,
Y = group.PointToScreen(Point.Empty).Y,
Width = group.Width,
Height = group.Height
};
_groupDropAreas.Add(group, rect);
}
}
_dragContent = content;
}
private void StopDrag()
{
_highlightForm.Hide();
_dragContent = null;
}
private void HandleDrag()
{
var location = Cursor.Position;
_targetGroup = null;
foreach (var keyValuePair in _groupDropAreas)
{
var group = keyValuePair.Key;
var rect = keyValuePair.Value;
if (group == _dragContent.DockGroup)
continue;
if (group.DockArea == DarkDockArea.Document)
continue;
if (rect.Contains(location))
{
_targetGroup = group;
_highlightForm.Location = new Point(rect.X, rect.Y);
_highlightForm.Size = new Size(rect.Width, rect.Height);
}
}
if (_targetGroup == null)
{
if (_highlightForm.Visible)
{
_highlightForm.Hide();
}
}
else
{
if (!_highlightForm.Visible)
{
_highlightForm.Show();
_highlightForm.BringToFront();
}
}
}
#endregion
}
}

View File

@ -5,7 +5,7 @@ using System.Windows.Forms;
namespace DarkUI.Win32
{
public class DarkDockResizeFilter : IMessageFilter
public class DockResizeFilter : IMessageFilter
{
#region Field Region
@ -20,7 +20,7 @@ namespace DarkUI.Win32
#region Constructor Region
public DarkDockResizeFilter(DarkDockPanel dockPanel)
public DockResizeFilter(DarkDockPanel dockPanel)
{
_dockPanel = dockPanel;

View File

@ -30,11 +30,14 @@ namespace Example
// Add the control scroll message filter to re-route all mousewheel events
// to the control the user is currently hovering over with their cursor.
Application.AddMessageFilter(new DarkControlScrollFilter());
Application.AddMessageFilter(new ControlScrollFilter());
// Add the dock content drag message filter to handle moving dock content around.
Application.AddMessageFilter(DockPanel.DockContentDragFilter);
// Add the dock panel message filter to filter through for dock panel splitter
// input before letting events pass through to the rest of the application.
Application.AddMessageFilter(DockPanel.MessageFilter);
Application.AddMessageFilter(DockPanel.DockResizeFilter);
// Hook in all the UI events manually for clarity.
HookEvents();

View File

@ -14,9 +14,14 @@ DarkUI
-- standardise the amount you scroll through with the mousewheel. Basing it on the pixels makes it weird.
-- ScrollView not taking in to account size WITHOUT scrollbars causing you to have to overshoot when re-sizing to get rid of them
-- if the final node in a treeview has been previous expanded, pressing 'down' will cause it to re-open
-- create click-through panel
Dock panel
-- drag tabs and toolwindows to re-order or change region
-- make it so highlight form doesn't steal focus
-- add splitters between region groups
-- fix max position of splitters
-- serialise the visible content for groups and the active content
-- serialise the visible content for groups and the active content
-- right click tab menu. close all, close all but this etc. etc.
-- stop dragging tabs instantly going to the end of the row
-- stop differently sized toolwindow tabs from vibrating when dragging
-- fix regions being visible with no groups on load