using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using CommunityToolkit.Mvvm.ComponentModel; using CtrEditor.Siemens; using CtrEditor.Simulacion; using SkiaSharp; namespace CtrEditor.ObjetosSim { /// /// Interaction logic for ucTransporteGuiasUnion.xaml /// public partial class osTransporteGuiasUnion : osBase, IosBase { private osBase _osMotorA = null; private osBase _osMotorB = null; Dictionary SimGeometriaT; Dictionary SimGeometriaG; Dictionary Storyboards; Dictionary TransportsDirection; Dictionary TransportsVelocidad; public static string NombreClase() { return "Transporte Guias Union"; } private string nombre = NombreClase(); public override string Nombre { get => nombre; set => SetProperty(ref nombre, value); } [ObservableProperty] public string motorA; partial void OnMotorAChanged(string value) { _osMotorA = ObtenerLink(MotorA, typeof(osVMmotorSim)); } [ObservableProperty] public float velocidadActualA; partial void OnVelocidadActualAChanged(float value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteA; SetSpeed(transporte); } } [ObservableProperty] bool invertirDireccionA; partial void OnInvertirDireccionAChanged(bool value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteA; SetSpeed(transporte); ActualizarStoryboards(transporte); } } [ObservableProperty] public string motorB; partial void OnMotorBChanged(string value) { _osMotorB = ObtenerLink(MotorB, typeof(osVMmotorSim)); } [ObservableProperty] public float velocidadActualB; partial void OnVelocidadActualBChanged(float value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteB; SetSpeed(transporte); } } [ObservableProperty] bool invertirDireccionB; partial void OnInvertirDireccionBChanged(bool value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteB; SetSpeed(transporte); ActualizarStoryboards(transporte); } } [ObservableProperty] public float anchoRecto; [ObservableProperty] public float anchoCentral; partial void OnAnchoRectoChanged(float value) { AnchoTransporte_oculto = anchoRecto + anchoCentral; } partial void OnAnchoCentralChanged(float value) { AnchoTransporte_oculto = anchoRecto + anchoCentral; } [ObservableProperty] public float anchoTransporte_oculto; [ObservableProperty] public float alto; partial void OnAltoChanged(float value) { // ActualizarGeometrias(); } [ObservableProperty] public float angulo; [ObservableProperty] public float frictionCoefficient; [ObservableProperty] public float velMax50hz; [ObservableProperty] public float tiempoRampa; [ObservableProperty] public bool esMarcha; [ObservableProperty] private float distance; [ObservableProperty] private float altoGuia; void ActualizarStoryboards(Rectangle transporte) { if (!Storyboards.Keys.Contains(transporte)) return; var direccion = TransportsDirection[transporte].Value; var velocidad = TransportsVelocidad[transporte].Value; Storyboards[transporte] = CrearAnimacionMultiStoryBoardTrasnporte(Storyboards[transporte], transporte, direccion); ActualizarAnimacionMultiStoryBoardTransporte(Storyboards[transporte], velocidad); } void SetSpeed(Rectangle transporte) { if (!Storyboards.Keys.Contains(transporte)) return; var invertirDireccion = TransportsDirection[transporte].Value; var velocidad = TransportsVelocidad[transporte].Value; if (invertirDireccion) SimGeometriaT[transporte]?.SetSpeed(-velocidad); else SimGeometriaT[transporte]?.SetSpeed(velocidad); ActualizarAnimacionMultiStoryBoardTransporte(Storyboards[transporte], velocidad); } private void ActualizarGeometrias() { if (_visualRepresentation is ucTransporteGuiasUnion uc) { foreach (var transporte in SimGeometriaT) { UpdateRectangle(transporte.Value, transporte.Key, Alto, AnchoTransporte_oculto, Angulo); ActualizarStoryboards(transporte.Key); SetSpeed(transporte.Key); } foreach (var l in SimGeometriaG) UpdateOrCreateLine(l.Value, l.Key); } } public osTransporteGuiasUnion() { AnchoRecto = 0.5f; AnchoCentral = 0.5f; Alto = 0.10f; AltoGuia = 0.03f; Distance = 0.02f; SimGeometriaT = new Dictionary(); SimGeometriaG = new Dictionary(); Storyboards = new Dictionary(); TransportsDirection = new Dictionary(); TransportsVelocidad = new Dictionary(); } public override void UpdateGeometryStart() { // Se llama antes de la simulacion ActualizarGeometrias(); } public override void SimulationStop() { // Se llama al detener la simulacion if (_visualRepresentation is ucTransporteGuiasUnion uc) { SetSpeed(uc.TransporteB); SetSpeed(uc.TransporteA); } } public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { if (_osMotorA != null) { if (_osMotorA is osVMmotorSim motor) VelocidadActualA = motor.Velocidad; } else if (MotorA.Length > 0) _osMotorA = ObtenerLink(MotorA, typeof(osVMmotorSim)); if (_osMotorB != null) { if (_osMotorB is osVMmotorSim motor) VelocidadActualB = motor.Velocidad; } else if (MotorB.Length > 0) _osMotorB = ObtenerLink(MotorB, typeof(osVMmotorSim)); } public override void ucLoaded() { // El UserControl ya se ha cargado y podemos obtener las coordenadas para // crear el objeto de simulacion ActualizarLeftTop(); // El UserControl ya se ha cargado y podemos obtener las coordenadas para // crear el objeto de simulacion if (_visualRepresentation is ucTransporteGuiasUnion uc) { foreach (var child in uc.Canvas.Children) if (child is Rectangle rect) if (rect.Name.StartsWith("Transporte")) { SimGeometriaT.Add(rect,AddRectangle(simulationManager, rect, Alto, AnchoTransporte_oculto, Angulo)); Storyboards.Add(rect,CrearAnimacionMultiStoryBoardTrasnporte(rect,false)); } foreach (var child in uc.GuiaSuperior.Canvas.Children) if (child is Rectangle rect) SimGeometriaG.Add(rect, AddLine(simulationManager, rect)); foreach (var child in uc.GuiaInferior.Canvas.Children) if (child is Rectangle rect) SimGeometriaG.Add(rect, AddLine(simulationManager, rect)); TransportsDirection.Add(uc.TransporteA, new BoolReference(() => InvertirDireccionA, value => InvertirDireccionA = value)); TransportsDirection.Add(uc.TransporteB, new BoolReference(() => InvertirDireccionB, value => InvertirDireccionB = value)); TransportsVelocidad.Add(uc.TransporteA, new FloatReference(() => VelocidadActualA, value => VelocidadActualA = value)); TransportsVelocidad.Add(uc.TransporteB, new FloatReference(() => VelocidadActualB, value => VelocidadActualB = value)); } OnMotorAChanged(MotorA); } public override void ucUnLoaded() { // El UserControl se esta eliminando // eliminar el objeto de simulacion foreach (var s in SimGeometriaT) simulationManager.Remove(s.Value); foreach (var s in SimGeometriaG) simulationManager.Remove(s.Value); } } public class BoolReference { private Func getter; private Action setter; public BoolReference(Func getter, Action setter) { this.getter = getter; this.setter = setter; } public bool Value { get => getter(); set => setter(value); } } public class FloatReference { private Func getter; private Action setter; public FloatReference(Func getter, Action setter) { this.getter = getter; this.setter = setter; } public float Value { get => getter(); set => setter(value); } } public partial class ucTransporteGuiasUnion : UserControl, IDataContainer { public osBase? Datos { get; set; } public ucTransporteGuiasUnion() { InitializeComponent(); this.Loaded += OnLoaded; this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } private void OnUnloaded(object sender, RoutedEventArgs e) { Datos?.ucUnLoaded(); } public void Resize(float width, float height) { if (Datos is osTransporteGuiasUnion datos) datos.AnchoRecto = PixelToMeter.Instance.calc.PixelsToMeters(width); } public void Move(float LeftPixels, float TopPixels) { if (Datos != null) { Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels); Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels); } } public void Rotate(float Angle) { if (Datos != null) if (Datos is osTransporteGuiasUnion datos) datos.Angulo = Angle; } public void Highlight(bool State) { } public int ZIndex() { return 1; } } }