using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace PamhagenSysCtrl.Helpers.Pipeline { public abstract class Valve : INode { public const double LENGTH = 4.8; public const double WIDTH = 2.6; public double CenterX { get; set; } public double CenterY { get; set; } public abstract string Label { get; } public Brush? Highlight { get; set; } public int Orientation { get; set; } public bool IsOpen => CallbackIsOpen(); public ISet Inputs { get; init; } public ISet Outputs { get; init; } protected Func CallbackIsOpen; protected Rectangle? _background; protected Polygon? _triangles; protected Polyline? _topLine; protected Polyline? _bottomLine; protected TextBlock? _text; public Valve(double x, double y, int orientation, Func cbOpen) { CenterX = x; CenterY = y; CallbackIsOpen = cbOpen; Inputs = new HashSet(); Outputs = new HashSet(); Orientation = orientation; } public void Draw(Canvas canvas) { _background = new Rectangle() { Fill = Brushes.White, }; _triangles = new Polygon() { Fill = Brushes.DarkGray, Stroke = Brushes.Black, }; _topLine = new Polyline() { Stroke = Brushes.Black, }; _bottomLine = new Polyline() { Stroke = Brushes.Black, }; _text = new() { Text = Label, VerticalAlignment = VerticalAlignment.Center, SnapsToDevicePixels = true, }; canvas.Children.Add(_background); canvas.Children.Add(_triangles); canvas.Children.Add(_topLine); canvas.Children.Add(_bottomLine); canvas.Children.Add(_text); } public void Scale(double scale) { var border = Graph.ToBorder(scale); if (Orientation == 0 || Orientation == 2) { Graph.SetCenter(_background, CenterX, CenterY, LENGTH / 2, LENGTH, scale); _triangles?.Points = [ Graph.ToPx(CenterX - WIDTH / 2, CenterY - LENGTH / 2, scale), Graph.ToPx(CenterX + WIDTH / 2, CenterY + LENGTH / 2, scale), Graph.ToPx(CenterX - WIDTH / 2, CenterY + LENGTH / 2, scale), Graph.ToPx(CenterX + WIDTH / 2, CenterY - LENGTH / 2, scale), ]; _topLine?.Points = [ Graph.ToPx(CenterX - WIDTH / 2, CenterY - LENGTH / 4, scale), Graph.ToPx(CenterX - WIDTH / 4, CenterY, scale), Graph.ToPx(CenterX - WIDTH / 2, CenterY + LENGTH / 4, scale), ]; _bottomLine?.Points = [ Graph.ToPx(CenterX + WIDTH / 2, CenterY - LENGTH / 4, scale), Graph.ToPx(CenterX + WIDTH / 4, CenterY, scale), Graph.ToPx(CenterX + WIDTH / 2, CenterY + LENGTH / 4, scale), ]; } else { Graph.SetCenter(_background, CenterX, CenterY, LENGTH, LENGTH / 2, scale); _triangles?.Points = [ Graph.ToPx(CenterX - LENGTH / 2, CenterY - WIDTH / 2, scale), Graph.ToPx(CenterX + LENGTH / 2, CenterY + WIDTH / 2, scale), Graph.ToPx(CenterX + LENGTH / 2, CenterY - WIDTH / 2, scale), Graph.ToPx(CenterX - LENGTH / 2, CenterY + WIDTH / 2, scale), ]; _topLine?.Points = [ Graph.ToPx(CenterX - LENGTH / 4, CenterY - WIDTH / 2, scale), Graph.ToPx(CenterX, CenterY - WIDTH / 4, scale), Graph.ToPx(CenterX + LENGTH / 4, CenterY - WIDTH / 2, scale), ]; _bottomLine?.Points = [ Graph.ToPx(CenterX - LENGTH / 4, CenterY + WIDTH / 2, scale), Graph.ToPx(CenterX, CenterY + WIDTH / 4, scale), Graph.ToPx(CenterX + LENGTH / 4, CenterY + WIDTH / 2, scale), ]; } _triangles?.StrokeThickness = border; _topLine?.StrokeThickness = border; _bottomLine?.StrokeThickness = border; _text?.Width = 40; _text?.Height = 16; _text?.FontSize = 12; _text?.TextAlignment = Orientation == 0 ? TextAlignment.Right : Orientation == 2 ? TextAlignment.Left : TextAlignment.Center; if (Orientation == 0) { _text?.SetValue(Canvas.LeftProperty, (CenterX - WIDTH / 1.5) * scale - 40); _text?.SetValue(Canvas.TopProperty, CenterY * scale - 8); } else if (Orientation == 2) { _text?.SetValue(Canvas.LeftProperty, (CenterX + WIDTH / 1.5) * scale); _text?.SetValue(Canvas.TopProperty, CenterY * scale - 8 ); } else if (Orientation == 1) { _text?.SetValue(Canvas.LeftProperty, CenterX * scale - 20); _text?.SetValue(Canvas.TopProperty, (CenterY - WIDTH / 2) * scale - 16); } else { _text?.SetValue(Canvas.LeftProperty, CenterX * scale - 20); _text?.SetValue(Canvas.TopProperty, (CenterY + WIDTH / 2) * scale); } } public bool IsInside(double x, double y) { if (Orientation == 0 || Orientation == 2) { return Math.Abs(x - CenterX) <= WIDTH / 2 && Math.Abs(y - CenterY) <= LENGTH / 2; } else { return Math.Abs(x - CenterX) <= LENGTH / 2 && Math.Abs(y - CenterY) <= WIDTH / 2; } } public abstract void Update(bool isHovering, bool isPressed); } }