Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs

465 lines
13 KiB
C#
Raw Normal View History

2021-07-23 09:42:22 +08:00
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows;
using System.Linq;
using System.Reactive.Linq;
using AIStudio.Wpf.DiagramDesigner.Models;
2023-01-12 23:02:53 +08:00
using AIStudio.Wpf.DiagramDesigner.Geometrys;
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-24 09:02:40 +08:00
public abstract class DesignerItemViewModelBase : SelectableDesignerItemViewModelBase
2021-07-23 09:42:22 +08:00
{
public DesignerItemViewModelBase() : base()
{
2023-01-12 23:02:53 +08:00
ShapeDefiner = Shapes.Rectangle;
2021-07-23 09:42:22 +08:00
}
public DesignerItemViewModelBase(IDiagramViewModel parent, DesignerItemBase designer) : base(parent, designer)
{
2023-01-12 23:02:53 +08:00
ShapeDefiner = Shapes.Rectangle;
2021-07-23 09:42:22 +08:00
}
public DesignerItemViewModelBase(IDiagramViewModel parent, string json) : base(parent, json)
{
2023-01-12 23:02:53 +08:00
ShapeDefiner = Shapes.Rectangle;
}
2021-07-23 09:42:22 +08:00
protected override void Init()
{
base.Init();
InitConnector();
2021-07-23 09:42:22 +08:00
}
protected override void LoadDesignerItemViewModel(IDiagramViewModel parent, SelectableDesignerItemBase designerbase)
{
base.LoadDesignerItemViewModel(parent, designerbase);
DesignerItemBase designer = designerbase as DesignerItemBase;
this.Left = designer.Left;
this.Top = designer.Top;
this.Angle = designer.Angle;
this.ScaleX = designer.ScaleX;
this.ScaleY = designer.ScaleY;
this.ItemWidth = designer.ItemWidth;
this.ItemHeight = designer.ItemHeight;
this.Icon = designer.Icon;
}
2021-07-23 09:42:22 +08:00
public override SelectableDesignerItemBase ToXmlObject()
{
return new DesignerItemBase(this);
}
public override Type ToXmlType()
{
return typeof(DesignerItemBase);
}
protected virtual void InitConnector()
{
connectors.Add(new FullyCreatedConnectorInfo(this, ConnectorOrientation.Top));
connectors.Add(new FullyCreatedConnectorInfo(this, ConnectorOrientation.Bottom));
connectors.Add(new FullyCreatedConnectorInfo(this, ConnectorOrientation.Left));
connectors.Add(new FullyCreatedConnectorInfo(this, ConnectorOrientation.Right));
2021-07-23 09:42:22 +08:00
}
2023-01-23 15:43:44 +08:00
#region
2021-07-23 09:42:22 +08:00
public FullyCreatedConnectorInfo TopConnector
{
get { return (connectors != null && connectors.Count >= 1) ? connectors[0] : null; }
}
public FullyCreatedConnectorInfo BottomConnector
{
get { return (connectors != null && connectors.Count >= 2) ? connectors[1] : null; }
}
public FullyCreatedConnectorInfo LeftConnector
{
get { return (connectors != null && connectors.Count >= 3) ? connectors[2] : null; }
}
public FullyCreatedConnectorInfo RightConnector
{
get { return (connectors != null && connectors.Count >= 4) ? connectors[3] : null; }
}
2023-01-23 15:43:44 +08:00
public Style ConnectorStyle
{
get; set;
}
2023-01-08 09:22:37 +08:00
public ShapeDefiner ShapeDefiner
{
get;
}
2021-07-23 09:42:22 +08:00
private string _icon;
[CanDo]
public string Icon
{
get
{
return _icon;
}
set
{
SetProperty(ref _icon, value);
}
}
private double _itemWidth = 65;
[Browsable(true)]
[CanDo]
public double ItemWidth
{
get
{
return _itemWidth;
}
set
{
if (value <= 0) return;
SetProperty(ref _itemWidth, value);
}
}
private double _itemHeight = 65;
[Browsable(true)]
[CanDo]
public double ItemHeight
{
get
{
return _itemHeight;
}
set
{
if (value <= 0) return;
SetProperty(ref _itemHeight, value);
}
}
[CanDo]
2023-01-08 09:22:37 +08:00
public SizeBase Size
2021-07-23 09:42:22 +08:00
{
get
{
2023-01-08 09:22:37 +08:00
return new SizeBase(ItemWidth, ItemHeight);
2021-07-23 09:42:22 +08:00
}
set
{
2023-01-08 09:22:37 +08:00
ItemWidth = value.Width;
ItemHeight = value.Height;
2021-07-23 09:42:22 +08:00
}
}
private bool _showConnectors = false;
[Browsable(false)]
public bool ShowConnectors
{
get
{
return _showConnectors;
}
set
{
if (SetProperty(ref _showConnectors, value))
{
foreach (var connector in connectors)
{
connector.ShowConnectors = value;
}
}
}
}
private bool _showResize = true;
[Browsable(false)]
public bool ShowResize
{
get
{
return _showResize;
}
set
{
SetProperty(ref _showResize, value);
}
}
2023-01-22 21:46:59 +08:00
private bool _showRotate = false;
[Browsable(true)]
public bool ShowRotate
{
get
{
return _showRotate;
}
set
{
SetProperty(ref _showRotate, value);
}
}
public bool ShowArrow { get; set; } = true;
2021-07-23 09:42:22 +08:00
private double _left;
[Browsable(true)]
[CanDo]
public double Left
{
get
{
return _left;
}
set
{
SetProperty(ref _left, value);
}
}
private double _top;
[Browsable(true)]
[CanDo]
public double Top
{
get
{
return _top;
}
set
{
SetProperty(ref _top, value);
}
2023-01-08 09:22:37 +08:00
}
2021-07-23 09:42:22 +08:00
2023-01-08 09:22:37 +08:00
public PointBase Position
{
get
{
return new PointBase(Left, Top);
}
}
[CanDo]
public PointBase TopLeft
2021-07-23 09:42:22 +08:00
{
get
{
2023-01-08 09:22:37 +08:00
return new PointBase(Left, Top);
2021-07-23 09:42:22 +08:00
}
set
{
Left = value.X;
Top = value.Y;
}
}
private double _angle;
[CanDo]
public double Angle
{
get
{
return _angle;
}
set
{
SetProperty(ref _angle, value);
}
}
private double _scaleX = 1;
[CanDo]
public double ScaleX
{
get
{
return _scaleX;
}
set
{
SetProperty(ref _scaleX, value);
}
}
private double _scaleY = 1;
[CanDo]
public double ScaleY
{
get
{
return _scaleY;
}
set
{
SetProperty(ref _scaleY, value);
}
}
private double _margin;
public double Margin
{
get
{
return _margin;
}
set
{
SetProperty(ref _margin, value);
}
}
/// <summary>
/// 连接点是否可以按偏移自定义
/// </summary>
public bool IsInnerConnector { get; set; }
2021-07-23 09:42:22 +08:00
private ObservableCollection<FullyCreatedConnectorInfo> connectors = new ObservableCollection<FullyCreatedConnectorInfo>();
public IEnumerable<FullyCreatedConnectorInfo> Connectors { get { return connectors; } }
protected ObservableCollection<CinchMenuItem> menuOptions;
public IEnumerable<CinchMenuItem> MenuOptions { get { return menuOptions; } }
public bool ShowMenuOptions
{
get
{
if (MenuOptions == null || MenuOptions.Count() == 0)
return false;
else
return true;
}
}
public bool BeginDo { get; set; }
public IObservable<NotifyCollectionChangedEventArgs> WhenConnectorsChanged
{
get
{
return Observable
.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
h => this.connectors.CollectionChanged += h,
h => this.connectors.CollectionChanged -= h)
.Select(x => x.EventArgs);
}
}
2023-01-23 15:43:44 +08:00
#endregion
#region
2021-07-23 09:42:22 +08:00
public void AddConnector(FullyCreatedConnectorInfo connector)
{
if (!connectors.Contains(connector))
{
connectors.Add(connector);
}
}
public void RemoveConnector(FullyCreatedConnectorInfo connector)
{
if (connectors.Contains(connector))
{
connectors.Remove(connector);
}
}
public void ClearConnectors()
{
connectors.Clear();
}
public void SetCellAlignment()
{
if (!(this is TextDesignerItemViewModel))
{
if (Parent.CellHorizontalAlignment == CellHorizontalAlignment.Center)
{
if (Parent.GridCellSize.Width > this.ItemWidth)
{
this.Left = (int)(this.Left / Parent.GridCellSize.Width) * Parent.GridCellSize.Width + Parent.GridMargin + (Parent.GridCellSize.Width - this.ItemWidth) / 2;
}
2021-07-23 09:42:22 +08:00
}
else if (Parent.CellHorizontalAlignment == CellHorizontalAlignment.Left)
2021-07-23 09:42:22 +08:00
{
this.Left = (int)(this.Left / Parent.GridCellSize.Width) * Parent.GridCellSize.Width + Parent.GridMargin;
}
else if (Parent.CellHorizontalAlignment == CellHorizontalAlignment.Right)
{
if (Parent.GridCellSize.Width > this.ItemWidth)
{
this.Left = (int)(this.Left / Parent.GridCellSize.Width) * Parent.GridCellSize.Width + Parent.GridMargin + (Parent.GridCellSize.Width - this.ItemWidth);
}
2021-07-23 09:42:22 +08:00
}
if (Parent.CellVerticalAlignment == CellVerticalAlignment.Center)
{
if (Parent.GridCellSize.Height > this.ItemHeight)
{
this.Top = (int)(this.Top / Parent.GridCellSize.Height) * Parent.GridCellSize.Height + Parent.GridMargin + (Parent.GridCellSize.Height - this.ItemHeight) / 2;
}
2021-07-23 09:42:22 +08:00
}
else if (Parent.CellVerticalAlignment == CellVerticalAlignment.Top)
{
2021-07-23 09:42:22 +08:00
this.Top = (int)(this.Top / Parent.GridCellSize.Height) * Parent.GridCellSize.Height + Parent.GridMargin;
}
else if (Parent.CellVerticalAlignment == CellVerticalAlignment.Bottom)
{
if (Parent.GridCellSize.Height > this.ItemHeight)
{
this.Top = (int)(this.Top / Parent.GridCellSize.Height) * Parent.GridCellSize.Height + Parent.GridMargin + (Parent.GridCellSize.Height - this.ItemHeight);
}
2021-07-23 09:42:22 +08:00
}
}
}
public void RaiseTopLeft()
{
2023-01-08 09:22:37 +08:00
this.RaisePropertyChanged(nameof(TopLeft), new PointBase(GetOldValue<double>(nameof(Left)), GetOldValue<double>(nameof(Top))), TopLeft);
2021-07-23 09:42:22 +08:00
}
public void RaiseItemWidthHeight()
{
2023-01-08 09:22:37 +08:00
this.RaisePropertyChanged(nameof(Size), new SizeBase(GetOldValue<double>(nameof(ItemWidth)), GetOldValue<double>(nameof(ItemHeight))), Size);
2021-07-23 09:42:22 +08:00
}
public void RaiseAngle()
{
this.RaisePropertyChanged(nameof(Angle), GetOldValue<double>(nameof(Angle)), Angle);
}
2023-01-08 09:22:37 +08:00
public RectangleBase GetBounds(bool includePorts = false)
{
if (!includePorts)
2023-01-12 23:02:53 +08:00
return new RectangleBase(Position, Size);
2023-01-08 09:22:37 +08:00
var leftPort = LeftConnector;
var topPort = TopConnector;
var rightPort = RightConnector;
var bottomPort = BottomConnector;
2023-01-15 20:27:39 +08:00
var left = leftPort == null ? Position.X: Math.Min(Position.X, leftPort.Position.X);
var top = topPort == null ? Position.Y : Math.Min(Position.Y, topPort.Position.Y);
2023-01-12 23:02:53 +08:00
var right = rightPort == null ? Position.X + ItemWidth :
2023-01-15 20:27:39 +08:00
Math.Max(rightPort.Position.X + rightPort.ConnectorWidth, Position.X + ItemWidth);
2023-01-12 23:02:53 +08:00
var bottom = bottomPort == null ? Position.Y + ItemHeight :
2023-01-15 20:27:39 +08:00
Math.Max(bottomPort.Position.Y + bottomPort.ConnectorHeight, Position.Y + ItemHeight);
2023-01-08 09:22:37 +08:00
2023-01-12 23:02:53 +08:00
return new RectangleBase(left, top, right, bottom, true);
2023-01-08 09:22:37 +08:00
}
2023-01-12 23:02:53 +08:00
public IShape GetShape() => ShapeDefiner(this);
2023-01-23 15:43:44 +08:00
#endregion
2021-07-23 09:42:22 +08:00
}
}