mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-15 05:36:35 +08:00
EnableSnapping完成
This commit is contained in:
@@ -17,8 +17,20 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class DesignerCanvas : Canvas
|
||||
{
|
||||
private IDiagramViewModel _viewModel { get { return DataContext as IDiagramViewModel; } }
|
||||
private IDiagramServiceProvider _service { get { return DiagramServicesProvider.Instance.Provider; } }
|
||||
private IDiagramViewModel _viewModel
|
||||
{
|
||||
get
|
||||
{
|
||||
return DataContext as IDiagramViewModel;
|
||||
}
|
||||
}
|
||||
private IDiagramServiceProvider _service
|
||||
{
|
||||
get
|
||||
{
|
||||
return DiagramServicesProvider.Instance.Provider;
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectionViewModel partialConnection;
|
||||
private List<Connector> connectorsHit = new List<Connector>();
|
||||
@@ -54,6 +66,22 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
}
|
||||
|
||||
private bool EnableSnapping
|
||||
{
|
||||
get
|
||||
{
|
||||
return _viewModel.EnableSnapping;
|
||||
}
|
||||
}
|
||||
|
||||
private double SnappingRadius
|
||||
{
|
||||
get
|
||||
{
|
||||
return _viewModel.SnappingRadius;
|
||||
}
|
||||
}
|
||||
|
||||
#region GridCellSize
|
||||
|
||||
public static readonly DependencyProperty GridCellSizeProperty =
|
||||
@@ -64,8 +92,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public Size GridCellSize
|
||||
{
|
||||
get { return (Size)GetValue(GridCellSizeProperty); }
|
||||
set { SetValue(GridCellSizeProperty, value); }
|
||||
get
|
||||
{
|
||||
return (Size)GetValue(GridCellSizeProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(GridCellSizeProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -80,8 +114,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public bool ShowGrid
|
||||
{
|
||||
get { return (bool)GetValue(ShowGridProperty); }
|
||||
set { SetValue(ShowGridProperty, value); }
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(ShowGridProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ShowGridProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -96,8 +136,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public Color GridColor
|
||||
{
|
||||
get { return (Color)GetValue(GridColorProperty); }
|
||||
set { SetValue(GridColorProperty, value); }
|
||||
get
|
||||
{
|
||||
return (Color)GetValue(GridColorProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(GridColorProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -112,8 +158,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public Size GridMarginSize
|
||||
{
|
||||
get { return (Size)GetValue(GridMarginSizeProperty); }
|
||||
set { SetValue(GridMarginSizeProperty, value); }
|
||||
get
|
||||
{
|
||||
return (Size)GetValue(GridMarginSizeProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(GridMarginSizeProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -204,7 +256,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
private Connector sourceConnector;
|
||||
public Connector SourceConnector
|
||||
{
|
||||
get { return sourceConnector; }
|
||||
get
|
||||
{
|
||||
return sourceConnector;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (sourceConnector != value)
|
||||
@@ -218,7 +273,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
|
||||
rectangleBounds.Bottom + (rectangleBounds.Height / 2));
|
||||
partialConnection = new ConnectionViewModel(_viewModel, sourceDataItem, new PartCreatedConnectorInfo(point.X, point.Y), DrawMode, RouterMode);
|
||||
|
||||
|
||||
_viewModel.DirectAddItemCommand.Execute(partialConnection);
|
||||
}
|
||||
}
|
||||
@@ -227,7 +282,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
private FullyCreatedConnectorInfo sourceConnectorInfo;
|
||||
public FullyCreatedConnectorInfo SourceConnectorInfo
|
||||
{
|
||||
get { return sourceConnectorInfo; }
|
||||
get
|
||||
{
|
||||
return sourceConnectorInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (sourceConnectorInfo != value)
|
||||
@@ -288,7 +346,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
if (connectorsHit.Count == 0)
|
||||
{
|
||||
LinkPointDesignerItemViewModel pointItemView = new LinkPointDesignerItemViewModel(rubberbandSelectionStartPoint.Value);
|
||||
LinkPointDesignerItemViewModel pointItemView = new LinkPointDesignerItemViewModel(rubberbandSelectionStartPoint.Value);
|
||||
_viewModel.DirectAddItemCommand.Execute(pointItemView);
|
||||
SourceConnectorInfo = pointItemView.TopConnector;
|
||||
}
|
||||
@@ -311,8 +369,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
if (_service.DrawModeViewModel.CursorMode == CursorMode.Move)
|
||||
{
|
||||
_viewModel.SelectedItems.OfType<DesignerItemViewModelBase>().ToList().ForEach(p =>
|
||||
{
|
||||
_viewModel.SelectedItems.OfType<DesignerItemViewModelBase>().ToList().ForEach(p => {
|
||||
p.Left = currentPoint.X;
|
||||
p.Top = currentPoint.Y;
|
||||
});
|
||||
@@ -325,6 +382,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
partialConnection.SinkConnectorInfo = new PartCreatedConnectorInfo(currentPoint.X, currentPoint.Y);
|
||||
HitTesting(currentPoint);
|
||||
|
||||
if (EnableSnapping)
|
||||
{
|
||||
var nearPort = FindNearPortToAttachTo();
|
||||
if (nearPort != null || partialConnection.SinkConnectorInfoFully != null)
|
||||
{
|
||||
//var oldPort = _ongoingLink.TargetPort;
|
||||
//_ongoingLink.SetTargetPort(nearPort);
|
||||
//oldPort?.Refresh();
|
||||
//nearPort?.Refresh();
|
||||
partialConnection.SinkConnectorInfo = nearPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -377,6 +447,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
sinkDataItem.DataItem.Root.DirectRemoveItemCommand.Execute(
|
||||
sinkDataItem.DataItem.Root.Items[indexOfLastTempConnection]);
|
||||
sinkDataItem.DataItem.Root.AddItemCommand.Execute(new ConnectionViewModel(_viewModel, sourceDataItem, sinkDataItem, DrawMode, RouterMode));
|
||||
}
|
||||
else if (partialConnection.IsFullConnection)
|
||||
{
|
||||
|
||||
}
|
||||
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine && connectorsHit.Count() == 1)
|
||||
{
|
||||
@@ -403,7 +477,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
connectorsHit = new List<Connector>();
|
||||
sourceConnector = null;
|
||||
sourceConnectorInfo = null;
|
||||
@@ -508,7 +582,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
itemBase.Suffix = System.IO.Path.GetExtension(itemBase.Icon).ToLower();
|
||||
itemBase.InitWidthAndHeight();
|
||||
itemBase.AutoSize();
|
||||
|
||||
|
||||
itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2);
|
||||
itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2);
|
||||
(DataContext as IDiagramViewModel).AddItemCommand.Execute(itemBase);
|
||||
@@ -516,5 +590,17 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
public FullyCreatedConnectorInfo FindNearPortToAttachTo()
|
||||
{
|
||||
foreach (var port in _viewModel.Items.OfType<DesignerItemViewModelBase>().ToList().SelectMany(n => n.Connectors))
|
||||
{
|
||||
if (partialConnection.OnGoingPosition.DistanceTo(port.Position) < SnappingRadius &&
|
||||
partialConnection.SourceConnectorInfo.CanAttachTo(port))
|
||||
return port;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,7 @@
|
||||
</Path>
|
||||
|
||||
<Path x:Name="rightarrow"
|
||||
Data="{Binding ShapeViewModel.SinkMarker.Path}"
|
||||
Visibility="{Binding Path=IsFullConnection, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
|
||||
Data="{Binding ShapeViewModel.SinkMarker.Path}"
|
||||
Width="{Binding ShapeViewModel.SinkMarker.Width}"
|
||||
Stretch="UniformToFill"
|
||||
HorizontalAlignment="Left"
|
||||
@@ -61,8 +60,7 @@
|
||||
</Path>
|
||||
|
||||
<Path x:Name="leftarrow"
|
||||
Data="{Binding ShapeViewModel.SourceMarker.Path}"
|
||||
Visibility="{Binding Path=IsFullConnection, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
|
||||
Data="{Binding ShapeViewModel.SourceMarker.Path}"
|
||||
Width="{Binding ShapeViewModel.SourceMarker.Width}"
|
||||
Canvas.Left="{Binding StartPoint.X}"
|
||||
Canvas.Top="{Binding StartPoint.Y}"
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
public FullyCreatedConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, ValueTypePoint valueTypePoint = 0)
|
||||
: base(orientation)
|
||||
{
|
||||
this.DataItem = dataItem;
|
||||
this.Parent = dataItem;
|
||||
this.IsInnerPoint = isInnerPoint;
|
||||
this.ValueTypePoint = valueTypePoint;
|
||||
if (IsInnerPoint == true)
|
||||
@@ -24,7 +24,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
this.DataItem = dataItem;
|
||||
this.Parent = dataItem;
|
||||
if (IsInnerPoint == true)
|
||||
{
|
||||
BuildMenuOptions();
|
||||
@@ -33,7 +33,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
this.DataItem = dataItem;
|
||||
this.Parent = dataItem;
|
||||
if (IsInnerPoint == true)
|
||||
{
|
||||
BuildMenuOptions();
|
||||
@@ -88,7 +88,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public DesignerItemViewModelBase DataItem
|
||||
{
|
||||
get; private set;
|
||||
get
|
||||
{
|
||||
return Parent as DesignerItemViewModelBase;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _showConnectors = false;
|
||||
@@ -257,6 +260,8 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanAttachTo(FullyCreatedConnectorInfo port) => port != this && !port.IsReadOnly && DataItem != port.DataItem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -366,6 +366,31 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
}
|
||||
|
||||
private bool _enableSnapping;
|
||||
public bool EnableSnapping
|
||||
{
|
||||
get
|
||||
{
|
||||
return _enableSnapping;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _enableSnapping, value);
|
||||
}
|
||||
}
|
||||
|
||||
private double _snappingRadius = 50;
|
||||
public double SnappingRadius
|
||||
{
|
||||
get
|
||||
{
|
||||
return _snappingRadius;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _snappingRadius, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isEditName;
|
||||
[Browsable(false)]
|
||||
@@ -1089,7 +1114,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void ExecuteBringForwardCommand(object parameter)
|
||||
{
|
||||
@@ -1391,7 +1416,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
SelectedItems.OfType<DesignerItemViewModelBase>().ToList();
|
||||
|
||||
List<ConnectionViewModel> selectedConnections =
|
||||
SelectedItems.OfType<ConnectionViewModel>().ToList();
|
||||
SelectedItems.OfType<ConnectionViewModel>().ToList();
|
||||
|
||||
foreach (ConnectionViewModel connection in Items.OfType<ConnectionViewModel>())
|
||||
{
|
||||
@@ -1444,7 +1469,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
foreach (var diagramItemData in copyitem.DesignerItems)
|
||||
{
|
||||
DesignerItemViewModelBase newItem = null;
|
||||
|
||||
|
||||
Type type = TypeHelper.GetType(diagramItemData.ModelTypeName);
|
||||
|
||||
DesignerItemViewModelBase itemBase = Activator.CreateInstance(type, this, diagramItemData, ".json") as DesignerItemViewModelBase;
|
||||
@@ -1460,7 +1485,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
items.Add(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DirectAddItemCommand.Execute(items);
|
||||
OffsetX += 10;
|
||||
@@ -1751,7 +1776,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -228,6 +228,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
bool EnableSnapping
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
double SnappingRadius
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
Size GridMarginSize
|
||||
{
|
||||
get; set;
|
||||
|
||||
Reference in New Issue
Block a user