Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/LogicalGateItemViewModelBase.cs
2023-04-24 20:10:17 +08:00

329 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Models;
namespace AIStudio.Wpf.DiagramDesigner
{
public abstract class LogicalGateItemViewModelBase : DesignerItemViewModelBase
{
public ICommand AddInputCommand
{
get; private set;
}
public ICommand AddOutputCommand
{
get; private set;
}
public virtual bool EnableAddInput
{
get;
} = false;
public virtual bool EnableAddOutput
{
get;
} = false;
public LogicalGateItemViewModelBase(LogicalType logicalType) : this(null, logicalType)
{
}
public LogicalGateItemViewModelBase(IDiagramViewModel root, LogicalType logicalType) : base(root)
{
this.LogicalType = logicalType;
}
public LogicalGateItemViewModelBase(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
{
}
public LogicalGateItemViewModelBase(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
{
}
public override SelectableItemBase GetSerializableObject()
{
return new LogicalGateDesignerItemBase(this);
}
protected override void Init(IDiagramViewModel root, bool initNew)
{
ShowRotate = false;
ShowArrow = false;
AddInputCommand = new SimpleCommand(Command_Enable, para => ExecuteAddInput(para));
AddOutputCommand = new SimpleCommand(Command_Enable, para => ExecuteAddOutput(para));
BuildMenuOptions();
base.Init(root, initNew);
}
protected override void InitNew()
{
base.InitNew();
}
private void BuildMenuOptions()
{
menuOptions = new ObservableCollection<CinchMenuItem>();
if (EnableAddInput == true)
{
CinchMenuItem menuItem = new CinchMenuItem();
menuItem.Text = "添加输入";
menuItem.Command = AddInputCommand;
menuItem.CommandParameter = menuItem;
menuOptions.Add(menuItem);
}
if (EnableAddOutput == true)
{
CinchMenuItem menuItem = new CinchMenuItem();
menuItem.Text = "添加输出";
menuItem.Command = AddOutputCommand;
menuItem.CommandParameter = menuItem;
menuOptions.Add(menuItem);
}
}
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
{
base.LoadDesignerItemViewModel(designerbase);
if (designerbase is LogicalGateDesignerItemBase designer)
{
this.LogicalType = designer.LogicalType;
this.OrderNumber = designer.OrderNumber;
this.Value = designer.Value;
this.IsEnabled = designer.IsEnabled;
ClearConnectors();
Input.Clear();
Output.Clear();
if (designer.LogicalConnectors != null)
{
foreach (var connector in designer.LogicalConnectors)
{
LogicalConnectorInfo fullyCreatedConnectorInfo = new LogicalConnectorInfo(this.Root, this, connector);
if (fullyCreatedConnectorInfo.Orientation == ConnectorOrientation.Left)
{
Input.Add(Input.Count, fullyCreatedConnectorInfo);
}
else if (fullyCreatedConnectorInfo.Orientation == ConnectorOrientation.Right)
{
Output.Add(Output.Count, fullyCreatedConnectorInfo);
}
AddConnector(fullyCreatedConnectorInfo);
}
}
}
}
private int _orderNumber;
public int OrderNumber
{
get
{
return _orderNumber;
}
set
{
SetProperty(ref _orderNumber, value);
}
}
private bool _isEnabled;
public bool IsEnabled
{
get
{
return _isEnabled;
}
set
{
SetProperty(ref _isEnabled, value);
}
}
private double _value;
public double Value
{
get
{
return _value;
}
set
{
SetProperty(ref _value, value);
}
}
public LogicalType LogicalType
{
get; set;
}
public Dictionary<int, LogicalConnectorInfo> Input { get; set; } = new Dictionary<int, LogicalConnectorInfo>();
public Dictionary<int, LogicalConnectorInfo> Output { get; set; } = new Dictionary<int, LogicalConnectorInfo>();
public virtual LogicalConnectorInfo ExecuteAddInput(object parameter, int index = 0)
{
if (Input.Values.Count >= 2)
{
this.ItemHeight = this.ItemHeight * (Input.Values.Count + 1) / Input.Values.Count;
}
LogicalConnectorInfo connector = new LogicalConnectorInfo(this, ConnectorOrientation.Left, true, false, ValueTypeInput.Count > index ? ValueTypeInput[index] : ValueTypeInput[0]);
connector.XRatio = 0;
Input.Add(Input.Count, connector);
for (int i = 0; i < Input.Values.Count; i++)
{
Input[i].YRatio = (i + 1.0) / (Input.Values.Count + 1.0);
}
AddConnector(connector);
return connector;
}
public virtual LogicalConnectorInfo ExecuteAddOutput(object parameter, int index = 0)
{
LogicalConnectorInfo connector = new LogicalConnectorInfo(this, ConnectorOrientation.Right, true, false, ValueTypeOutput.Count > index ? ValueTypeOutput[index] : ValueTypeInput[0]);
connector.XRatio = 1;
Output.Add(Output.Count, connector);
for (int i = 0; i < Output.Values.Count; i++)
{
Output[i].YRatio = (i + 1.0) / (Output.Values.Count + 1.0);
}
AddConnector(connector);
return connector;
}
public List<ConnectorValueType> ValueTypeInput
{
get
{
if (LogicalType == LogicalType.NOT)
{
return new List<ConnectorValueType>() { ConnectorValueType.Bool };
}
else if (LogicalType == LogicalType.AND || LogicalType == LogicalType.OR || LogicalType == LogicalType.XOR
|| LogicalType == LogicalType.SHL || LogicalType == LogicalType.SHR || LogicalType == LogicalType.ROL || LogicalType == LogicalType.ROR)
{
return new List<ConnectorValueType>() { ConnectorValueType.Int };
}
else if (LogicalType == LogicalType.SEL)
{
return new List<ConnectorValueType>() { ConnectorValueType.Bool, ConnectorValueType.Real, ConnectorValueType.Real };
}
else
{
return new List<ConnectorValueType>() { ConnectorValueType.Real };
}
}
}
public List<ConnectorValueType> ValueTypeOutput
{
get
{
if (LogicalType == LogicalType.GT || LogicalType == LogicalType.LT || LogicalType == LogicalType.GE || LogicalType == LogicalType.LE || LogicalType == LogicalType.EQ || LogicalType == LogicalType.NE
|| LogicalType == LogicalType.NOT)
{
return new List<ConnectorValueType>() { ConnectorValueType.Bool };
}
else if (LogicalType == LogicalType.AND || LogicalType == LogicalType.OR || LogicalType == LogicalType.XOR
|| LogicalType == LogicalType.SHL || LogicalType == LogicalType.SHR || LogicalType == LogicalType.ROL || LogicalType == LogicalType.ROR)
{
return new List<ConnectorValueType>() { ConnectorValueType.Int };
}
else
{
return new List<ConnectorValueType>() { ConnectorValueType.Real };
}
}
}
public void Execute()
{
GetInput();
CalculateOutput();
}
public virtual void GetInput()
{
foreach (var input in Input)
{
var connector = GetSourceItem(input.Value);
if (connector == null)
{
continue;
}
if (connector.SourceConnectorInfo.DataItem is LogicalGateItemViewModelBase)
{
input.Value.ConnectorValue = (connector.SourceConnectorInfo as LogicalConnectorInfo).ConnectorValue;
input.Value.ConnectorString = (connector.SourceConnectorInfo as LogicalConnectorInfo).ConnectorString;
input.Value.ColorViewModel.FillColor.Color = connector.SourceConnectorInfo.ColorViewModel.FillColor.Color;
connector.ColorViewModel.LineColor.Color = connector.SourceConnectorInfo.ColorViewModel.FillColor.Color;
connector.ColorViewModel.FillColor.Color = connector.SourceConnectorInfo.ColorViewModel.FillColor.Color;
if (LogicalType == LogicalType.Output)
{
input.Value.ConnectorValueType = (connector.SourceConnectorInfo as LogicalConnectorInfo).ConnectorValueType;
}
else if (LogicalType == LogicalType.NOT)
{
input.Value.ConnectorValueType = ((connector.SourceConnectorInfo as LogicalConnectorInfo).ConnectorValueType == ConnectorValueType.Bool) ? ConnectorValueType.Bool : ConnectorValueType.Int;
}
}
}
}
public virtual void CalculateOutput()
{
foreach (var output in Output)
{
if (output.Value.ConnectorValueType == ConnectorValueType.Bool)
{
if (output.Value.ConnectorValue == 0)
{
output.Value.ColorViewModel.FillColor.Color = Colors.Red;
if (LogicalType == LogicalType.Output)
{
ColorViewModel.FillColor.Color = Colors.Red;
}
}
else
{
output.Value.ColorViewModel.FillColor.Color = Colors.Green;
if (LogicalType == LogicalType.Output)
{
ColorViewModel.FillColor.Color = Colors.Green;
}
}
}
else
{
output.Value.ColorViewModel.FillColor.Color = Colors.Green;
}
}
}
protected ConnectionViewModel GetSourceItem(FullyCreatedConnectorInfo sinkConnector)
{
return Root?.Items.OfType<ConnectionViewModel>().FirstOrDefault(p => p.SinkConnectorInfo == sinkConnector);
}
}
}