mirror of
https://github.com/colhountech/DarkUI.Net5.git
synced 2025-07-02 07:09:27 +03:00
Refactored dock content drag & drop.
This commit is contained in:
parent
f96c0b0f21
commit
fe9d60dc0e
@ -128,9 +128,12 @@
|
||||
<Compile Include="Docking\DarkDockTab.cs" />
|
||||
<Compile Include="Docking\DarkDockTabArea.cs" />
|
||||
<Compile Include="Docking\DockContentEventArgs.cs" />
|
||||
<Compile Include="Docking\DockDropArea.cs" />
|
||||
<Compile Include="Docking\DockDropCollection.cs" />
|
||||
<Compile Include="Docking\DockGroupState.cs" />
|
||||
<Compile Include="Docking\DockPanelState.cs" />
|
||||
<Compile Include="Docking\DockRegionState.cs" />
|
||||
<Compile Include="Docking\DockInsertType.cs" />
|
||||
<Compile Include="Extensions\BitmapExtensions.cs" />
|
||||
<Compile Include="Extensions\IEnumerableExtensions.cs" />
|
||||
<Compile Include="Forms\DarkDialog.cs">
|
||||
|
@ -159,7 +159,7 @@ namespace DarkUI.Docking
|
||||
dockContent.Select();
|
||||
}
|
||||
|
||||
public void InsertContent(DarkDockContent dockContent, DarkDockGroup dockGroup)
|
||||
public void InsertContent(DarkDockContent dockContent, DarkDockGroup dockGroup, DockInsertType insertType)
|
||||
{
|
||||
if (_contents.Contains(dockContent))
|
||||
RemoveContent(dockContent);
|
||||
@ -170,7 +170,7 @@ namespace DarkUI.Docking
|
||||
dockContent.DockArea = dockGroup.DockArea;
|
||||
|
||||
var region = _regions[dockGroup.DockArea];
|
||||
region.InsertContent(dockContent, dockGroup);
|
||||
region.InsertContent(dockContent, dockGroup, insertType);
|
||||
|
||||
if (ContentAdded != null)
|
||||
ContentAdded(this, new DockContentEventArgs(dockContent));
|
||||
|
@ -92,9 +92,14 @@ namespace DarkUI.Docking
|
||||
PositionGroups();
|
||||
}
|
||||
|
||||
internal void InsertContent(DarkDockContent dockContent, DarkDockGroup dockGroup)
|
||||
internal void InsertContent(DarkDockContent dockContent, DarkDockGroup dockGroup, DockInsertType insertType)
|
||||
{
|
||||
var newGroup = InsertGroup(dockGroup.Order);
|
||||
var order = dockGroup.Order;
|
||||
|
||||
if (insertType == DockInsertType.After)
|
||||
order++;
|
||||
|
||||
var newGroup = InsertGroup(order);
|
||||
|
||||
dockContent.DockRegion = this;
|
||||
newGroup.AddContent(dockContent);
|
||||
@ -166,7 +171,7 @@ namespace DarkUI.Docking
|
||||
{
|
||||
foreach (var group in _groups)
|
||||
{
|
||||
if (group.Order <= order)
|
||||
if (group.Order >= order)
|
||||
group.Order++;
|
||||
}
|
||||
|
||||
|
138
DarkUI/Docking/DockDropArea.cs
Normal file
138
DarkUI/Docking/DockDropArea.cs
Normal file
@ -0,0 +1,138 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace DarkUI.Docking
|
||||
{
|
||||
internal class DockDropArea
|
||||
{
|
||||
#region Property Region
|
||||
|
||||
internal DarkDockPanel DockPanel { get; private set; }
|
||||
|
||||
internal Rectangle DropArea { get; private set; }
|
||||
|
||||
internal Rectangle HighlightArea { get; private set; }
|
||||
|
||||
internal DarkDockRegion DockRegion { get; private set; }
|
||||
|
||||
internal DarkDockGroup DockGroup { get; private set; }
|
||||
|
||||
internal DockInsertType InsertType { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor Region
|
||||
|
||||
internal DockDropArea(DarkDockRegion region, DockInsertType insertType)
|
||||
{
|
||||
DockRegion = region;
|
||||
InsertType = insertType;
|
||||
}
|
||||
|
||||
internal DockDropArea(DarkDockGroup group, DockInsertType insertType)
|
||||
{
|
||||
DockGroup = group;
|
||||
InsertType = insertType;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Method Region
|
||||
|
||||
internal void BuildAreas()
|
||||
{
|
||||
if (DockRegion != null)
|
||||
BuildRegionAreas();
|
||||
else if (DockGroup != null)
|
||||
BuildGroupAreas();
|
||||
}
|
||||
|
||||
private void BuildRegionAreas()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void BuildGroupAreas()
|
||||
{
|
||||
switch (InsertType)
|
||||
{
|
||||
case DockInsertType.None:
|
||||
var dropRect = new Rectangle
|
||||
{
|
||||
X = DockGroup.PointToScreen(Point.Empty).X,
|
||||
Y = DockGroup.PointToScreen(Point.Empty).Y,
|
||||
Width = DockGroup.Width,
|
||||
Height = DockGroup.Height
|
||||
};
|
||||
|
||||
DropArea = dropRect;
|
||||
HighlightArea = dropRect;
|
||||
|
||||
break;
|
||||
|
||||
case DockInsertType.Before:
|
||||
var beforeDropWidth = DockGroup.Width;
|
||||
var beforeDropHeight = DockGroup.Height;
|
||||
|
||||
switch (DockGroup.DockArea)
|
||||
{
|
||||
case DarkDockArea.Left:
|
||||
case DarkDockArea.Right:
|
||||
beforeDropHeight = DockGroup.Height / 4;
|
||||
break;
|
||||
|
||||
case DarkDockArea.Bottom:
|
||||
beforeDropWidth = DockGroup.Width / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
var beforeDropRect = new Rectangle
|
||||
{
|
||||
X = DockGroup.PointToScreen(Point.Empty).X,
|
||||
Y = DockGroup.PointToScreen(Point.Empty).Y,
|
||||
Width = beforeDropWidth,
|
||||
Height = beforeDropHeight
|
||||
};
|
||||
|
||||
DropArea = beforeDropRect;
|
||||
HighlightArea = beforeDropRect;
|
||||
|
||||
break;
|
||||
|
||||
case DockInsertType.After:
|
||||
var afterDropX = DockGroup.PointToScreen(Point.Empty).X;
|
||||
var afterDropY = DockGroup.PointToScreen(Point.Empty).Y;
|
||||
var afterDropWidth = DockGroup.Width;
|
||||
var afterDropHeight = DockGroup.Height;
|
||||
|
||||
switch (DockGroup.DockArea)
|
||||
{
|
||||
case DarkDockArea.Left:
|
||||
case DarkDockArea.Right:
|
||||
afterDropHeight = DockGroup.Height / 4;
|
||||
afterDropY = DockGroup.PointToScreen(Point.Empty).Y + DockGroup.Height - afterDropHeight;
|
||||
break;
|
||||
|
||||
case DarkDockArea.Bottom:
|
||||
afterDropWidth = DockGroup.Width / 4;
|
||||
afterDropX = DockGroup.PointToScreen(Point.Empty).X + DockGroup.Width - afterDropWidth;
|
||||
break;
|
||||
}
|
||||
|
||||
var afterDropRect = new Rectangle
|
||||
{
|
||||
X = afterDropX,
|
||||
Y = afterDropY,
|
||||
Width = afterDropWidth,
|
||||
Height = afterDropHeight
|
||||
};
|
||||
|
||||
DropArea = afterDropRect;
|
||||
HighlightArea = afterDropRect;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
48
DarkUI/Docking/DockDropCollection.cs
Normal file
48
DarkUI/Docking/DockDropCollection.cs
Normal file
@ -0,0 +1,48 @@
|
||||
namespace DarkUI.Docking
|
||||
{
|
||||
internal class DockDropCollection
|
||||
{
|
||||
#region Property Region
|
||||
|
||||
internal DockDropArea DropArea { get; private set; }
|
||||
|
||||
internal DockDropArea InsertBeforeArea { get; private set; }
|
||||
|
||||
internal DockDropArea InsertAfterArea { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor Region
|
||||
|
||||
internal DockDropCollection(DarkDockPanel dockPanel, DarkDockRegion region)
|
||||
{
|
||||
DropArea = new DockDropArea(region, DockInsertType.None);
|
||||
InsertBeforeArea = new DockDropArea(region, DockInsertType.Before);
|
||||
InsertAfterArea = new DockDropArea(region, DockInsertType.After);
|
||||
|
||||
BuildAreas();
|
||||
}
|
||||
|
||||
internal DockDropCollection(DarkDockPanel dockPanel, DarkDockGroup group)
|
||||
{
|
||||
DropArea = new DockDropArea(group, DockInsertType.None);
|
||||
InsertBeforeArea = new DockDropArea(group, DockInsertType.Before);
|
||||
InsertAfterArea = new DockDropArea(group, DockInsertType.After);
|
||||
|
||||
BuildAreas();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Method Region
|
||||
|
||||
private void BuildAreas()
|
||||
{
|
||||
DropArea.BuildAreas();
|
||||
InsertBeforeArea.BuildAreas();
|
||||
InsertAfterArea.BuildAreas();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
9
DarkUI/Docking/DockInsertType.cs
Normal file
9
DarkUI/Docking/DockInsertType.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace DarkUI.Docking
|
||||
{
|
||||
public enum DockInsertType
|
||||
{
|
||||
None,
|
||||
Before,
|
||||
After
|
||||
}
|
||||
}
|
@ -18,13 +18,12 @@ namespace DarkUI.Win32
|
||||
private DarkTranslucentForm _highlightForm;
|
||||
|
||||
private bool _isDragging = false;
|
||||
private bool _insert = false;
|
||||
private DarkDockRegion _targetRegion;
|
||||
private DarkDockGroup _targetGroup;
|
||||
private DockInsertType _insertType = DockInsertType.None;
|
||||
|
||||
private Dictionary<DarkDockRegion, Rectangle> _regionDropAreas = new Dictionary<DarkDockRegion, Rectangle>();
|
||||
private Dictionary<DarkDockGroup, Rectangle> _groupInsertDropAreas = new Dictionary<DarkDockGroup, Rectangle>();
|
||||
private Dictionary<DarkDockGroup, Rectangle> _groupDropAreas = new Dictionary<DarkDockGroup, Rectangle>();
|
||||
private Dictionary<DarkDockRegion, DockDropCollection> _regionDropAreas = new Dictionary<DarkDockRegion, DockDropCollection>();
|
||||
private Dictionary<DarkDockGroup, DockDropCollection> _groupDropAreas = new Dictionary<DarkDockGroup, DockDropCollection>();
|
||||
|
||||
#endregion
|
||||
|
||||
@ -73,10 +72,17 @@ namespace DarkUI.Win32
|
||||
{
|
||||
_dockPanel.RemoveContent(_dragContent);
|
||||
|
||||
if (_insert)
|
||||
_dockPanel.InsertContent(_dragContent, _targetGroup);
|
||||
else
|
||||
_dockPanel.AddContent(_dragContent, _targetGroup);
|
||||
switch (_insertType)
|
||||
{
|
||||
case DockInsertType.None:
|
||||
_dockPanel.AddContent(_dragContent, _targetGroup);
|
||||
break;
|
||||
|
||||
case DockInsertType.Before:
|
||||
case DockInsertType.After:
|
||||
_dockPanel.InsertContent(_dragContent, _targetGroup, _insertType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StopDrag();
|
||||
@ -92,71 +98,28 @@ namespace DarkUI.Win32
|
||||
|
||||
public void StartDrag(DarkDockContent content)
|
||||
{
|
||||
_regionDropAreas = new Dictionary<DarkDockRegion, Rectangle>();
|
||||
_groupInsertDropAreas = new Dictionary<DarkDockGroup, Rectangle>();
|
||||
_groupDropAreas = new Dictionary<DarkDockGroup, Rectangle>();
|
||||
_regionDropAreas = new Dictionary<DarkDockRegion, DockDropCollection>();
|
||||
_groupDropAreas = new Dictionary<DarkDockGroup, DockDropCollection>();
|
||||
|
||||
// Add all regions and groups to the drop collections
|
||||
foreach (var region in _dockPanel.Regions.Values)
|
||||
{
|
||||
if (region.DockArea == DarkDockArea.Document)
|
||||
continue;
|
||||
|
||||
// If the region is visible then build drop areas for the groups.
|
||||
if (region.Visible)
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
var insertRect = new Rectangle();
|
||||
|
||||
switch (group.DockArea)
|
||||
{
|
||||
case DarkDockArea.Left:
|
||||
case DarkDockArea.Right:
|
||||
|
||||
var top = rect.Top;
|
||||
|
||||
if (group.Order > 0)
|
||||
top -= 7;
|
||||
|
||||
insertRect = new Rectangle
|
||||
{
|
||||
X = rect.Left,
|
||||
Y = top,
|
||||
Width = rect.Width,
|
||||
Height = 15
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case DarkDockArea.Bottom:
|
||||
|
||||
var left = rect.Left;
|
||||
|
||||
if (group.Order > 0)
|
||||
left -= 7;
|
||||
|
||||
insertRect = new Rectangle
|
||||
{
|
||||
X = left,
|
||||
Y = rect.Top,
|
||||
Width = 15,
|
||||
Height = rect.Height
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
_groupDropAreas.Add(group, rect);
|
||||
_groupInsertDropAreas.Add(group, insertRect);
|
||||
var collection = new DockDropCollection(_dockPanel, group);
|
||||
_groupDropAreas.Add(group, collection);
|
||||
}
|
||||
}
|
||||
// If the region is NOT visible then build a drop area for the region itself.
|
||||
else
|
||||
{
|
||||
var rect = new Rectangle();
|
||||
/*var rect = new Rectangle();
|
||||
|
||||
switch (region.DockArea)
|
||||
{
|
||||
@ -211,7 +174,7 @@ namespace DarkUI.Win32
|
||||
break;
|
||||
}
|
||||
|
||||
_regionDropAreas.Add(region, rect);
|
||||
_regionDropAreas.Add(region, rect);*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,97 +184,143 @@ namespace DarkUI.Win32
|
||||
|
||||
private void StopDrag()
|
||||
{
|
||||
Cursor.Current = Cursors.Default;
|
||||
|
||||
_highlightForm.Hide();
|
||||
_dragContent = null;
|
||||
_isDragging = false;
|
||||
}
|
||||
|
||||
private void UpdateHighlightForm(Rectangle rect)
|
||||
{
|
||||
Cursor.Current = Cursors.SizeAll;
|
||||
|
||||
_highlightForm.SuspendLayout();
|
||||
|
||||
_highlightForm.Size = new Size(rect.Width, rect.Height);
|
||||
_highlightForm.Location = new Point(rect.X, rect.Y);
|
||||
|
||||
_highlightForm.ResumeLayout();
|
||||
|
||||
if (!_highlightForm.Visible)
|
||||
{
|
||||
_highlightForm.Show();
|
||||
_highlightForm.BringToFront();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDrag()
|
||||
{
|
||||
var location = Cursor.Position;
|
||||
|
||||
_insertType = DockInsertType.None;
|
||||
|
||||
_targetRegion = null;
|
||||
_targetGroup = null;
|
||||
|
||||
foreach (var keyValuePair in _regionDropAreas)
|
||||
// Check all region drop areas
|
||||
foreach (var collection in _regionDropAreas.Values)
|
||||
{
|
||||
var region = keyValuePair.Key;
|
||||
var rect = keyValuePair.Value;
|
||||
|
||||
if (rect.Contains(location))
|
||||
if (collection.InsertBeforeArea.DropArea.Contains(location))
|
||||
{
|
||||
_targetRegion = region;
|
||||
_insertType = DockInsertType.Before;
|
||||
_targetRegion = collection.InsertBeforeArea.DockRegion;
|
||||
UpdateHighlightForm(collection.InsertBeforeArea.HighlightArea);
|
||||
return;
|
||||
}
|
||||
|
||||
_highlightForm.Location = new Point(rect.X, rect.Y);
|
||||
_highlightForm.Size = new Size(rect.Width, rect.Height);
|
||||
if (collection.InsertAfterArea.DropArea.Contains(location))
|
||||
{
|
||||
_insertType = DockInsertType.After;
|
||||
_targetRegion = collection.InsertAfterArea.DockRegion;
|
||||
UpdateHighlightForm(collection.InsertAfterArea.HighlightArea);
|
||||
return;
|
||||
}
|
||||
|
||||
if (collection.DropArea.DropArea.Contains(location))
|
||||
{
|
||||
_insertType = DockInsertType.None;
|
||||
_targetRegion = collection.DropArea.DockRegion;
|
||||
UpdateHighlightForm(collection.DropArea.HighlightArea);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var inserting = false;
|
||||
|
||||
foreach (var keyValuePair in _groupInsertDropAreas)
|
||||
// Check all group drop areas
|
||||
foreach (var collection in _groupDropAreas.Values)
|
||||
{
|
||||
var group = keyValuePair.Key;
|
||||
var rect = keyValuePair.Value;
|
||||
var sameRegion = false;
|
||||
var sameGroup = false;
|
||||
var groupHasOtherContent = false;
|
||||
|
||||
if (group.DockRegion == _dragContent.DockGroup.DockRegion)
|
||||
if (collection.DropArea.DockGroup == _dragContent.DockGroup)
|
||||
{
|
||||
if (group == _dragContent.DockGroup)
|
||||
continue;
|
||||
sameGroup = true;
|
||||
|
||||
if (_dragContent.DockGroup.Order == group.Order - 1)
|
||||
continue;
|
||||
if (collection.DropArea.DockGroup.ContentCount > 1)
|
||||
groupHasOtherContent = true;
|
||||
}
|
||||
|
||||
if (rect.Contains(location))
|
||||
if (collection.DropArea.DockGroup.DockRegion == _dragContent.DockRegion)
|
||||
{
|
||||
inserting = true;
|
||||
|
||||
_insert = true;
|
||||
_targetGroup = group;
|
||||
|
||||
_highlightForm.Location = new Point(rect.X, rect.Y);
|
||||
_highlightForm.Size = new Size(rect.Width, rect.Height);
|
||||
sameRegion = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inserting)
|
||||
{
|
||||
foreach (var keyValuePair in _groupDropAreas)
|
||||
if (!sameGroup || groupHasOtherContent)
|
||||
{
|
||||
var group = keyValuePair.Key;
|
||||
var rect = keyValuePair.Value;
|
||||
var skipBefore = false;
|
||||
var skipAfter = false;
|
||||
|
||||
if (group == _dragContent.DockGroup)
|
||||
continue;
|
||||
|
||||
if (group.DockArea == DarkDockArea.Document)
|
||||
continue;
|
||||
|
||||
if (rect.Contains(location))
|
||||
if (sameRegion && !groupHasOtherContent)
|
||||
{
|
||||
_insert = false;
|
||||
_targetGroup = group;
|
||||
if (collection.InsertBeforeArea.DockGroup.Order == _dragContent.DockGroup.Order + 1)
|
||||
skipBefore = true;
|
||||
|
||||
_highlightForm.Location = new Point(rect.X, rect.Y);
|
||||
_highlightForm.Size = new Size(rect.Width, rect.Height);
|
||||
if (collection.InsertAfterArea.DockGroup.Order == _dragContent.DockGroup.Order - 1)
|
||||
skipAfter = true;
|
||||
}
|
||||
|
||||
if (!skipBefore)
|
||||
{
|
||||
if (collection.InsertBeforeArea.DropArea.Contains(location))
|
||||
{
|
||||
_insertType = DockInsertType.Before;
|
||||
_targetGroup = collection.InsertBeforeArea.DockGroup;
|
||||
UpdateHighlightForm(collection.InsertBeforeArea.HighlightArea);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipAfter)
|
||||
{
|
||||
if (collection.InsertAfterArea.DropArea.Contains(location))
|
||||
{
|
||||
_insertType = DockInsertType.After;
|
||||
_targetGroup = collection.InsertAfterArea.DockGroup;
|
||||
UpdateHighlightForm(collection.InsertAfterArea.HighlightArea);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sameGroup)
|
||||
{
|
||||
if (collection.DropArea.DropArea.Contains(location))
|
||||
{
|
||||
_insertType = DockInsertType.None;
|
||||
_targetGroup = collection.DropArea.DockGroup;
|
||||
UpdateHighlightForm(collection.DropArea.HighlightArea);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_targetRegion == null && _targetGroup == null)
|
||||
{
|
||||
if (_highlightForm.Visible)
|
||||
_highlightForm.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_highlightForm.Visible)
|
||||
{
|
||||
_highlightForm.Show();
|
||||
_highlightForm.BringToFront();
|
||||
}
|
||||
}
|
||||
// Not hovering over anything - hide the highlight
|
||||
if (_highlightForm.Visible)
|
||||
_highlightForm.Hide();
|
||||
|
||||
// Show we can't drag here
|
||||
Cursor.Current = Cursors.No;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
Loading…
x
Reference in New Issue
Block a user