using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace PamhagenSysCtrl.Helpers.Pipeline { public class PipeJoin : INode { public const double SIZE = 18; public const double POINT = 4; public double CenterX { get; set; } public double CenterY { get; set; } public string Label => ""; public ISet Inputs { get; init; } public ISet Outputs { get; init; } private Shape? _rect; public PipeJoin(double x, double y) { CenterX = x; CenterY = y; Inputs = new HashSet(); Outputs = new HashSet(); } public void Draw(Canvas canvas) { var it = Inputs.Any(e => (e.Start.CenterY < CenterY && (!e.Orientation || e.Start.CenterX == CenterX)) || (e.IsTwoWay && e.End.CenterY < CenterY && (!e.Orientation || e.End.CenterX == CenterX))); var ot = Outputs.Any(e => (e.End.CenterY < CenterY && ( e.Orientation || e.End.CenterX == CenterX)) || (e.IsTwoWay && e.Start.CenterY < CenterY && ( e.Orientation || e.Start.CenterX == CenterX))); var ir = Inputs.Any(e => (e.Start.CenterX > CenterX && ( e.Orientation || e.Start.CenterY == CenterY)) || (e.IsTwoWay && e.End.CenterX > CenterX && ( e.Orientation || e.End.CenterY == CenterY))); var or = Outputs.Any(e => (e.End.CenterX > CenterX && (!e.Orientation || e.End.CenterY == CenterY)) || (e.IsTwoWay && e.Start.CenterX > CenterX && (!e.Orientation || e.Start.CenterY == CenterY))); var ib = Inputs.Any(e => (e.Start.CenterY > CenterY && (!e.Orientation || e.Start.CenterX == CenterX)) || (e.IsTwoWay && e.End.CenterY > CenterY && (!e.Orientation || e.End.CenterX == CenterX))); var ob = Outputs.Any(e => (e.End.CenterY > CenterY && ( e.Orientation || e.End.CenterX == CenterX)) || (e.IsTwoWay && e.Start.CenterY > CenterY && ( e.Orientation || e.Start.CenterX == CenterX))); var il = Inputs.Any(e => (e.Start.CenterX < CenterX && ( e.Orientation || e.Start.CenterY == CenterY)) || (e.IsTwoWay && e.End.CenterX < CenterX && ( e.Orientation || e.End.CenterY == CenterY))); var ol = Outputs.Any(e => (e.End.CenterX < CenterX && (!e.Orientation || e.End.CenterY == CenterY)) || (e.IsTwoWay && e.Start.CenterX < CenterX && (!e.Orientation || e.Start.CenterY == CenterY))); var points = new List { new(0, 0) }; if (ot && it) { points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, -POINT / 2), new(SIZE / 2, POINT / 2), new(SIZE / 2 + POINT, 0)]); } else if (ot) { points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, -POINT), new(SIZE / 2 + POINT, 0)]); } else if (it) { points.AddRange([new(SIZE / 2 - POINT, 0), new(SIZE / 2, POINT), new(SIZE / 2 + POINT, 0)]); } points.Add(new(SIZE, 0)); if (or && ir) { points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE + POINT / 2, SIZE / 2), new(SIZE - POINT / 2, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); } else if (or) { points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE + POINT, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); } else if (ir) { points.AddRange([new(SIZE, SIZE / 2 - POINT), new(SIZE - POINT, SIZE / 2), new(SIZE, SIZE / 2 + POINT)]); } points.Add(new(SIZE, SIZE)); if (ob && ib) { points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE + POINT / 2), new(SIZE / 2, SIZE - POINT / 2), new(SIZE / 2 - POINT, SIZE)]); } else if (ob) { points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE + POINT), new(SIZE / 2 - POINT, SIZE)]); } else if (ib) { points.AddRange([new(SIZE / 2 + POINT, SIZE), new(SIZE / 2, SIZE - POINT), new(SIZE / 2 - POINT, SIZE)]); } points.Add(new(0, SIZE)); if (ol && il) { points.AddRange([new(0, SIZE / 2 + POINT), new(-POINT / 2, SIZE / 2), new(POINT / 2, SIZE / 2), new(0, SIZE / 2 - POINT)]); } else if (ol) { points.AddRange([new(0, SIZE / 2 + POINT), new(-POINT, SIZE / 2), new(0, SIZE / 2 - POINT)]); } else if (il) { points.AddRange([new(0, SIZE / 2 + POINT), new(POINT, SIZE / 2), new(0, SIZE / 2 - POINT)]); } _rect = new Polygon() { Points = [..points], Fill = Brushes.Black, Stroke = Brushes.Black, StrokeThickness = 2, }; _rect.SetValue(Canvas.LeftProperty, CenterX - SIZE / 2); _rect.SetValue(Canvas.TopProperty, CenterY - SIZE / 2); canvas.Children.Add(_rect); } public bool IsInside(double x, double y) { return Math.Abs(x - CenterX) <= SIZE / 2 && Math.Abs(y - CenterY) <= SIZE / 2; } public void Update(bool isHovering, bool isPressed) { _rect?.Stroke = isHovering ? Brushes.Black : Brushes.Black; } } }