using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace PamhagenSysCtrl.Helpers.Pipeline { public class Switcher : INode { public const double WIDTH = 100; public const double HEIGHT = 50; 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; } private Line? _main; private Line? _shadow; private RotateTransform? _mainTransform; private RotateTransform? _shadowTransform; protected Func CallbackIsPosition; protected Func CallbackWantPosition; public Switcher(string label, double x, double y, Func cbIsPosition, Func cbWantPosition) { CenterX = x; CenterY = y; Label = label; CallbackIsPosition = cbIsPosition; CallbackWantPosition = cbWantPosition; Inputs = new HashSet(); Outputs = new HashSet(); } public void Draw(Canvas canvas) { _mainTransform = new RotateTransform(0, CenterX, CenterY); _shadowTransform = new RotateTransform(0, CenterX, CenterY); _main = new Line() { X1 = CenterX - WIDTH / 2, Y1 = CenterY, X2 = CenterX + WIDTH / 2, Y2 = CenterY, StrokeThickness = 5, Stroke = Brushes.Black, StrokeStartLineCap = PenLineCap.Square, StrokeEndLineCap = PenLineCap.Square, RenderTransform = _mainTransform, }; _shadow = new Line() { X1 = CenterX - WIDTH / 2, Y1 = CenterY, X2 = CenterX + WIDTH / 2, Y2 = CenterY, StrokeThickness = 5, Stroke = Brushes.DarkGray, StrokeStartLineCap = PenLineCap.Square, StrokeEndLineCap = PenLineCap.Square, RenderTransform = _shadowTransform, }; canvas.Children.Add(_shadow); canvas.Children.Add(_main); } 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) { var isPos = CallbackIsPosition(); var wantPos = CallbackWantPosition(); if (isHovering && wantPos == isPos) wantPos = wantPos == 1 ? 2 : 1; var target1 = isPos == 0 ? 0 : isPos == 1 ? 15 : -15; var target2 = wantPos == 0 ? 0 : wantPos == 1 ? 15 : -15; _mainTransform?.BeginAnimation( RotateTransform.AngleProperty, new DoubleAnimation { From = _mainTransform.Angle, To = target1, Duration = TimeSpan.FromSeconds(Math.Abs(_mainTransform.Angle - target1) / 120.0) }); _shadowTransform?.BeginAnimation( RotateTransform.AngleProperty, new DoubleAnimation { From = _shadowTransform.Angle, To = target2, Duration = TimeSpan.FromSeconds(Math.Abs(_shadowTransform.Angle - target2) / 120.0) }); } } }