删除几个非mit的引用

This commit is contained in:
艾竹
2024-02-20 22:14:30 +08:00
parent a0439f6b88
commit 2a97a90ac8
8 changed files with 98 additions and 400 deletions

View File

@@ -2531,11 +2531,6 @@
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M819.198 910.218 204.799 910.218c-50.267 0-91.022-40.75-91.022-91.02L113.777 204.822c0-50.29 40.755-91.045 91.022-91.045l614.398 0c50.27 0 91.02 40.755 91.02 91.045l0 614.376C910.218 869.468 869.468 910.218 819.198 910.218zM841.953 227.554c0-25.122-20.385-45.51-45.51-45.51L227.554 182.044c-25.122 0-45.51 20.387-45.51 45.51l0 568.889c0 25.125 20.387 45.535 45.51 45.535l568.889 0c25.125 0 45.51-20.39 45.51-45.535L841.953 227.554zM603.268 400.952l-57.14-57.115 0 335.802 55.505-55.5c13.335-13.31 34.93-13.335 48.265 0 13.33 13.335 13.33 34.95 0 48.29l-105.77 105.765c-1.615 3.415-3.525 6.78-6.37 9.625-7.1 7.08-16.475 10.1-25.76 9.67-9.262 0.46-18.66-2.59-25.76-9.69-2.842-2.85-4.8-6.15-6.347-9.58l-105.79-105.79c-13.335-13.34-13.335-34.955 0-48.29 13.332-13.31 34.927-13.335 48.262 0l55.502 55.5L477.865 343.837l-57.117 57.115c-13.335 13.357-34.952 13.335-48.287 0s-13.335-34.93 0-48.265l115.395-115.37c13.332-13.335 34.927-13.357 48.262 0l115.395 115.37c13.335 13.335 13.335 34.952 0 48.265C638.198 414.286 616.583 414.286 603.268 400.952z"></Path> <Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M819.198 910.218 204.799 910.218c-50.267 0-91.022-40.75-91.022-91.02L113.777 204.822c0-50.29 40.755-91.045 91.022-91.045l614.398 0c50.27 0 91.02 40.755 91.02 91.045l0 614.376C910.218 869.468 869.468 910.218 819.198 910.218zM841.953 227.554c0-25.122-20.385-45.51-45.51-45.51L227.554 182.044c-25.122 0-45.51 20.387-45.51 45.51l0 568.889c0 25.125 20.387 45.535 45.51 45.535l568.889 0c25.125 0 45.51-20.39 45.51-45.535L841.953 227.554zM603.268 400.952l-57.14-57.115 0 335.802 55.505-55.5c13.335-13.31 34.93-13.335 48.265 0 13.33 13.335 13.33 34.95 0 48.29l-105.77 105.765c-1.615 3.415-3.525 6.78-6.37 9.625-7.1 7.08-16.475 10.1-25.76 9.67-9.262 0.46-18.66-2.59-25.76-9.69-2.842-2.85-4.8-6.15-6.347-9.58l-105.79-105.79c-13.335-13.34-13.335-34.955 0-48.29 13.332-13.31 34.927-13.335 48.262 0l55.502 55.5L477.865 343.837l-57.117 57.115c-13.335 13.357-34.952 13.335-48.287 0s-13.335-34.93 0-48.265l115.395-115.37c13.332-13.335 34.927-13.357 48.262 0l115.395 115.37c13.335 13.335 13.335 34.952 0 48.265C638.198 414.286 616.583 414.286 603.268 400.952z"></Path>
</Fluent:Button.LargeIcon> </Fluent:Button.LargeIcon>
</Fluent:Button> </Fluent:Button>
<Fluent:Button Header="自动布局" Width="90" VerticalAlignment="Top" Command="{Binding PageViewModel.DiagramViewModel.AutoLayoutCommand}">
<Fluent:Button.LargeIcon>
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M913.065145 0.000569A110.705593 110.705593 0 0 1 1023.998293 109.682164V256.000142a110.478038 110.478038 0 0 1-110.933148 109.681595H365.794946v109.738484h328.81723a36.693272 36.693272 0 0 1 36.977716 36.522606v146.317978h181.475253A109.738484 109.738484 0 0 1 1023.998293 767.999289v146.317978A110.534927 110.534927 0 0 1 913.065145 1023.998862H110.933148A110.705593 110.705593 0 0 1 0 914.317267V767.999289a110.478038 110.478038 0 0 1 110.933148-109.681595h547.270199V548.636099H329.386118a36.750161 36.750161 0 0 1-36.977716-36.579495V365.738626H110.933148A109.738484 109.738484 0 0 1 0 256.000142V109.682164A110.534927 110.534927 0 0 1 110.933148 0.000569h802.131997z m0.568888 731.476114H110.364261a36.579495 36.579495 0 0 0-36.977717 36.522606v146.317978a36.977716 36.977716 0 0 0 10.808871 25.94129 36.124384 36.124384 0 0 0 26.168846 10.581316h803.269772a36.636383 36.636383 0 0 0 36.977716-36.522606V767.999289a36.863939 36.863939 0 0 0-10.808871-25.94129 35.669274 35.669274 0 0 0-26.168845-10.581316z m-219.021857 73.1021a36.465717 36.465717 0 0 1 32.9955 17.863082 36.863939 36.863939 0 0 1 0 37.489715 36.295051 36.295051 0 0 1-32.9955 17.806193H328.81723a36.636383 36.636383 0 0 1 0-73.15899h365.794946z m219.021857-731.419225H110.364261a36.636383 36.636383 0 0 0-36.977717 36.522606V256.000142a36.80705 36.80705 0 0 0 10.808871 25.94129 35.669274 35.669274 0 0 0 26.168846 10.581316h803.269772a36.579495 36.579495 0 0 0 36.977716-36.522606V109.682164a36.977716 36.977716 0 0 0-10.808871-25.94129 36.124384 36.124384 0 0 0-26.168845-10.581316z m-219.021857 73.158989a36.579495 36.579495 0 0 1 0 73.158989H328.81723a36.067495 36.067495 0 0 1-32.426613-17.863081 34.474609 34.474609 0 0 1 0-37.489715 36.010607 36.010607 0 0 1 32.426613-17.806193h365.794946z m0 0"></Path>
</Fluent:Button.LargeIcon>
</Fluent:Button>
</Fluent:RibbonGroupBox> </Fluent:RibbonGroupBox>
</Fluent:RibbonTabItem> </Fluent:RibbonTabItem>
<Fluent:RibbonTabItem Header="高级"> <Fluent:RibbonTabItem Header="高级">

View File

@@ -1,72 +0,0 @@
using System;
namespace AIStudio.Wpf.DiagramDesigner.Layout
{
public class Configuration
{
/// <summary>
/// The network whose nodes are to be repositioned.
/// </summary>
public DiagramViewModel Network
{
get; set;
}
/// <summary>
/// A time modifier that is used to speed up, or slow down, time during the simulation.
/// A greater time modifier speeds up the physics simulation, at the cost of accuracy and stability.
/// </summary>
public float TimeModifier { get; set; } = 3.5f;
/// <summary>
/// Number of updates per iteration.
/// Increasing this number increases the accuracy of the physics simulation at the cost of performance.
/// </summary>
public int UpdatesPerIteration { get; set; } = 1;
/// <summary>
/// How strongly should nodes push eachother away?
/// A greater NodeRepulsionForce increases the distance between nodes.
/// </summary>
public float NodeRepulsionForce { get; set; } = 100;
/// <summary>
/// A function that maps each connection onto the equilibrium distance of its corresponding spring.
/// A greater equilibrium distance increases the distance between the two connected endpoints.
/// </summary>
public Func<ConnectionViewModel, double> EquilibriumDistance { get; set; } = conn => 100;
/// <summary>
/// A function that maps each connection onto the springiness/stiffness constant of its corresponding spring.
/// (c.f. Hooke's law)
/// </summary>
public Func<ConnectionViewModel, double> SpringConstant { get; set; } = conn => 1;
/// <summary>
/// A function that maps each connection onto the strength of its row force.
/// Since inputs/outputs are on the left/right of a node, networks tend to be layed out horizontally.
/// The row force is added onto the endpoints of the connection to make the nodes end up in a more horizontal layout.
/// </summary>
public Func<ConnectionViewModel, double> RowForce { get; set; } = conn => 100;
/// <summary>
/// A function that maps each node onto its mass in the physics simulation.
/// Greater mass makes the node harder to move.
/// </summary>
public Func<DesignerItemViewModelBase, float> NodeMass { get; set; } = node => 10;
/// <summary>
/// The friction coefficient is used to control friction forces in the simulation.
/// Greater friction makes the simulation converge faster, as it slows nodes down when
/// they are swinging around. If the friction is too high, the nodes will stop moving before
/// they reach their optimal position or might not even move at all.
/// </summary>
public Func<DesignerItemViewModelBase, float> FrictionCoefficient { get; set; } = node => 2.5f;
/// <summary>
/// A predicate function that specifies whether or not a node is fixed.
/// Fixed nodes do not get moved in the simulation.
/// </summary>
public Func<DesignerItemViewModelBase, bool> IsFixedNode { get; set; } = node => false;
}
}

View File

@@ -1,123 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner.Layout
{
internal class Engine
{
internal void ApplyRandomShift(DiagramViewModel network)
{
Random random = new Random();
foreach (var node in network.Items.OfType<DesignerItemViewModelBase>())
{
node.Position = node.Position + new VectorBase(random.NextDouble(), random.NextDouble());
}
}
internal void Update(int deltaTMillis, IState state, Configuration config)
{
// Calculate forces
int nodeCount = config.Network.Items.Count;
IList<(DesignerItemViewModelBase, VectorBase)> nodeForces = new List<(DesignerItemViewModelBase, VectorBase)>(nodeCount);
foreach (var node in config.Network.Items.OfType<DesignerItemViewModelBase>())
{
if (!config.IsFixedNode(node))
{
nodeForces.Add((node, CalculateNodeForce(node, state, config)));
}
}
// Apply forces
foreach (var (node, force) in nodeForces)
{
VectorBase speed = state.GetNodeSpeed(node);
VectorBase pos = state.GetNodePosition(node);
double deltaT = deltaTMillis / 1000.0;
state.SetNodePosition(node, pos + ((speed * deltaT) + (force * deltaT * deltaT / 2)));
state.SetNodeSpeed(node, speed + ((force / config.NodeMass(node)) * deltaT));
}
}
private VectorBase CalculateNodeForce(DesignerItemViewModelBase node, IState state, Configuration config)
{
VectorBase force = new VectorBase();
// Calculate total force on node from endpoints
if (node.InputConnectors.Count > 0 || node.OutputConnectors.Count > 0)
{
force += node.InputConnectors.Concat(node.OutputConnectors)
.Select(e => CalculateEndpointForce(e, state, config))
.Aggregate((v1, v2) => v1 + v2);
}
// Apply node repulsion force so nodes don't overlap
var nodeCenter = state.GetNodePosition(node) + (new VectorBase(node.Size.Width, node.Size.Height) / 2.0);
foreach (var otherNode in config.Network.Items.OfType<DesignerItemViewModelBase>())
{
if (node == otherNode)
{
continue;
}
var otherNodeCenter = state.GetNodePosition(otherNode) + (new VectorBase(otherNode.Size.Width, otherNode.Size.Height) / 2.0);
var thisToOther = otherNodeCenter - nodeCenter;
var dist = thisToOther.Length;
thisToOther.Normalize();
var repulsionX = thisToOther.X * (-1 * ((node.Size.Width + otherNode.Size.Width) / 2) / dist);
var repulsionY = thisToOther.Y * (-1 * ((node.Size.Height + otherNode.Size.Height) / 2) / dist);
force += new VectorBase(repulsionX, repulsionY) * config.NodeRepulsionForce;
}
// Apply friction to make the movement converge to a stable state.
float gravity = 9.8f;
float normalForce = gravity * config.NodeMass(node);
float kineticFriction = normalForce * config.FrictionCoefficient(node);
VectorBase frictionVector = new VectorBase();
var nodeSpeed = state.GetNodeSpeed(node);
if (nodeSpeed.Length > 0)
{
frictionVector = new VectorBase(nodeSpeed.X, nodeSpeed.Y);
frictionVector.Normalize();
frictionVector *= -1.0 * kineticFriction;
}
force += frictionVector;
return force;
}
private VectorBase CalculateEndpointForce(ConnectorInfoBase endpoint, IState state, Configuration config)
{
var pos = state.GetEndpointPosition(endpoint);
VectorBase force = new VectorBase();
foreach (var conn in config.Network.Items.OfType<ConnectionViewModel>().Where(p => p.SinkConnectorInfo == endpoint || p.SourceConnectorInfo == endpoint).ToList())
{
var otherSide = conn.SourceConnectorInfo == endpoint ? conn.SinkConnectorInfo : conn.SourceConnectorInfo;
var otherSidePos = state.GetEndpointPosition(otherSide);
var dist = (otherSidePos - pos).Length;
var angle = Math.Acos((otherSidePos.X - pos.X) / dist);
if (otherSidePos.Y < pos.Y)
{
angle *= -1.0;
}
// Put a spring between connected endpoints.
var hookForce = (dist - config.EquilibriumDistance(conn)) * config.SpringConstant(conn);
force += new VectorBase(Math.Cos(angle), Math.Sin(angle)) * hookForce;
// Try to 'straighten' out the graph horizontally.
var isLeftSide = endpoint.Orientation == ConnectorOrientation.Left;
var rowForce = (isLeftSide ? 1 : -1) * config.RowForce(conn);
force.X += rowForce;
}
return force;
}
}
}

View File

@@ -1,81 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Layout
{
/// <summary>
/// Reposition the nodes in a network using a physics-based approach.
/// The nodes are interpreted as point masses, and the connections are represented
/// by springs. This system, along with a few additional forces such as friction and a
/// horizontal force, is then simulated to calculate the new position of the nodes.
/// </summary>
public class ForceDirectedLayouter
{
/// <summary>
/// Layout the nodes in the network.
/// </summary>
/// <param name="config">The configuration to use.</param>
/// <param name="maxIterations">The maximum amount of iterations after which the physics simulation ends.</param>
public void Layout(Configuration config, int maxIterations)
{
var engine = new Engine();
var state = new BufferedState();
// Move each node so no two nodes have the exact same position.
engine.ApplyRandomShift(config.Network);
int deltaT = (int)Math.Ceiling(10.0 / (double)config.UpdatesPerIteration);
for (int i = 0; i < maxIterations * config.UpdatesPerIteration; i++)
{
engine.Update(deltaT, state, config);
}
foreach (var newNodePosition in state.NodePositions)
{
newNodePosition.Key.Position = new Point(newNodePosition.Value.X, newNodePosition.Value.Y);
}
}
/// <summary>
/// Layout the nodes in the network, updating the user interface at each iteration.
/// This method, contrary to Layout(), lets users see the simulation as it happens.
/// The cancellation token should be used to end the simulation.
/// </summary>
/// <param name="config">The configuration to use.</param>
/// <param name="token">A cancellation token to end the layout process.</param>
/// <returns>The async task</returns>
public async Task LayoutAsync(Configuration config, CancellationToken token)
{
var engine = new Engine();
var state = new LiveState();
// Move each node so no two nodes have the exact same position.
engine.ApplyRandomShift(config.Network);
DateTime start = DateTime.Now;
TimeSpan t = TimeSpan.Zero;
do
{
// Current real time
var newT = DateTime.Now - start;
var deltaT = newT - t;
// Current modified time
//int virtT = (int)(t.Milliseconds * Settings.TimeModifier);
int virtDeltaT = (int)(deltaT.Milliseconds * config.TimeModifier);
int virtDeltaTPerUpdate = virtDeltaT / config.UpdatesPerIteration;
for (int i = 0; i < config.UpdatesPerIteration; i++)
{
// Modified time in this update step
engine.Update(virtDeltaTPerUpdate, state, config);
}
t = newT;
await Task.Delay(14, token);
} while (!token.IsCancellationRequested);
}
}
}

View File

@@ -1,100 +0,0 @@
using System.Collections.Generic;
using System.Windows;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner.Layout
{
internal interface IState
{
VectorBase GetNodePosition(DesignerItemViewModelBase node);
void SetNodePosition(DesignerItemViewModelBase node, VectorBase pos);
VectorBase GetEndpointPosition(ConnectorInfoBase endpoint);
VectorBase GetNodeSpeed(DesignerItemViewModelBase node);
void SetNodeSpeed(DesignerItemViewModelBase node, VectorBase speed);
}
internal class BufferedState : IState
{
private readonly Dictionary<DesignerItemViewModelBase, VectorBase> _nodePositions = new Dictionary<DesignerItemViewModelBase, VectorBase>();
private readonly Dictionary<ConnectorInfoBase, VectorBase> _endpointRelativePositions = new Dictionary<ConnectorInfoBase, VectorBase>();
public IEnumerable<KeyValuePair<DesignerItemViewModelBase, VectorBase>> NodePositions => _nodePositions;
private readonly Dictionary<DesignerItemViewModelBase, VectorBase> _nodeSpeeds = new Dictionary<DesignerItemViewModelBase, VectorBase>();
public VectorBase GetNodePosition(DesignerItemViewModelBase node)
{
if (!_nodePositions.TryGetValue(node, out VectorBase result))
{
result = new VectorBase(node.Position.X, node.Position.Y);
}
return result;
}
public void SetNodePosition(DesignerItemViewModelBase node, VectorBase pos)
{
_nodePositions[node] = pos;
}
public VectorBase GetEndpointPosition(ConnectorInfoBase endpoint)
{
if (!_endpointRelativePositions.TryGetValue(endpoint, out VectorBase result))
{
result = new VectorBase(endpoint.MiddlePosition.X, endpoint.MiddlePosition.Y) - GetNodePosition(endpoint.Parent as DesignerItemViewModelBase);
_endpointRelativePositions[endpoint] = result;
}
return result + GetNodePosition(endpoint.Parent as DesignerItemViewModelBase);
}
public VectorBase GetNodeSpeed(DesignerItemViewModelBase node)
{
if (!_nodeSpeeds.TryGetValue(node, out VectorBase result))
{
result = new VectorBase(0, 0);
}
return result;
}
public void SetNodeSpeed(DesignerItemViewModelBase node, VectorBase speed)
{
_nodeSpeeds[node] = speed;
}
}
internal class LiveState : IState
{
private readonly Dictionary<DesignerItemViewModelBase, VectorBase> _nodeSpeeds = new Dictionary<DesignerItemViewModelBase, VectorBase>();
public VectorBase GetNodePosition(DesignerItemViewModelBase node)
{
return new VectorBase(node.Position.X, node.Position.Y);
}
public void SetNodePosition(DesignerItemViewModelBase node, VectorBase pos)
{
node.Position = new Point(pos.X, pos.Y);
}
public VectorBase GetEndpointPosition(ConnectorInfoBase endpoint)
{
return new VectorBase(endpoint.MiddlePosition.X, endpoint.MiddlePosition.Y);
}
public VectorBase GetNodeSpeed(DesignerItemViewModelBase node)
{
if (!_nodeSpeeds.TryGetValue(node, out VectorBase result))
{
result = new VectorBase(0, 0);
}
return result;
}
public void SetNodeSpeed(DesignerItemViewModelBase node, VectorBase speed)
{
_nodeSpeeds[node] = speed;
}
}
}

View File

@@ -0,0 +1,96 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="AIStudio.DiagramDesigner.Styles.ToggleButton.Flat" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid ClipToBounds="True" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0.38" Storyboard.TargetProperty="(UIElement.Opacity)" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualStateGroup.Transitions>
<VisualTransition From="*" To="Checked">
<Storyboard>
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="Checked" To="Unchecked">
<Storyboard>
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale" To="1.0" />
<DoubleAnimation Duration="0" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale" To="1.0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale" To="0" />
<DoubleAnimation Duration="0" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale" To="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Fill="Transparent" x:Name="HoverEllipse" Stroke="Transparent" StrokeThickness="1" />
<Rectangle Fill="{TemplateBinding Background}" x:Name="CheckedEllipse" RenderTransformOrigin="0.5, 0.5">
<Rectangle.RenderTransform>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1.0" ScaleY="1.0" x:Name="CheckedEllipseScale"/>
</Rectangle.RenderTransform>
</Rectangle>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="HoverEllipse" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#f1f1f1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value=".9"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value=".6"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

View File

@@ -9,5 +9,6 @@
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/TextBox.xaml" /> <ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/TextBox.xaml" />
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ZoomBox.xaml" /> <ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ZoomBox.xaml" />
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ComboBox.xaml" /> <ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ComboBox.xaml" />
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ToggleButton.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>

View File

@@ -10,10 +10,8 @@ using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometrys; using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Helpers; using AIStudio.Wpf.DiagramDesigner.Helpers;
using AIStudio.Wpf.DiagramDesigner.Layout;
using AIStudio.Wpf.DiagramDesigner.Models; using AIStudio.Wpf.DiagramDesigner.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using static System.Net.Mime.MediaTypeNames;
namespace AIStudio.Wpf.DiagramDesigner namespace AIStudio.Wpf.DiagramDesigner
{ {
@@ -682,16 +680,6 @@ namespace AIStudio.Wpf.DiagramDesigner
} }
} }
private ICommand _autoLayoutCommand;
public ICommand AutoLayoutCommand
{
get
{
return this._autoLayoutCommand ?? (this._autoLayoutCommand = new SimpleCommand(ExecuteEnable, ExecuteAutoLayoutCommand));
}
}
private ICommand _groupCommand; private ICommand _groupCommand;
public ICommand GroupCommand public ICommand GroupCommand
{ {
@@ -2462,12 +2450,6 @@ namespace AIStudio.Wpf.DiagramDesigner
FitViewModel = new FitViewModel() { BoundingRect = DiagramViewModelHelper.GetBoundingRectangle(Items.OfType<DesignerItemViewModelBase>()), FitMode = FitMode.FitHeight }; FitViewModel = new FitViewModel() { BoundingRect = DiagramViewModelHelper.GetBoundingRectangle(Items.OfType<DesignerItemViewModelBase>()), FitMode = FitMode.FitHeight };
} }
} }
private void ExecuteAutoLayoutCommand(object parameter)
{
ForceDirectedLayouter layouter = new ForceDirectedLayouter();
layouter.Layout(new Configuration { Network = this }, 10000);
}
#endregion #endregion
#region #region