This commit is contained in:
kwai
2023-02-27 20:18:58 +08:00
parent 298ec29dd9
commit f8c2115f03
21 changed files with 326 additions and 75 deletions

View File

@@ -12,6 +12,10 @@
<Description>一个Wpf的Diagram控件基础库</Description>
</PropertyGroup>
<ItemGroup>
<Compile Remove="PathGenerators\PathGenerators.FishBone.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Images\file.png" />
<None Remove="Images\FormatPainter.cur" />
@@ -19,6 +23,7 @@
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="PathGenerators\PathGenerators.FishBone.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -7,6 +7,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public enum RouterMode
{
RouterNormal,
RouterOrthogonal
RouterOrthogonal,
RouterFishBone
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public static partial class PathGenerators
{
public static PathGeneratorResult Straight(IDiagramViewModel _, ConnectionViewModel link, PointBase[] route, PointBase source, PointBase target)
{
route = ConcatRouteAndSourceAndTarget(route, source, target);
double sourceAngle = SourceMarkerAdjustement(route, link.GetSourceMarkerWidth(), link.GetSourceMarkerHeight());
double targetAngle = TargetMarkerAdjustement(route, link.GetSinkMarkerWidth(), link.GetSinkMarkerHeight());
DoShift(route, link);
var paths = new string[route.Length - 1];
for (var i = 0; i < route.Length - 1; i++)
{
paths[i] = FormattableString.Invariant($"M {route[i].X} {route[i].Y} L {route[i + 1].X} {route[i + 1].Y}");
}
return new PathGeneratorResult(paths, sourceAngle, route[0], targetAngle, route[route.Length - 1]);
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public class RouterFishBone : IRouter
{
public PointBase[] Get(IDiagramViewModel _, ConnectionViewModel link)
{
return Routers.FishBone(_, link);
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
// Implementation taken from the JS version: https://gist.github.com/menendezpoo/4a8894c152383b9d7a870c24a04447e4
// Todo: Make it more c#, Benchmark A* vs Dijkstra, Add more options
namespace AIStudio.Wpf.DiagramDesigner
{
public static partial class Routers
{
public static PointBase[] FishBone(IDiagramViewModel _, ConnectionViewModel link)
{
if (link.IsPortless)
throw new Exception("Orthogonal router doesn't work with portless links yet");
if (link.IsFullConnection == false)
return Normal(_, link);
double x2 = link.SourceConnectorInfo.MiddlePosition.X < link.SinkConnectorInfoFully.MiddlePosition.X ?
link.SinkConnectorInfoFully.MiddlePosition.X - Math.Abs(link.SourceConnectorInfo.MiddlePosition.Y - link.SinkConnectorInfoFully.MiddlePosition.Y)
: link.SinkConnectorInfoFully.MiddlePosition.X + Math.Abs(link.SourceConnectorInfo.MiddlePosition.Y - link.SinkConnectorInfoFully.MiddlePosition.Y);
double y2 = link.SourceConnectorInfo.MiddlePosition.Y;
return new PointBase[] { new PointBase(x2, y2) };
}
}
}

View File

@@ -38,6 +38,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
shapeMargin = 0;
inflatedA = shapeA;
inflatedB = shapeB;
}

View File

@@ -32,9 +32,9 @@ namespace AIStudio.Wpf.DiagramDesigner
{
InitializeComponent();
this.Loaded += TextControl_Loaded;
}
this.Loaded += TextControl_Loaded;
this.PART_ShowText.IsVisibleChanged += PART_ShowText_IsVisibleChanged;
}
private void TextControl_Loaded(object sender, RoutedEventArgs e)
{
@@ -56,6 +56,14 @@ namespace AIStudio.Wpf.DiagramDesigner
TextControl_PropertyChanged(this.DataContext, new System.ComponentModel.PropertyChangedEventArgs("IsSelected"));
}
private void PART_ShowText_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (this.DataContext is ISelectable selectable)
{
selectable.IsEditing = PART_ShowText.IsVisible;
}
}
private void TextControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSelected")

View File

@@ -686,6 +686,11 @@ namespace AIStudio.Wpf.DiagramDesigner
SinkConnectorInfo = port;
}
public void SetVisible(bool visible)
{
Visible = visible;
}
public double GetSourceMarkerWidth()
{
if (!IsFullConnection || string.IsNullOrEmpty(ShapeViewModel.SourceMarker.Path))

View File

@@ -3,8 +3,10 @@ using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.Common;
using System.Linq;
using System.Reactive.Linq;
using System.Reflection.Metadata;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
@@ -836,16 +838,44 @@ namespace AIStudio.Wpf.DiagramDesigner
private bool _undoing;
private void UndoExecuted(object para)
{
Undo(para);
}
private bool Undo(object para)
{
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
_undoing = true;
DoCommandManager.UnDo();
_undoing = false;
return true;
}
private void RedoExecuted(object para)
{
Redo(para);
}
private bool Redo(object para)
{
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
_undoing = true;
DoCommandManager.ReDo();
_undoing = false;
return true;
}
private bool Undo_Enabled(object para)
{
return DoCommandManager.CanUnDo;
@@ -1684,6 +1714,11 @@ namespace AIStudio.Wpf.DiagramDesigner
#region
private void ExecuteCopyCommand(object parameter)
{
Copy(parameter);
}
private bool Copy(object parameter)
{
List<DesignerItemViewModelBase> selectedDesignerItems;
@@ -1696,6 +1731,15 @@ namespace AIStudio.Wpf.DiagramDesigner
}
else
{
if (SelectedItems.Count == 0)
{
return false;
}
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
selectedDesignerItems = SelectedItems.OfType<DesignerItemViewModelBase>().ToList();
selectedConnections = SelectedItems.OfType<ConnectionViewModel>().ToList();
}
@@ -1732,16 +1776,23 @@ namespace AIStudio.Wpf.DiagramDesigner
OffsetY = 10;
System.Windows.Clipboard.Clear();
System.Windows.Clipboard.SetData(System.Windows.DataFormats.Serializable, json);
return true;
}
private void ExecutePasteCommand(object parameter)
{
Paste(parameter);
}
private bool Paste(object parameter)
{
if (System.Windows.Clipboard.ContainsData(System.Windows.DataFormats.Serializable))
{
string clipboardData = System.Windows.Clipboard.GetData(System.Windows.DataFormats.Serializable) as String;
if (string.IsNullOrEmpty(clipboardData))
return;
return false;
try
{
List<SelectableDesignerItemViewModelBase> items = new List<SelectableDesignerItemViewModelBase>();
@@ -1816,6 +1867,12 @@ namespace AIStudio.Wpf.DiagramDesigner
{
System.Windows.MessageBox.Show(e.StackTrace, e.Message, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
}
return true;
}
else
{
return false;
}
}
@@ -1831,13 +1888,27 @@ namespace AIStudio.Wpf.DiagramDesigner
private void ExecuteCutCommand(object parameter)
{
ExecutePasteCommand(null);
Cut(parameter);
}
private bool Cut(object parameter)
{
if (Paste(null) == false)
return false;
OffsetX = 0;
OffsetY = 0;
ExecuteDeleteCommand(null);
if (Delete(null) == false)
return false;
return true;
}
private void ExecuteDeleteCommand(object parameter)
{
Delete(parameter);
}
private bool Delete(object parameter)
{
List<SelectableDesignerItemViewModelBase> itemsToRemove;
@@ -1847,6 +1918,15 @@ namespace AIStudio.Wpf.DiagramDesigner
}
else
{
if (SelectedItems.Count == 0)
{
return false;
}
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
itemsToRemove = SelectedItems.OfType<SelectableDesignerItemViewModelBase>().ToList();
}
@@ -1868,6 +1948,8 @@ namespace AIStudio.Wpf.DiagramDesigner
itemsToRemove.AddRange(connectionsToAlsoRemove);
RemoveItemCommand.Execute(itemsToRemove);
return true;
}
#endregion
@@ -2119,33 +2201,27 @@ namespace AIStudio.Wpf.DiagramDesigner
}
else if (DiagramOption.ShortcutOption.Copy(e))
{
CopyCommand.Execute(null);
return true;
return Copy(null);
}
else if (DiagramOption.ShortcutOption.Paste(e))
{
PasteCommand.Execute(null);
return true;
return Paste(null);
}
else if (DiagramOption.ShortcutOption.Cut(e))
{
CutCommand.Execute(null);
return true;
return Cut(null);
}
else if (DiagramOption.ShortcutOption.Undo(e))
{
UndoCommand.Execute(null);
return true;
return Undo(null);
}
else if (DiagramOption.ShortcutOption.Redo(e))
{
RedoCommand.Execute(null);
return true;
return Redo(null);
}
else if (DiagramOption.ShortcutOption.Delete(e))
{
DeleteCommand.Execute(null);
return true;
return Delete(null);
}
else if (DiagramOption.ShortcutOption.LeftMove(e))
{

View File

@@ -166,6 +166,24 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
bool IsEditing
{
get; set;
}
private bool _isEditing = true;
public bool IsEditing
{
get
{
return _isEditing;
}
set
{
SetProperty(ref _isEditing, value);
}
}
private bool _visible = true;
public bool Visible
{

View File

@@ -18,6 +18,11 @@ namespace AIStudio.Wpf.DiagramDesigner
get;
}
bool IsEditing
{
get; set;
}
void AddToSelection(bool selected);
event PropertyChangedEventHandler PropertyChanged;