Revert "Revert "block 可以拖拽到内部,还有少量问题待解决""

This reverts commit fcd7beb193.
This commit is contained in:
艾竹
2023-06-11 23:58:22 +08:00
parent fcd7beb193
commit 5a9bcc03f3
73 changed files with 7132 additions and 242 deletions

View File

@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Models;
namespace AIStudio.Wpf.DiagramDesigner
{
public class ItemsContainerInfo : SelectableViewModelBase
{
public ItemsContainerInfo(BlockDesignerItemViewModel dataItem) : this(null, dataItem)
{
}
public ItemsContainerInfo(IDiagramViewModel root, BlockDesignerItemViewModel dataItem) : base(root)
{
this.Parent = dataItem;
}
public ItemsContainerInfo(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
{
}
public ItemsContainerInfo(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
{
}
//public override SelectableItemBase GetSerializableObject()
//{
// return new ConnectorInfoItemBase(this);
//}
protected override void Init(IDiagramViewModel root, bool initNew)
{
base.Init(root, initNew);
}
protected override void InitNew()
{
ColorViewModel = new ColorViewModel()
{
LineWidth = 1,
LineColor = new ColorObject() { Color = Color.FromArgb(0xAA, 0x00, 0x00, 0x80) },
FillColor = new ColorObject() { Color = Colors.Transparent },
};
}
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
{
base.LoadDesignerItemViewModel(designerbase);
//if (designerbase is ConnectorInfoItemBase designer)
//{
// PhysicalConnectorWidth = designer.PhysicalConnectorWidth;
// PhysicalConnectorHeight = designer.PhysicalConnectorHeight;
// Orientation = designer.Orientation;
//}
}
#region
private double _itemWidth = double.NaN;
public double ItemWidth
{
get
{
return _itemWidth;
}
set
{
if (value <= 0) return;
SetProperty(ref _itemWidth, value);
}
}
private double _itemHeight = double.NaN;
public double ItemHeight
{
get
{
return _itemHeight;
}
set
{
if (value <= 0) return;
SetProperty(ref _itemHeight, value);
}
}
private double _actualItemWidth;
public double ActualItemWidth
{
get
{
return _actualItemWidth;
}
set
{
SetProperty(ref _actualItemWidth, value);
}
}
private double _actualItemHeight;
public double ActualItemHeight
{
get
{
return _actualItemHeight;
}
set
{
SetProperty(ref _actualItemHeight, value);
}
}
//public PointBase Position
//{
// get
// {
// var offset = GetOffSetFunc?.Invoke() ?? new Point(0, 0);
// return new PointBase(DataItem.Left + offset.X, DataItem.Top + offset.Y);
// }
//}
//public PointBase MiddlePosition
//{
// get
// {
// return new PointBase(Position.X + GetItemWidth() / 2, Position.Y + GetItemHeight() / 2);
// }
//}
public RectangleBase GetBounds()
{
var offset = GetOffSetFunc?.Invoke() ?? new Point(0, 0);
return new RectangleBase(DataItem.Left + offset.X, DataItem.Top + offset.Y, GetItemWidth(), GetItemHeight());
}
public BlockDesignerItemViewModel DataItem
{
get
{
return Parent as BlockDesignerItemViewModel;
}
}
public ObservableCollection<BlockDesignerItemViewModel> Children
{
get; set;
} = new ObservableCollection<BlockDesignerItemViewModel>();
private Func<Point> _getOffSetFunc;
public Func<Point> GetOffSetFunc
{
get
{
return _getOffSetFunc;
}
set
{
SetProperty(ref _getOffSetFunc, value);
}
}
private bool _beAttachTo;
public bool BeAttachTo
{
get
{
return _beAttachTo;
}
set
{
SetProperty(ref _beAttachTo, value);
}
}
private bool _disableAttachTo;
public bool DisableAttachTo
{
get
{
return _disableAttachTo;
}
set
{
SetProperty(ref _disableAttachTo, value);
}
}
public virtual bool CanAttachTo(DesignerItemViewModelBase item)
=> item != null && item != this.DataItem && !item.IsReadOnly && item is BlockDesignerItemViewModel;
#endregion
public double GetItemWidth()
{
return double.IsNaN(ItemWidth) ? ActualItemWidth : ItemWidth;
}
public double GetItemHeight()
{
return double.IsNaN(ItemHeight) ? ActualItemHeight : ItemHeight;
}
}
}

View File

@@ -261,7 +261,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get
{
return new SizeBase(ItemWidth, ItemHeight);
return new SizeBase(GetItemWidth(), GetItemHeight());
}
set
{
@@ -445,7 +445,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get
{
return new Point(Left + ItemWidth, Top + ItemHeight);
return new Point(Left + GetItemWidth(), Top + GetItemHeight());
}
}
@@ -557,6 +557,32 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private double _actualItemWidth;
public double ActualItemWidth
{
get
{
return _actualItemWidth;
}
set
{
SetProperty(ref _actualItemWidth, value);
}
}
private double _actualItemHeight;
public double ActualItemHeight
{
get
{
return _actualItemHeight;
}
set
{
SetProperty(ref _actualItemHeight, value);
}
}
/// <summary>
/// 连接点是否可以按偏移自定义
/// </summary>
@@ -637,9 +663,9 @@ namespace AIStudio.Wpf.DiagramDesigner
{
if (Root.DiagramOption.LayoutOption.CellHorizontalAlignment == CellHorizontalAlignment.Center)
{
if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.ItemWidth)
if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.GetItemWidth())
{
this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.ItemWidth) / 2;
this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.GetItemWidth()) / 2;
}
}
else if (Root.DiagramOption.LayoutOption.CellHorizontalAlignment == CellHorizontalAlignment.Left)
@@ -648,17 +674,17 @@ namespace AIStudio.Wpf.DiagramDesigner
}
else if (Root.DiagramOption.LayoutOption.CellHorizontalAlignment == CellHorizontalAlignment.Right)
{
if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.ItemWidth)
if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.GetItemWidth())
{
this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.ItemWidth);
this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.GetItemWidth());
}
}
if (Root.DiagramOption.LayoutOption.CellVerticalAlignment == CellVerticalAlignment.Center)
{
if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.ItemHeight)
if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.GetItemHeight())
{
this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.ItemHeight) / 2;
this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.GetItemHeight()) / 2;
}
}
else if (Root.DiagramOption.LayoutOption.CellVerticalAlignment == CellVerticalAlignment.Top)
@@ -667,9 +693,9 @@ namespace AIStudio.Wpf.DiagramDesigner
}
else if (Root.DiagramOption.LayoutOption.CellVerticalAlignment == CellVerticalAlignment.Bottom)
{
if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.ItemHeight)
if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.GetItemHeight())
{
this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.ItemHeight);
this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.GetItemHeight());
}
}
}
@@ -740,14 +766,24 @@ namespace AIStudio.Wpf.DiagramDesigner
var left = leftPort == null ? Position.X : Math.Min(Position.X, leftPort.Position.X);
var top = topPort == null ? Position.Y : Math.Min(Position.Y, topPort.Position.Y);
var right = rightPort == null ? Position.X + ItemWidth :
Math.Max(rightPort.Position.X + rightPort.ConnectorWidth, Position.X + ItemWidth);
var right = rightPort == null ? Position.X + GetItemWidth() :
Math.Max(rightPort.Position.X + rightPort.ConnectorWidth, Position.X + GetItemWidth());
var bottom = bottomPort == null ? Position.Y + ItemHeight :
Math.Max(bottomPort.Position.Y + bottomPort.ConnectorHeight, Position.Y + ItemHeight);
Math.Max(bottomPort.Position.Y + bottomPort.ConnectorHeight, Position.Y + GetItemHeight());
return new RectangleBase(left, top, right, bottom, true);
}
public double GetItemWidth()
{
return double.IsNaN(ItemWidth) ? ActualItemWidth : ItemWidth;
}
public double GetItemHeight()
{
return double.IsNaN(ItemHeight) ? ActualItemHeight : ItemHeight;
}
public IShape GetShape() => ShapeDefiner(this);
public override string ToString()

View File

@@ -1449,7 +1449,7 @@ namespace AIStudio.Wpf.DiagramDesigner
return items;
}
protected void ExecuteDeleteCommand(object parameter)
protected virtual void ExecuteDeleteCommand(object parameter)
{
var items = Delete(parameter, false);
if (items.Any())
@@ -1580,11 +1580,11 @@ namespace AIStudio.Wpf.DiagramDesigner
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double mid = selectedItems.Select(p => p.Top + p.ItemHeight / 2).Average();
double mid = selectedItems.Select(p => p.Top + p.GetItemHeight() / 2).Average();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = mid - item.ItemHeight / 2;
item.Top = mid - item.GetItemHeight() / 2;
}
},
() => {
@@ -1618,11 +1618,11 @@ namespace AIStudio.Wpf.DiagramDesigner
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double top = selectedItems.OrderBy(p => p.Top + p.ItemHeight).Select(p => p.Top + p.ItemHeight).LastOrDefault();
double top = selectedItems.OrderBy(p => p.Top + p.GetItemHeight()).Select(p => p.Top + p.GetItemHeight()).LastOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = top - item.ItemHeight;
item.Top = top - item.GetItemHeight();
}
},
() => {
@@ -1694,11 +1694,11 @@ namespace AIStudio.Wpf.DiagramDesigner
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double mid = selectedItems.Select(p => p.Left + p.ItemWidth / 2).Average();
double mid = selectedItems.Select(p => p.Left + p.GetItemWidth() / 2).Average();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = mid - item.ItemWidth / 2;
item.Left = mid - item.GetItemWidth() / 2;
}
},
() => {
@@ -1732,11 +1732,11 @@ namespace AIStudio.Wpf.DiagramDesigner
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double right = selectedItems.OrderBy(p => p.Left + p.ItemWidth).Select(p => p.Left + p.ItemWidth).LastOrDefault();
double right = selectedItems.OrderBy(p => p.Left + p.GetItemWidth()).Select(p => p.Left + p.GetItemWidth()).LastOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = right - item.ItemWidth;
item.Left = right - item.GetItemWidth();
}
},
() => {
@@ -1975,8 +1975,8 @@ namespace AIStudio.Wpf.DiagramDesigner
foreach (DesignerItemViewModelBase item in selectedItems)
{
left = Math.Min(left, item.Left);
right = Math.Max(right, item.Left + item.ItemWidth);
sumWidth += item.ItemWidth;
right = Math.Max(right, item.Left + item.GetItemWidth());
sumWidth += item.GetItemWidth();
}
double distance = Math.Max(0, (right - left - sumWidth) / (selectedItems.Count() - 1));
@@ -1989,7 +1989,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
di.Left += delta;
}
offset = offset + item.ItemWidth + distance;
offset = offset + item.GetItemWidth() + distance;
}
},
@@ -2030,8 +2030,8 @@ namespace AIStudio.Wpf.DiagramDesigner
foreach (DesignerItemViewModelBase item in selectedItems)
{
top = Math.Min(top, item.Top);
bottom = Math.Max(bottom, item.Top + item.ItemHeight);
sumHeight += item.ItemHeight;
bottom = Math.Max(bottom, item.Top + item.GetItemHeight());
sumHeight += item.GetItemHeight();
}
double distance = Math.Max(0, (bottom - top - sumHeight) / (selectedItems.Count() - 1));
@@ -2044,7 +2044,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
di.Top += +delta;
}
offset = offset + item.ItemHeight + distance;
offset = offset + item.GetItemHeight() + distance;
}
},
() => {
@@ -2264,8 +2264,8 @@ namespace AIStudio.Wpf.DiagramDesigner
() => {
foreach (var item in selectedItems)
{
item.ItemWidth = selectedItems.FirstOrDefault().ItemWidth;
item.ItemHeight = selectedItems.FirstOrDefault().ItemHeight;
item.ItemWidth = selectedItems.FirstOrDefault().GetItemWidth();
item.ItemHeight = selectedItems.FirstOrDefault().GetItemHeight();
}
},
() => {
@@ -2295,13 +2295,13 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count > 1)
{
Dictionary<DesignerItemViewModelBase, double> infos = selectedItems.ToDictionary(p => p, p => p.ItemWidth);
Dictionary<DesignerItemViewModelBase, double> infos = selectedItems.ToDictionary(p => p, p => p.GetItemWidth());
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in selectedItems)
{
item.ItemWidth = selectedItems.FirstOrDefault().ItemWidth;
item.ItemWidth = selectedItems.FirstOrDefault().GetItemWidth();
}
},
() => {
@@ -2331,13 +2331,13 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count > 1)
{
Dictionary<DesignerItemViewModelBase, double> infos = selectedItems.ToDictionary(p => p, p => p.ItemHeight);
Dictionary<DesignerItemViewModelBase, double> infos = selectedItems.ToDictionary(p => p, p => p.GetItemHeight());
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in selectedItems)
{
item.ItemHeight = selectedItems.FirstOrDefault().ItemHeight;
item.ItemHeight = selectedItems.FirstOrDefault().GetItemHeight();
}
},
() => {
@@ -3145,6 +3145,37 @@ namespace AIStudio.Wpf.DiagramDesigner
return new Tuple<FullyCreatedConnectorInfo, FullyCreatedConnectorInfo>(parent, next);
}
public ItemsContainerInfo FindNearContainerToAttachTo(BlockDesignerItemViewModel blockDesignerItemViewModel)
{
if (blockDesignerItemViewModel == null)
return null;
List<BlockDesignerItemViewModel> items;
items = Items.OfType<BlockDesignerItemViewModel>().
Where(p => p != blockDesignerItemViewModel)
.ToList();
foreach (var port in items.SelectMany(n => n.Contains))
{
if (port.GetBounds().IntersectsWith(blockDesignerItemViewModel.GetBounds())) //如果两个位置相交
{
port.DataItem.ShowConnectors = true;
if (port.CanAttachTo(blockDesignerItemViewModel) == true)
{
port.BeAttachTo = true;
}
else
{
port.DisableAttachTo = true;
}
return port;
}
}
return null;
}
public void ClearNearPort()
{
Items.OfType<DesignerItemViewModelBase>().ToList().SelectMany(n => n.Connectors).Where(p => p.BeAttachTo == true || p.DisableAttachTo == true).ToList()
@@ -3152,6 +3183,91 @@ namespace AIStudio.Wpf.DiagramDesigner
p.DisableAttachTo = false;
p.BeAttachTo = false;
});
}
public void ClearNearContain()
{
Items.OfType<BlockDesignerItemViewModel>().ToList().SelectMany(n => n.Contains).Where(p => p.BeAttachTo == true || p.DisableAttachTo == true).ToList()
.ForEach(p => {
p.DisableAttachTo = false;
p.BeAttachTo = false;
});
}
#endregion
#region Block拖拽预览-
public void PreviewNearBlock(List<BlockDesignerItemViewModel> blocks)
{
if (blocks.Any())
{
ClearNearPort();
ClearNearContain();
foreach (BlockDesignerItemViewModel item in blocks)
{
var contain = FindNearContainerToAttachTo(item);
if (contain != null)
{
continue;
}
FindNearPortToAttachTo(item, false);
}
}
}
public void FinishNearBlock(List<BlockDesignerItemViewModel> blocks)
{
if (blocks.Any())
{
ClearNearPort();
ClearNearContain();
foreach (BlockDesignerItemViewModel item in blocks)
{
var contain = FindNearContainerToAttachTo(item);
if (contain != null)
{
(contain.DataItem as BlockDesignerItemViewModel).AddChild(item);
contain.BeAttachTo = false;
contain.DisableAttachTo = false;
continue;
}
var portTuple = FindNearPortToAttachTo(item, true);
var portParent = portTuple.Item1;
var portNext = portTuple.Item2;
if (portParent != null)
{
(portParent.DataItem as BlockDesignerItemViewModel).AddNext(item);
portParent.BeAttachTo = false;
portParent.DisableAttachTo = false;
}
else
{
if (item.Parent != null)
{
(item.Parent as BlockDesignerItemViewModel).RemoveNext();
}
}
if (portNext != null)
{
item.AddNext(portNext.DataItem as BlockDesignerItemViewModel);
portNext.BeAttachTo = false;
portNext.DisableAttachTo = false;
}
else
{
if (item.Next != null)
{
item.RemoveNext();
}
}
}
}
}
#endregion

View File

@@ -26,8 +26,8 @@ namespace AIStudio.Wpf.DiagramDesigner
x1 = Math.Min(item.Left, x1);
y1 = Math.Min(item.Top, y1);
x2 = Math.Max(item.Left + item.ItemWidth, x2);
y2 = Math.Max(item.Top + item.ItemHeight, y2);
x2 = Math.Max(item.Left + item.GetItemWidth(), x2);
y2 = Math.Max(item.Top + item.GetItemHeight(), y2);
}
return new RectangleBase(new PointBase(x1, y1), new PointBase(x2, y2));