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, string json) : base(root, json) { ShapeDefiner = Shapes.Rectangle; } 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; } } public override SelectableItemBase 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)); } #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.GridMargin + (Root.GridCellSize.Width - this.ItemWidth) / 2; } } else if (Root.CellHorizontalAlignment == CellHorizontalAlignment.Left) { this.Left = (int)(this.Left / Root.GridCellSize.Width) * Root.GridCellSize.Width + Root.GridMargin; } else if (Root.CellHorizontalAlignment == CellHorizontalAlignment.Right) { if (Root.GridCellSize.Width > this.ItemWidth) { this.Left = (int)(this.Left / Root.GridCellSize.Width) * Root.GridCellSize.Width + Root.GridMargin + (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.GridMargin + (Root.GridCellSize.Height - this.ItemHeight) / 2; } } else if (Root.CellVerticalAlignment == CellVerticalAlignment.Top) { this.Top = (int)(this.Top / Root.GridCellSize.Height) * Root.GridCellSize.Height + Root.GridMargin; } else if (Root.CellVerticalAlignment == CellVerticalAlignment.Bottom) { if (Root.GridCellSize.Height > this.ItemHeight) { this.Top = (int)(this.Top / Root.GridCellSize.Height) * Root.GridCellSize.Height + Root.GridMargin + (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 } }