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;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner
{
public abstract class DesignerItemViewModelBase : SelectableDesignerItemViewModelBase
{
public DesignerItemViewModelBase() : base()
{
ShapeDefiner = Shapes.Rectangle;
}
public DesignerItemViewModelBase(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
{
ShapeDefiner = Shapes.Rectangle;
}
public DesignerItemViewModelBase(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
{
ShapeDefiner = Shapes.Rectangle;
}
public override SelectableItemBase GetSerializableObject()
{
return new DesignerItemBase(this);
}
protected override void Init()
{
base.Init();
InitConnector();
}
protected override void LoadDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designerbase)
{
base.LoadDesignerItemViewModel(root, designerbase);
if (designerbase is DesignerItemBase designer)
{
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;
}
}
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));
}
#region 属性
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; }
}
public Style ConnectorStyle
{
get; set;
}
public ShapeDefiner ShapeDefiner
{
get;
}
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]
public SizeBase Size
{
get
{
return new SizeBase(ItemWidth, ItemHeight);
}
set
{
ItemWidth = value.Width;
ItemHeight = value.Height;
}
}
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);
}
}
private bool _showRotate = false;
[Browsable(true)]
public bool ShowRotate
{
get
{
return _showRotate;
}
set
{
SetProperty(ref _showRotate, value);
}
}
public bool ShowArrow { get; set; } = true;
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);
}
}
public PointBase Position
{
get
{
return new PointBase(Left, Top);
}
}
[CanDo]
public PointBase TopLeft
{
get
{
return new PointBase(Left, Top);
}
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);
}
}
///
/// 连接点是否可以按偏移自定义
///
public bool IsInnerConnector { get; set; }
private ObservableCollection connectors = new ObservableCollection();
public IEnumerable Connectors { get { return connectors; } }
protected ObservableCollection menuOptions;
public IEnumerable 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 WhenConnectorsChanged
{
get
{
return Observable
.FromEventPattern(
h => this.connectors.CollectionChanged += h,
h => this.connectors.CollectionChanged -= h)
.Select(x => x.EventArgs);
}
}
#endregion
#region 方法
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 (Root.CellHorizontalAlignment == CellHorizontalAlignment.Center)
{
if (Root.GridCellSize.Width > this.ItemWidth)
{
this.Left = (int)(this.Left / Root.GridCellSize.Width) * Root.GridCellSize.Width + Root.GridMarginSize.Width + (Root.GridCellSize.Width - this.ItemWidth) / 2;
}
}
else if (Root.CellHorizontalAlignment == CellHorizontalAlignment.Left)
{
this.Left = (int)(this.Left / Root.GridCellSize.Width) * Root.GridCellSize.Width + Root.GridMarginSize.Width;
}
else if (Root.CellHorizontalAlignment == CellHorizontalAlignment.Right)
{
if (Root.GridCellSize.Width > this.ItemWidth)
{
this.Left = (int)(this.Left / Root.GridCellSize.Width) * Root.GridCellSize.Width + Root.GridMarginSize.Width + (Root.GridCellSize.Width - this.ItemWidth);
}
}
if (Root.CellVerticalAlignment == CellVerticalAlignment.Center)
{
if (Root.GridCellSize.Height > this.ItemHeight)
{
this.Top = (int)(this.Top / Root.GridCellSize.Height) * Root.GridCellSize.Height + Root.GridMarginSize.Height + (Root.GridCellSize.Height - this.ItemHeight) / 2;
}
}
else if (Root.CellVerticalAlignment == CellVerticalAlignment.Top)
{
this.Top = (int)(this.Top / Root.GridCellSize.Height) * Root.GridCellSize.Height + Root.GridMarginSize.Height;
}
else if (Root.CellVerticalAlignment == CellVerticalAlignment.Bottom)
{
if (Root.GridCellSize.Height > this.ItemHeight)
{
this.Top = (int)(this.Top / Root.GridCellSize.Height) * Root.GridCellSize.Height + Root.GridMarginSize.Height + (Root.GridCellSize.Height - this.ItemHeight);
}
}
}
}
public void RaiseTopLeft()
{
this.RaisePropertyChanged(nameof(TopLeft), new PointBase(GetOldValue(nameof(Left)), GetOldValue(nameof(Top))), TopLeft);
}
public void RaiseItemWidthHeight()
{
this.RaisePropertyChanged(nameof(Size), new SizeBase(GetOldValue(nameof(ItemWidth)), GetOldValue(nameof(ItemHeight))), Size);
}
public void RaiseAngle()
{
this.RaisePropertyChanged(nameof(Angle), GetOldValue(nameof(Angle)), Angle);
}
public RectangleBase GetBounds(bool includePorts = false)
{
if (!includePorts)
return new RectangleBase(Position, Size);
var leftPort = LeftConnector;
var topPort = TopConnector;
var rightPort = RightConnector;
var bottomPort = BottomConnector;
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);
var right = rightPort == null ? Position.X + ItemWidth :
Math.Max(rightPort.Position.X + rightPort.ConnectorWidth, Position.X + ItemWidth);
var bottom = bottomPort == null ? Position.Y + ItemHeight :
Math.Max(bottomPort.Position.Y + bottomPort.ConnectorHeight, Position.Y + ItemHeight);
return new RectangleBase(left, top, right, bottom, true);
}
public IShape GetShape() => ShapeDefiner(this);
#endregion
}
}