using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace PamhagenSysCtrl.Helpers.Pipeline { public class Pump : INode { public const double DIAMETER = 4.8; public double CenterX { get; set; } public double CenterY { get; set; } public string Label { get; set; } public ISet Inputs { get; init; } public ISet Outputs { get; init; } public Brush? Highlight { get; set; } public bool IsActive => State == MotorState.Forward || State == MotorState.Backward; public MotorState State => CallbackState(); public bool HasClearance => CallbackClearance(); public bool IsSelected => CallbackSelected(this); protected Func CallbackState; protected Func CallbackClearance; protected Func CallbackSelected; private Ellipse? _circle; private Polygon? _triangle; private TextBlock? _text; public Pump(string label, double x, double y, Func cbState, Func cbClearance, Func cbSelected) { CenterX = x; CenterY = y; Label = label; CallbackState = cbState; CallbackClearance = cbClearance; CallbackSelected = cbSelected; Inputs = new HashSet(); Outputs = new HashSet(); } public void Draw(Canvas canvas) { _circle = new Ellipse() { Fill = Brushes.WhiteSmoke, Stroke = Brushes.Black, }; _triangle = new Polygon() { Fill = Brushes.Transparent, Stroke = Brushes.Black, }; _text = new() { Text = Label, TextAlignment = TextAlignment.Left, VerticalAlignment = VerticalAlignment.Center, }; canvas.Children.Add(_circle); canvas.Children.Add(_triangle); canvas.Children.Add(_text); } public void Scale(double scale) { var border = Graph.ToBorder(scale); _circle?.StrokeThickness = border; Graph.SetCenter(_circle, CenterX, CenterY, DIAMETER, DIAMETER, scale); var dx = Math.Cos(Math.PI / 6) * (DIAMETER / 2); var dy = Math.Sin(Math.PI / 6) * (DIAMETER / 2); _triangle?.Points = [ Graph.ToPx(CenterX - dx, CenterY - dy, scale, dxpx: border, dypx: border / 2, round: false), Graph.ToPx(CenterX + dx, CenterY - dy, scale, dxpx: -border, dypx: border / 2, round: false), Graph.ToPx(CenterX, CenterY + DIAMETER / 2, scale, dypx: -border, round: false), ]; _triangle?.StrokeThickness = border; _text?.FontSize = 14; _text?.SetValue(Canvas.LeftProperty, (CenterX + DIAMETER / 2) * scale + 2); _text?.SetValue(Canvas.TopProperty, CenterY * scale - 10); } public bool IsInside(double x, double y) { return Math.Sqrt(Math.Pow(CenterX - x, 2) + Math.Pow(CenterY - y, 2)) <= DIAMETER / 2; } public void Update(bool isHovering, bool isPresed) { if (App.Plant?.ManualControlMode ?? false) { _circle?.Fill = Highlight ?? ( IsActive && isHovering ? PamhagenBrushes.Red : IsActive ? PamhagenBrushes.Green : HasClearance && isHovering ? PamhagenBrushes.Green : HasClearance ? PamhagenBrushes.Yellow : PamhagenBrushes.Red); } else { _circle?.Fill = Highlight ?? ( IsActive && isHovering ? PamhagenBrushes.Red : IsActive ? PamhagenBrushes.Green : HasClearance && IsSelected && isHovering ? PamhagenBrushes.Green : HasClearance && IsSelected ? PamhagenBrushes.Yellow : IsSelected ? PamhagenBrushes.Red : isHovering ? Brushes.LightGray : Brushes.WhiteSmoke); } } } }