mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-03-03 00:00:57 +08:00
适应窗口大小完成
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
using AIStudio.Wpf.DiagramDesigner.Services;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// DefaultNode
|
||||
/// </summary>
|
||||
public class DefaultDesignerItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
public DefaultDesignerItemViewModel() : this(null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DefaultDesignerItemViewModel(IDiagramViewModel root) : base(root)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DefaultDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DefaultDesignerItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
{
|
||||
return new DesignerItemBase(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class GifImageItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
//private IDisposable propertyChangedSubscription;
|
||||
//private IDisposable connectorsChangedSubscription;
|
||||
|
||||
public GifImageItemViewModel() : this(null)
|
||||
{
|
||||
|
||||
}
|
||||
public GifImageItemViewModel(IDiagramViewModel root) : base(root)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public GifImageItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public GifImageItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
{
|
||||
return new MediaDesignerItem(this);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
base.Init(root);
|
||||
|
||||
ClearConnectors();
|
||||
//propertyChangedSubscription = WhenPropertyChanged.Where(o => o.ToString() == "Left" || o.ToString() == "Top" || o.ToString() == "ItemWidth" || o.ToString() == "ItemHeight").Subscribe(ChangeImageElement);
|
||||
//connectorsChangedSubscription = WhenConnectorsChanged.Subscribe(OnConnectorsChanged);
|
||||
|
||||
AddItemCommand = new SimpleCommand(Command_Enable, ExecuteAddItemCommand);
|
||||
ImageSwitchCommand = new SimpleCommand(Command_Enable, ExecuteImageSwitchCommand);
|
||||
BuildMenuOptions();
|
||||
}
|
||||
|
||||
|
||||
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
|
||||
{
|
||||
base.LoadDesignerItemViewModel(designerbase);
|
||||
|
||||
if (designerbase is MediaDesignerItem designer)
|
||||
{
|
||||
this.Icon = designer.Icon;
|
||||
foreach (var connector in designer.Connectors)
|
||||
{
|
||||
FullyCreatedConnectorInfo fullyCreatedConnectorInfo = new FullyCreatedConnectorInfo(this.Root, this, connector);
|
||||
AddConnector(fullyCreatedConnectorInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _shouldInsertAnchor;
|
||||
public bool ShouldInsertAnchor
|
||||
{
|
||||
get
|
||||
{
|
||||
return _shouldInsertAnchor;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _shouldInsertAnchor, value);
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleCommand AddItemCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand ImageSwitchCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
private string dir = System.AppDomain.CurrentDomain.BaseDirectory + "Images\\Gifs";
|
||||
private void BuildMenuOptions()
|
||||
{
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
menuOptions = new ObservableCollection<CinchMenuItem>();
|
||||
var equipmentImages = Directory.GetFiles(dir).Select(Path.GetFileName);
|
||||
foreach (var item in equipmentImages)
|
||||
{
|
||||
CinchMenuItem menuItem = new CinchMenuItem();
|
||||
menuItem.Text = item;
|
||||
menuItem.Command = ImageSwitchCommand;
|
||||
menuItem.CommandParameter = item;
|
||||
menuOptions.Add(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteAddItemCommand(object parameter)
|
||||
{
|
||||
FullyCreatedConnectorInfo connector = new FullyCreatedConnectorInfo(this, ConnectorOrientation.None, true);
|
||||
MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs;
|
||||
var position = mosueArg.GetPosition(((EventToCommandArgs)parameter).Sender as IInputElement);
|
||||
connector.XRatio = (position.X - connector.ConnectorWidth / 2) / connector.DataItem.ItemWidth;
|
||||
connector.YRatio = (position.Y - connector.ConnectorHeight / 2) / connector.DataItem.ItemHeight;
|
||||
AddConnector(connector);
|
||||
}
|
||||
|
||||
private void ExecuteImageSwitchCommand(object parameter)
|
||||
{
|
||||
string image = parameter as string;
|
||||
string path = dir + @"\{0}";
|
||||
string filePath = string.Format(path, image);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
Icon = filePath;
|
||||
}
|
||||
}
|
||||
|
||||
//private void OnConnectorsChanged(NotifyCollectionChangedEventArgs args)
|
||||
//{
|
||||
// if (args.Action == NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
// if (args.NewItems.Count > 0)
|
||||
// {
|
||||
// foreach (var item in args.NewItems)
|
||||
// {
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (args.Action == NotifyCollectionChangedAction.Remove)
|
||||
// {
|
||||
// if (args.OldItems.Count > 0)
|
||||
// {
|
||||
// foreach (var item in args.OldItems)
|
||||
// {
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (args.Action == NotifyCollectionChangedAction.Reset)
|
||||
// {
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class ImageItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
private static readonly string filter = "图片|*.bmp;*.jpg;*.jpeg;*.gif;*.png";
|
||||
|
||||
public ImageItemViewModel() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public ImageItemViewModel(IDiagramViewModel root) : base(root)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ImageItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ImageItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
{
|
||||
return new ImageDesignerItem(this);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
base.Init(root);
|
||||
|
||||
this.PropertyChanged += ImageItemViewModel_PropertyChanged;
|
||||
|
||||
BuildMenuOptions();
|
||||
}
|
||||
|
||||
private void ImageItemViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(ItemWidth) || e.PropertyName == nameof(ItemHeight) || e.PropertyName == nameof(ResizeMargin) || e.PropertyName == nameof(ClipMode))
|
||||
{
|
||||
RaisePropertyChanged(nameof(Object));
|
||||
}
|
||||
else if (e.PropertyName == nameof(IsSelected))
|
||||
{
|
||||
if (IsSelected == false)
|
||||
{
|
||||
EndResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _suffix;
|
||||
public string Suffix
|
||||
{
|
||||
get { return _suffix; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _suffix, filter.Contains(value) ? value : ".txt");
|
||||
}
|
||||
}
|
||||
|
||||
public ImageItemViewModel Object
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
public double ImageWidth { get; set; }
|
||||
public double ImageHeight { get; set; }
|
||||
|
||||
private bool _resizeMode;
|
||||
public bool ResizeMode
|
||||
{
|
||||
get { return _resizeMode; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _resizeMode, value);
|
||||
}
|
||||
}
|
||||
|
||||
//显示的时候是真实的Marigin,不显示的时候是按比例换算的Marigin
|
||||
private Thickness _resizeMargin = new Thickness(0);
|
||||
public Thickness ResizeMargin
|
||||
{
|
||||
get { return _resizeMargin; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _resizeMargin, value);
|
||||
}
|
||||
}
|
||||
|
||||
private ClipMode _clipMode;
|
||||
public ClipMode ClipMode
|
||||
{
|
||||
get { return _clipMode; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _clipMode, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
|
||||
{
|
||||
base.LoadDesignerItemViewModel(designerbase);
|
||||
|
||||
if (designerbase is ImageDesignerItem designer)
|
||||
{
|
||||
this.Icon = designer.Icon;
|
||||
Suffix = Path.GetExtension(this.Icon).ToLower();
|
||||
foreach (var connector in designer.Connectors)
|
||||
{
|
||||
FullyCreatedConnectorInfo fullyCreatedConnectorInfo = new FullyCreatedConnectorInfo(this.Root, this, connector);
|
||||
AddConnector(fullyCreatedConnectorInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildMenuOptions()
|
||||
{
|
||||
menuOptions = new ObservableCollection<CinchMenuItem>();
|
||||
CinchMenuItem menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "更换";
|
||||
menuItem.Command = MenuItemCommand;
|
||||
menuItem.CommandParameter = menuItem;
|
||||
menuOptions.Add(menuItem);
|
||||
}
|
||||
|
||||
private SimpleCommand _menuItemCommand;
|
||||
public SimpleCommand MenuItemCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._menuItemCommand ?? (this._menuItemCommand = new SimpleCommand(Command_Enable, ExecuteMenuItemCommand));
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteMenuItemCommand(object obj)
|
||||
{
|
||||
EditData();
|
||||
}
|
||||
|
||||
protected override void ExecuteEditCommand(object param)
|
||||
{
|
||||
if (IsReadOnly == true) return;
|
||||
|
||||
if (ResizeMode == true)
|
||||
{
|
||||
EndResize();
|
||||
return;
|
||||
}
|
||||
|
||||
System.Diagnostics.Process.Start(Icon);
|
||||
|
||||
}
|
||||
|
||||
public void InitWidthAndHeight()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = new FileStream(this.Icon, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
System.Drawing.Image image = System.Drawing.Image.FromStream(fs);
|
||||
this.ImageWidth = image.Width;
|
||||
this.ImageHeight = image.Height;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
this.Suffix = ".txt";
|
||||
this.ImageWidth = 32;
|
||||
this.ImageHeight = 32;
|
||||
}
|
||||
}
|
||||
public void AutoSize()
|
||||
{
|
||||
this.ItemWidth = this.ImageWidth;
|
||||
this.ItemHeight = this.ImageHeight;
|
||||
}
|
||||
|
||||
public override bool InitData()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Icon))
|
||||
return EditData();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool EditData()
|
||||
{
|
||||
Microsoft.Win32.OpenFileDialog openFile = new Microsoft.Win32.OpenFileDialog();
|
||||
openFile.Filter = filter;
|
||||
|
||||
if (openFile.ShowDialog() == true)
|
||||
{
|
||||
bool needauto = Icon == null;
|
||||
Icon = openFile.FileName;
|
||||
Suffix = Path.GetExtension(Icon).ToLower();
|
||||
InitWidthAndHeight();
|
||||
if (needauto)
|
||||
{
|
||||
AutoSize();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void StartResize()
|
||||
{
|
||||
if (ResizeMode == true) return;
|
||||
|
||||
ResizeMode = true;
|
||||
if (ResizeMargin == new Thickness(0, 0, 0, 0))
|
||||
{
|
||||
ResizeMargin = new Thickness(ItemWidth * 0.1, ItemHeight * 0.1, ItemWidth * 0.1, ItemHeight * 0.1);
|
||||
}
|
||||
else
|
||||
{
|
||||
var margin = ResizeMargin;
|
||||
double xradio = ItemWidth / ImageWidth;
|
||||
double yradio = ItemHeight / ImageHeight;
|
||||
ResizeMargin = new Thickness(margin.Left * xradio, margin.Top * yradio, margin.Right * xradio, margin.Bottom * yradio);
|
||||
|
||||
ItemWidth = ItemWidth + ResizeMargin.Left + ResizeMargin.Right;
|
||||
ItemHeight = ItemHeight + ResizeMargin.Top + ResizeMargin.Bottom;
|
||||
Left = Left - ResizeMargin.Left;
|
||||
Top = Top - ResizeMargin.Top;
|
||||
}
|
||||
}
|
||||
|
||||
public void EndResize()
|
||||
{
|
||||
if (ResizeMode == false)
|
||||
return;
|
||||
|
||||
ResizeMode = false;
|
||||
var margin = ResizeMargin;
|
||||
double xradio = ItemWidth / ImageWidth;
|
||||
double yradio = ItemHeight / ImageHeight;
|
||||
|
||||
ResizeMargin = new Thickness(margin.Left / xradio, margin.Top / yradio, margin.Right / xradio, margin.Bottom / yradio);
|
||||
ItemWidth = ItemWidth - margin.Left - margin.Right;
|
||||
ItemHeight = ItemHeight - margin.Top - margin.Bottom;
|
||||
Left = Left + margin.Left;
|
||||
Top = Top + margin.Top;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (ResizeMode == true)
|
||||
{
|
||||
ResizeMargin = new Thickness(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (ResizeMargin == new Thickness(0, 0, 0, 0))
|
||||
{
|
||||
ResizeMode = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var margin = ResizeMargin;
|
||||
ResizeMargin = new Thickness(0, 0, 0, 0);
|
||||
ItemWidth = ItemWidth + margin.Left + margin.Right;
|
||||
ItemHeight = ItemHeight + margin.Top + margin.Bottom;
|
||||
Left = Left - margin.Left;
|
||||
Top = Top - margin.Top;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public enum ClipMode
|
||||
{
|
||||
RectangleGeometry,
|
||||
EllipseGeometry
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class LinkPointDesignerItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
public LinkPointDesignerItemViewModel(Point location) : this(null, location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public LinkPointDesignerItemViewModel(IDiagramViewModel root, Point location) : base(root)
|
||||
{
|
||||
Left = Math.Max(0, location.X - ItemWidth / 2);
|
||||
Top = Math.Max(0, location.Y - ItemHeight / 2);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
base.Init(root);
|
||||
|
||||
this.ClearConnectors();
|
||||
this.AddConnector(new FullyCreatedConnectorInfo(this, ConnectorOrientation.None, true));
|
||||
|
||||
ItemWidth = 5;
|
||||
ItemHeight = 5;
|
||||
}
|
||||
|
||||
public Point CurrentLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Point() { X = Left + ItemWidth / 2, Y = Top + ItemHeight / 2 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public abstract class LogicalGateItemViewModelBase : DesignerItemViewModelBase
|
||||
{
|
||||
public SimpleCommand AddInputCommand { get; private set; }
|
||||
public SimpleCommand AddOutputCommand { get; private set; }
|
||||
|
||||
|
||||
public LogicalGateItemViewModelBase(LogicalType logicalType) : this(null, logicalType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public LogicalGateItemViewModelBase(IDiagramViewModel root, LogicalType logicalType) : base(root)
|
||||
{
|
||||
this.LogicalType = logicalType;
|
||||
|
||||
if (this.LogicalType == LogicalType.Input)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddOutput(null);
|
||||
}
|
||||
else if (this.LogicalType == LogicalType.Output)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddInput(null);
|
||||
}
|
||||
else if (this.LogicalType == LogicalType.Constant)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddOutput(null);
|
||||
}
|
||||
else if (this.LogicalType == LogicalType.Time)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddOutput(null);
|
||||
}
|
||||
else if (this.LogicalType == LogicalType.None)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddOutput(null);
|
||||
}
|
||||
else if (this.LogicalType == LogicalType.NOT)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddInput(null);
|
||||
ExecuteAddOutput(null);
|
||||
}
|
||||
else if (this.LogicalType == LogicalType.SEL)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddInput(null, 0);
|
||||
ExecuteAddInput(null, 1);
|
||||
ExecuteAddInput(null, 2);
|
||||
ExecuteAddOutput(null, 0);
|
||||
}
|
||||
else if (this.LogicalType >= LogicalType.ABS && this.LogicalType <= LogicalType.EXPT)
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddInput(null);
|
||||
ExecuteAddOutput(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearConnectors();
|
||||
ExecuteAddInput(null);
|
||||
ExecuteAddInput(null);
|
||||
ExecuteAddOutput(null);
|
||||
}
|
||||
BuildMenuOptions();
|
||||
}
|
||||
|
||||
public LogicalGateItemViewModelBase(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
BuildMenuOptions();
|
||||
}
|
||||
|
||||
public LogicalGateItemViewModelBase(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
BuildMenuOptions();
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
{
|
||||
return new LogicalGateDesignerItemBase(this);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
ShowRotate = false;
|
||||
ShowArrow = false;
|
||||
AddInputCommand = new SimpleCommand(Command_Enable, para => ExecuteAddInput(para));
|
||||
AddOutputCommand = new SimpleCommand(Command_Enable, para => ExecuteAddOutput(para));
|
||||
|
||||
base.Init(root);
|
||||
}
|
||||
|
||||
private void BuildMenuOptions()
|
||||
{
|
||||
bool enAddInput = false;
|
||||
bool enAddOutput = false;
|
||||
if (LogicalType >= LogicalType.ADD && LogicalType <= LogicalType.AVE)
|
||||
{
|
||||
enAddInput = true;
|
||||
enAddOutput = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
enAddInput = false;
|
||||
enAddOutput = false;
|
||||
}
|
||||
|
||||
menuOptions = new ObservableCollection<CinchMenuItem>();
|
||||
if (enAddInput == true)
|
||||
{
|
||||
CinchMenuItem menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "添加输入";
|
||||
menuItem.Command = AddInputCommand;
|
||||
menuItem.CommandParameter = menuItem;
|
||||
menuOptions.Add(menuItem);
|
||||
}
|
||||
if (enAddOutput == 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();
|
||||
|
||||
foreach (var connector in designer.Connectors)
|
||||
{
|
||||
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 void 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);
|
||||
}
|
||||
|
||||
public virtual void 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);
|
||||
}
|
||||
|
||||
public List<ValueTypePoint> ValueTypeInput
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LogicalType == LogicalType.NOT)
|
||||
{
|
||||
return new List<ValueTypePoint>() { ValueTypePoint.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<ValueTypePoint>() { ValueTypePoint.Int };
|
||||
}
|
||||
else if (LogicalType == LogicalType.SEL)
|
||||
{
|
||||
return new List<ValueTypePoint>() { ValueTypePoint.Bool, ValueTypePoint.Real, ValueTypePoint.Real };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<ValueTypePoint>() { ValueTypePoint.Real };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<ValueTypePoint> 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<ValueTypePoint>() { ValueTypePoint.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<ValueTypePoint>() { ValueTypePoint.Int };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<ValueTypePoint>() { ValueTypePoint.Real };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class MediaItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
protected virtual string Filter { get; set; } = "媒体·|*.*";
|
||||
|
||||
public MediaItemViewModel() : this(null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MediaItemViewModel(IDiagramViewModel root) : base(root)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MediaItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MediaItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
{
|
||||
return new MediaDesignerItem(this);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
base.Init(root);
|
||||
|
||||
BuildMenuOptions();
|
||||
}
|
||||
|
||||
|
||||
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
|
||||
{
|
||||
base.LoadDesignerItemViewModel(designerbase);
|
||||
|
||||
if (designerbase is MediaDesignerItem designer)
|
||||
{
|
||||
this.Icon = designer.Icon;
|
||||
|
||||
foreach (var connector in designer.Connectors)
|
||||
{
|
||||
FullyCreatedConnectorInfo fullyCreatedConnectorInfo = new FullyCreatedConnectorInfo(this.Root, this, connector);
|
||||
AddConnector(fullyCreatedConnectorInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildMenuOptions()
|
||||
{
|
||||
menuOptions = new ObservableCollection<CinchMenuItem>();
|
||||
CinchMenuItem menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "更换";
|
||||
menuItem.Command = MenuItemCommand;
|
||||
menuItem.CommandParameter = menuItem;
|
||||
menuOptions.Add(menuItem);
|
||||
}
|
||||
|
||||
private SimpleCommand _menuItemCommand;
|
||||
public SimpleCommand MenuItemCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._menuItemCommand ?? (this._menuItemCommand = new SimpleCommand(Command_Enable, ExecuteMenuItemCommand));
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteMenuItemCommand(object obj)
|
||||
{
|
||||
EditData();
|
||||
}
|
||||
|
||||
public override bool InitData()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Icon))
|
||||
return EditData();
|
||||
return true;
|
||||
}
|
||||
public override bool EditData()
|
||||
{
|
||||
Microsoft.Win32.OpenFileDialog openFile = new Microsoft.Win32.OpenFileDialog();
|
||||
openFile.Filter = Filter;
|
||||
|
||||
if (openFile.ShowDialog() == true)
|
||||
{
|
||||
Icon = openFile.FileName;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void ExecuteEditCommand(object param)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class PointDesignerItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
public PointDesignerItemViewModel(Point location) : this(null, location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PointDesignerItemViewModel(IDiagramViewModel root, Point location) : base(root)
|
||||
{
|
||||
Left = Math.Max(0, location.X - ItemWidth / 2);
|
||||
Top = Math.Max(0, location.Y - ItemHeight / 2);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
base.Init(root);
|
||||
|
||||
this.ClearConnectors();
|
||||
this.AddConnector(new FullyCreatedConnectorInfo(this, ConnectorOrientation.None, true));
|
||||
|
||||
ItemWidth = 5;
|
||||
ItemHeight = 5;
|
||||
}
|
||||
|
||||
private bool _showConnectors = false;
|
||||
public new bool ShowConnectors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _showConnectors;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _showConnectors, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Point CurrentLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Point() { X = Left + ItemWidth / 2, Y = Top + ItemHeight / 2 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class ShapeDesignerItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
public ShapeDesignerItemViewModel(DrawMode drawMode, List<Point> points) : this(null, drawMode, points)
|
||||
{
|
||||
}
|
||||
|
||||
public ShapeDesignerItemViewModel(IDiagramViewModel root, DrawMode drawMode, List<Point> points) : base(root)
|
||||
{
|
||||
DrawMode = drawMode;
|
||||
ConnectionPoints = points;
|
||||
|
||||
ItemWidth = ConnectionPoints.Max(p => p.X) - ConnectionPoints.Min(p => p.X);
|
||||
ItemHeight = ConnectionPoints.Max(p => p.Y) - ConnectionPoints.Min(p => p.Y);
|
||||
Left = ConnectionPoints.Min(p => p.X);
|
||||
Top = ConnectionPoints.Min(p => p.Y);
|
||||
|
||||
PointDesignerItemViewModels = new List<PointDesignerItemViewModel>();
|
||||
ConnectionPoints.ForEach((Action<Point>)(p => {
|
||||
var item = new PointDesignerItemViewModel(p);
|
||||
PointDesignerItemViewModels.Add((PointDesignerItemViewModel)item);
|
||||
}));
|
||||
|
||||
PointDesignerItemViewModels.ForEach(p => p.PropertyChanged += PointDesignerItemViewModel_PropertyChanged);
|
||||
}
|
||||
|
||||
public List<PointDesignerItemViewModel> PointDesignerItemViewModels
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
private List<Point> _connectionPoints;
|
||||
public List<Point> ConnectionPoints
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connectionPoints;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetProperty(ref _connectionPoints, value);
|
||||
}
|
||||
}
|
||||
public DrawMode DrawMode
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
private bool _showConnectors = false;
|
||||
public new bool ShowConnectors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _showConnectors;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _showConnectors, value))
|
||||
{
|
||||
foreach (var connector in PointDesignerItemViewModels)
|
||||
{
|
||||
connector.ShowConnectors = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleCommand MenuItemCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
private void PointDesignerItemViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(Left) || e.PropertyName == nameof(Top))
|
||||
{
|
||||
UpdatePoints();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePoints()
|
||||
{
|
||||
ConnectionPoints = PointDesignerItemViewModels.Select(p => p.CurrentLocation).ToList();
|
||||
ItemWidth = ConnectionPoints.Max(p => p.X) - ConnectionPoints.Min(p => p.X);
|
||||
ItemHeight = ConnectionPoints.Max(p => p.Y) - ConnectionPoints.Min(p => p.Y);
|
||||
Left = ConnectionPoints.Min(p => p.X);
|
||||
Top = ConnectionPoints.Min(p => p.Y);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
MenuItemCommand = new SimpleCommand(Command_Enable, ExecuteMenuItemCommand);
|
||||
base.Init(root);
|
||||
|
||||
this.ClearConnectors();
|
||||
|
||||
BuildMenuOptions();
|
||||
}
|
||||
|
||||
private void ExecuteMenuItemCommand(object obj)
|
||||
{
|
||||
ShowConnectors = (obj as CinchMenuItem).IsChecked;
|
||||
}
|
||||
|
||||
private void BuildMenuOptions()
|
||||
{
|
||||
menuOptions = new ObservableCollection<CinchMenuItem>();
|
||||
CinchMenuItem menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "显示点";
|
||||
menuItem.IsCheckable = true;
|
||||
menuItem.Command = MenuItemCommand;
|
||||
menuItem.CommandParameter = menuItem;
|
||||
menuOptions.Add(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
using System;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// DefaultTextNode
|
||||
/// </summary>
|
||||
public class TextDesignerItemViewModel : DesignerItemViewModelBase
|
||||
{
|
||||
public TextDesignerItemViewModel() : this(null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TextDesignerItemViewModel(IDiagramViewModel root) : base(root)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TextDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TextDesignerItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
{
|
||||
return new TextDesignerItem(this);
|
||||
}
|
||||
|
||||
protected override void Init(IDiagramViewModel root)
|
||||
{
|
||||
base.Init(root);
|
||||
|
||||
CustomText = true;
|
||||
|
||||
this.ItemWidth = 150;
|
||||
this.ClearConnectors();
|
||||
}
|
||||
|
||||
private string _watermark = "请输入文本";
|
||||
public string Watermark
|
||||
{
|
||||
get
|
||||
{
|
||||
return _watermark;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _watermark, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class VideoItemViewModel : MediaItemViewModel
|
||||
{
|
||||
protected override string Filter { get; set; } = "视频|*.wmv;*.asf;*.asx;*.rm;*.rmvb;*.mp4;*.3gp;*.mov;*.m4v;*.avi;*.dat;*.mkv;*.flv;*.vob";
|
||||
|
||||
public VideoItemViewModel() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public VideoItemViewModel(IDiagramViewModel root) : base(root)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public VideoItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public VideoItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
{
|
||||
return new MediaDesignerItem(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user