using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace PamhagenSysCtrl.Helpers.Pipeline { class EntryTrough : INode { public const double WIDTH = 30; public const double HEIGHT = 12; 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 bool IsActive => CallbackActive(); public bool IsAnimationActive { get => _animationActive; set { _auger?.IsAnimationActive = value; if (value && !_animationActive) { _doorTransform?.BeginAnimation( RotateTransform.AngleProperty, new DoubleAnimation { From = _doorTransform.Angle, To = 60, Duration = TimeSpan.FromSeconds(Math.Abs(_doorTransform.Angle - 60) / 60.0) }); } else if (!value && _animationActive) { _doorTransform?.BeginAnimation( RotateTransform.AngleProperty, new DoubleAnimation { From = _doorTransform.Angle, To = 0, Duration = TimeSpan.FromSeconds(Math.Abs(_doorTransform.Angle - 0) / 60.0) }); } _animationActive = value; } } public double Top => CenterY - HEIGHT / 2; public double Right => CenterX + WIDTH / 2; public double Bottom => CenterY + HEIGHT / 2; public double Left => CenterX - WIDTH / 2; protected Func CallbackActive; private bool _animationActive; private Polygon? _inner; private Polygon? _outer; private TextBlock? _text; private Auger? _auger; private Line? _door; private RotateTransform? _doorTransform; public EntryTrough(string label, double x, double y, Func cbActive) { CenterX = x; CenterY = y; Label = label; CallbackActive = cbActive; Inputs = new HashSet(); Outputs = new HashSet(); } public void Draw(Canvas canvas) { _outer = new Polygon() { Fill = Brushes.Black, }; _inner = new Polygon() { Fill = Brushes.WhiteSmoke, }; _doorTransform = new RotateTransform(0); _door = new Line() { Stroke = Brushes.Black, RenderTransform = _doorTransform, }; _text = new() { Text = Label, TextAlignment = TextAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }; canvas.Children.Add(_outer); canvas.Children.Add(_inner); canvas.Children.Add(_text); canvas.Children.Add(_door); _auger = new(CenterX - 2.2, CenterY + HEIGHT / 2 - 1.8, WIDTH - 5, 2.4); _auger.Draw(canvas); } public void Scale(double scale) { var border = Graph.ToBorder(scale); _outer?.Points = [ new(Left * scale, Top * scale), new(Right * scale, Top * scale), new((Right - 4) * scale, Bottom * scale), new(Left * scale, Bottom * scale), new(Left * scale, (Bottom - 4) * scale), new((Left + 2.5) * scale, (Bottom - 4) * scale), ]; _inner?.Points = [ new(Left * scale + border, Top * scale), new(Right * scale - border, Top * scale), new((Right - 4) * scale - border, Bottom * scale - border), new(Left * scale, Bottom * scale - border), new(Left * scale, (Bottom - 3.6) * scale), new((Left + 3.1) * scale, (Bottom - 3.6) * scale), ]; _door?.X1 = Left * scale; _door?.Y1 = (Bottom - 4.8) * scale; _door?.X2 = Left * scale; _door?.Y2 = (Bottom + 0.8) * scale; _door?.StrokeThickness = border * 2; _doorTransform?.CenterX = Left * scale; _doorTransform?.CenterY = (Bottom - 4.8) * scale; _text?.FontSize = 12; _text?.Width = WIDTH * scale; _text?.SetValue(Canvas.LeftProperty, (CenterX - WIDTH / 2) * scale); _text?.SetValue(Canvas.TopProperty, (CenterY - 1.5) * scale - 8); _auger?.Scale(scale); } public bool IsInside(double x, double y) { return Math.Abs(x - CenterX) <= WIDTH / 2 && Math.Abs(y - CenterY) <= HEIGHT / 2; } public void Update(bool isHovering, bool isPressed) { IsAnimationActive = IsActive; _inner?.Fill = IsAnimationActive && isHovering && isPressed ? PamhagenBrushes.Red : IsAnimationActive && isHovering ? PamhagenBrushes.Red : !IsAnimationActive && isHovering && isPressed ? PamhagenBrushes.Green : !IsAnimationActive && isHovering ? PamhagenBrushes.Green : IsAnimationActive ? PamhagenBrushes.Green : Brushes.WhiteSmoke; } } }