Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/LogicalGateItemViewModelBase.cs

356 lines
12 KiB
C#
Raw Normal View History

2021-07-23 09:42:22 +08:00
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
2023-04-25 23:07:25 +08:00
using System.ComponentModel.DataAnnotations;
2021-07-23 09:42:22 +08:00
using System.Linq;
using System.Text;
using System.Threading.Tasks;
2023-05-01 00:10:55 +08:00
using System.Windows.Controls;
2023-03-24 22:32:42 +08:00
using System.Windows.Input;
2021-07-23 09:42:22 +08:00
using System.Windows.Media;
2023-04-26 22:53:44 +08:00
using AIStudio.Wpf.DiagramDesigner.Enums;
2023-01-25 11:11:27 +08:00
using AIStudio.Wpf.DiagramDesigner.Models;
2021-07-23 09:42:22 +08:00
2022-10-28 22:45:39 +08:00
namespace AIStudio.Wpf.DiagramDesigner
2021-07-23 09:42:22 +08:00
{
2023-01-27 14:54:03 +08:00
public abstract class LogicalGateItemViewModelBase : DesignerItemViewModelBase
2021-07-23 09:42:22 +08:00
{
public ICommand AddInputCommand
{
get; private set;
}
public ICommand AddOutputCommand
{
get; private set;
}
2021-07-23 09:42:22 +08:00
2023-04-22 21:06:52 +08:00
public virtual bool EnableAddInput
{
get;
} = false;
public virtual bool EnableAddOutput
{
get;
} = false;
2021-07-23 09:42:22 +08:00
2023-01-27 14:54:03 +08:00
public LogicalGateItemViewModelBase(LogicalType logicalType) : this(null, logicalType)
{
}
public LogicalGateItemViewModelBase(IDiagramViewModel root, LogicalType logicalType) : base(root)
2021-07-23 09:42:22 +08:00
{
2023-04-23 22:44:15 +08:00
this.LogicalType = logicalType;
2021-07-23 09:42:22 +08:00
}
2023-01-24 17:53:04 +08:00
public LogicalGateItemViewModelBase(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
2021-07-23 09:42:22 +08:00
{
2023-04-23 22:44:15 +08:00
2021-07-23 09:42:22 +08:00
}
2023-01-25 11:11:27 +08:00
public LogicalGateItemViewModelBase(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
{
2023-04-23 22:44:15 +08:00
}
2023-01-24 23:10:57 +08:00
public override SelectableItemBase GetSerializableObject()
{
return new LogicalGateDesignerItemBase(this);
}
2023-03-25 11:59:31 +08:00
protected override void Init(IDiagramViewModel root, bool initNew)
{
2021-07-23 09:42:22 +08:00
ShowRotate = false;
ShowArrow = false;
2023-01-25 23:55:30 +08:00
AddInputCommand = new SimpleCommand(Command_Enable, para => ExecuteAddInput(para));
AddOutputCommand = new SimpleCommand(Command_Enable, para => ExecuteAddOutput(para));
2023-04-22 21:06:52 +08:00
BuildMenuOptions();
2021-07-23 09:42:22 +08:00
2023-03-25 11:59:31 +08:00
base.Init(root, initNew);
}
protected override void InitNew()
{
ExecuteAddInput(null);
ExecuteAddInput(null);
ExecuteAddOutput(null);
2021-07-23 09:42:22 +08:00
}
private void BuildMenuOptions()
{
menuOptions = new ObservableCollection<CinchMenuItem>();
2023-04-22 21:06:52 +08:00
if (EnableAddInput == true)
2021-07-23 09:42:22 +08:00
{
CinchMenuItem menuItem = new CinchMenuItem();
menuItem.Text = "添加输入";
menuItem.Command = AddInputCommand;
menuItem.CommandParameter = menuItem;
menuOptions.Add(menuItem);
}
2023-04-22 21:06:52 +08:00
if (EnableAddOutput == true)
2021-07-23 09:42:22 +08:00
{
CinchMenuItem menuItem = new CinchMenuItem();
menuItem.Text = "添加输出";
menuItem.Command = AddOutputCommand;
menuItem.CommandParameter = menuItem;
menuOptions.Add(menuItem);
}
}
2023-01-27 14:54:03 +08:00
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
2021-07-23 09:42:22 +08:00
{
2023-01-27 14:54:03 +08:00
base.LoadDesignerItemViewModel(designerbase);
2021-07-23 09:42:22 +08:00
2023-01-24 17:53:04 +08:00
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();
2023-04-16 12:21:51 +08:00
if (designer.LogicalConnectors != null)
2021-07-23 09:42:22 +08:00
{
2023-04-16 12:21:51 +08:00
foreach (var connector in designer.LogicalConnectors)
2023-01-24 17:53:04 +08:00
{
2023-04-16 12:21:51 +08:00
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);
2023-01-24 17:53:04 +08:00
}
2021-07-23 09:42:22 +08:00
}
}
}
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;
}
2021-07-23 09:42:22 +08:00
2023-01-31 22:45:50 +08:00
public Dictionary<int, LogicalConnectorInfo> Input { get; set; } = new Dictionary<int, LogicalConnectorInfo>();
public Dictionary<int, LogicalConnectorInfo> Output { get; set; } = new Dictionary<int, LogicalConnectorInfo>();
2021-07-23 09:42:22 +08:00
2023-04-23 22:44:15 +08:00
public override void ClearConnectors()
{
Connectors.Clear();
2023-04-23 22:44:15 +08:00
Input.Clear();
Output.Clear();
}
public virtual LogicalConnectorInfo ExecuteAddInput(object parameter, int index = 0, string name = null)
2021-07-23 09:42:22 +08:00
{
if (Input.Values.Count >= 2)
{
this.ItemHeight = this.ItemHeight * (Input.Values.Count + 1) / Input.Values.Count;
}
2023-01-31 22:45:50 +08:00
LogicalConnectorInfo connector = new LogicalConnectorInfo(this, ConnectorOrientation.Left, true, false, ValueTypeInput.Count > index ? ValueTypeInput[index] : ValueTypeInput[0]);
2021-07-23 09:42:22 +08:00
connector.XRatio = 0;
2023-04-23 22:44:15 +08:00
connector.Name = name ?? $"Input{index}";
2021-07-23 09:42:22 +08:00
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);
2021-07-23 09:42:22 +08:00
}
AddConnector(connector);
2023-04-22 22:40:41 +08:00
return connector;
2021-07-23 09:42:22 +08:00
}
2023-04-23 22:44:15 +08:00
public virtual LogicalConnectorInfo ExecuteAddOutput(object parameter, int index = 0, string name = null)
2021-07-23 09:42:22 +08:00
{
2023-01-31 22:45:50 +08:00
LogicalConnectorInfo connector = new LogicalConnectorInfo(this, ConnectorOrientation.Right, true, false, ValueTypeOutput.Count > index ? ValueTypeOutput[index] : ValueTypeInput[0]);
2021-07-23 09:42:22 +08:00
connector.XRatio = 1;
2023-04-23 22:44:15 +08:00
connector.Name = name ?? $"Output{index}";
2021-07-23 09:42:22 +08:00
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);
2021-07-23 09:42:22 +08:00
}
AddConnector(connector);
2023-04-22 22:40:41 +08:00
return connector;
2021-07-23 09:42:22 +08:00
}
2023-04-29 18:36:50 +08:00
public virtual List<ConnectorValueType> ValueTypeInput
2021-07-23 09:42:22 +08:00
{
get
{
2023-04-29 18:36:50 +08:00
return new List<ConnectorValueType>() { ConnectorValueType.Real };
2021-07-23 09:42:22 +08:00
}
}
2023-04-29 18:36:50 +08:00
public virtual List<ConnectorValueType> ValueTypeOutput
2021-07-23 09:42:22 +08:00
{
get
{
2023-04-29 18:36:50 +08:00
return new List<ConnectorValueType>() { ConnectorValueType.Real };
2021-07-23 09:42:22 +08:00
}
}
2023-04-16 10:10:12 +08:00
public void Execute()
{
GetInput();
CalculateOutput();
}
2023-04-29 18:36:50 +08:00
public virtual void GetInput()
{
2023-04-16 20:11:40 +08:00
foreach (var input in Input)
{
var connector = GetSourceItem(input.Value);
if (connector == null)
{
2023-04-26 22:53:44 +08:00
input.Value.ErrorCode = ConnectorErrorCode.None;
2023-04-16 20:11:40 +08:00
continue;
}
2023-05-03 09:59:46 +08:00
if (connector.SourceConnectorInfoFully?.DataItem is LogicalGateItemViewModelBase sourceItem)
2023-04-16 20:11:40 +08:00
{
2023-05-03 09:59:46 +08:00
var output = (connector.SourceConnectorInfoFully as LogicalConnectorInfo);
2023-04-16 20:11:40 +08:00
2023-05-01 00:10:55 +08:00
if (EnableInputValue(connector, input.Value, output))
2023-04-16 20:11:40 +08:00
{
2023-05-01 00:10:55 +08:00
connector.ColorViewModel.LineColor.Color = output.ColorViewModel.FillColor.Color;
connector.ColorViewModel.FillColor.Color = output.ColorViewModel.FillColor.Color;
connector.AnimationViewModel.Color = output.ColorViewModel.FillColor.Color;
2023-04-25 23:07:25 +08:00
input.Value.ConnectorValue = output.ConnectorValue;
input.Value.ConnectorString = output.ConnectorString;
2023-05-03 09:59:46 +08:00
input.Value.ColorViewModel.FillColor.Color = connector.SourceConnectorInfoFully.ColorViewModel.FillColor.Color;
2023-04-25 23:07:25 +08:00
if (LogicalType == LogicalType.Output)
{
2023-05-03 09:59:46 +08:00
input.Value.ConnectorValueType = (connector.SourceConnectorInfoFully as LogicalConnectorInfo).ConnectorValueType;
2023-04-25 23:07:25 +08:00
}
else if (LogicalType == LogicalType.NOT)
{
2023-05-03 09:59:46 +08:00
input.Value.ConnectorValueType = ((connector.SourceConnectorInfoFully as LogicalConnectorInfo).ConnectorValueType == ConnectorValueType.Bool) ? ConnectorValueType.Bool : ConnectorValueType.Int;
2023-04-25 23:07:25 +08:00
}
2023-05-01 00:10:55 +08:00
sourceItem.ClearOutputValue(connector, output);
2023-04-16 20:11:40 +08:00
}
2023-05-01 00:10:55 +08:00
sourceItem.StartAnimation(output);
2023-04-16 20:11:40 +08:00
}
}
}
public virtual void CalculateOutput()
{
2023-04-16 20:11:40 +08:00
foreach (var output in Output)
{
2023-04-26 22:53:44 +08:00
if (output.Value.ErrorCode != ConnectorErrorCode.None)
{
2023-04-26 22:53:44 +08:00
output.Value.ColorViewModel.FillColor.Color = Colors.DarkRed;
}
else if (output.Value.ConnectorValueType == ConnectorValueType.Bool)
2023-04-16 20:11:40 +08:00
{
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;
}
}
}
2023-05-01 00:10:55 +08:00
else if (output.Value.ConnectorValueType <= ConnectorValueType.ValueType)
2023-04-16 20:11:40 +08:00
{
output.Value.ColorViewModel.FillColor.Color = Colors.Green;
}
}
}
2021-07-23 09:42:22 +08:00
2023-05-01 00:10:55 +08:00
public virtual bool EnableInputValue(ConnectionViewModel connector, LogicalConnectorInfo input, LogicalConnectorInfo output)
{
if (!input.CanAttachTo(output))
{
input.ErrorCode = ConnectorErrorCode.ConnErr;
input.ErrorMessage = "连接类型不匹配";
input.ColorViewModel.FillColor.Color = Colors.DarkRed;
return false;
}
return true;
}
public virtual void ClearOutputValue(ConnectionViewModel connector, LogicalConnectorInfo output)
{
}
public virtual void StartAnimation(LogicalConnectorInfo output)
{
}
2023-04-16 20:11:40 +08:00
protected ConnectionViewModel GetSourceItem(FullyCreatedConnectorInfo sinkConnector)
{
2023-04-24 20:10:17 +08:00
return Root?.Items.OfType<ConnectionViewModel>().FirstOrDefault(p => p.SinkConnectorInfo == sinkConnector);
2023-04-16 20:11:40 +08:00
}
2023-05-01 00:10:55 +08:00
protected ConnectionViewModel GetSinkItem(FullyCreatedConnectorInfo sourceConnector)
{
2023-05-03 09:59:46 +08:00
return Root?.Items.OfType<ConnectionViewModel>().FirstOrDefault(p => p.SourceConnectorInfoFully == sourceConnector);
2023-05-01 00:10:55 +08:00
}
2023-04-16 20:11:40 +08:00
}
2021-07-23 09:42:22 +08:00
}