mirror of
https://github.com/colhountech/DarkUI.Net5.git
synced 2025-07-05 08:29:26 +03:00
Can now drag tool windows between groups.
This commit is contained in:
parent
89853f1a6e
commit
7e43827bee
@ -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>
|
||||||
|
@ -529,7 +529,9 @@ namespace DarkUI.Docking
|
|||||||
{
|
{
|
||||||
DockPanel.ActiveContent = tab.DockContent;
|
DockPanel.ActiveContent = tab.DockContent;
|
||||||
EnsureVisible();
|
EnsureVisible();
|
||||||
|
|
||||||
_dragTab = tab;
|
_dragTab = tab;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
149
DarkUI/Win32/DockContentDragFilter.cs
Normal file
149
DarkUI/Win32/DockContentDragFilter.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
|
@ -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();
|
||||||
|
9
todo.txt
9
todo.txt
@ -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
|
Loading…
x
Reference in New Issue
Block a user