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> <DesignTime>True</DesignTime>
<DependentUpon>TreeViewIcons.resx</DependentUpon> <DependentUpon>TreeViewIcons.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Win32\DarkControlScrollFilter.cs" /> <Compile Include="Win32\ControlScrollFilter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Renderers\DarkMenuRenderer.cs" /> <Compile Include="Renderers\DarkMenuRenderer.cs" />
<Compile Include="Renderers\DarkToolStripRenderer.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\Native.cs" />
<Compile Include="Win32\WindowsMessages.cs" /> <Compile Include="Win32\WindowsMessages.cs" />
</ItemGroup> </ItemGroup>

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ using System.Windows.Forms;
namespace DarkUI.Win32 namespace DarkUI.Win32
{ {
public class DarkControlScrollFilter : IMessageFilter public class ControlScrollFilter : IMessageFilter
{ {
public bool PreFilterMessage(ref Message m) 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 namespace DarkUI.Win32
{ {
public class DarkDockResizeFilter : IMessageFilter public class DockResizeFilter : IMessageFilter
{ {
#region Field Region #region Field Region
@ -20,7 +20,7 @@ namespace DarkUI.Win32
#region Constructor Region #region Constructor Region
public DarkDockResizeFilter(DarkDockPanel dockPanel) public DockResizeFilter(DarkDockPanel dockPanel)
{ {
_dockPanel = dockPanel; _dockPanel = dockPanel;

View File

@ -30,11 +30,14 @@ namespace Example
// Add the control scroll message filter to re-route all mousewheel events // Add the control scroll message filter to re-route all mousewheel events
// to the control the user is currently hovering over with their cursor. // 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 // 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. // 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. // Hook in all the UI events manually for clarity.
HookEvents(); 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. -- 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 -- 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 -- 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 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 -- add splitters between region groups
-- fix max position of splitters -- 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