using System.ComponentModel; 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 LibS7Adv; using CtrEditor.Simulacion; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; 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] Color color; [ObservableProperty] [property: Description("Link to Motor A")] [property: Category("PLC link:")] [property: ItemsSource(typeof(osBaseItemsSource))] string id_MotorA; partial void OnId_MotorAChanged(string value) { if (_osMotorA != null) _osMotorA.PropertyChanged -= OnMotorPropertyChangedA; if (_mainViewModel != null && value != null && value.Length > 0) { _osMotorA = (osVMmotorSim)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => (s is osVMmotorSim && s.Nombre == value), null); if (_osMotorA != null) _osMotorA.PropertyChanged += OnMotorPropertyChangedA; } } private void OnMotorPropertyChangedA(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(osVMmotorSim.Nombre)) { Id_MotorA = ((osVMmotorSim)sender).Nombre; } } [ObservableProperty] [property: Description("Link to Motor B")] [property: Category("PLC link:")] [property: ItemsSource(typeof(osBaseItemsSource))] string id_MotorB; partial void OnId_MotorBChanged(string value) { if (_osMotorB != null) _osMotorB.PropertyChanged -= OnMotorPropertyChangedB; if (_mainViewModel != null && value != null && value.Length > 0) { _osMotorB = (osVMmotorSim)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => (s is osVMmotorSim && s.Nombre == value), null); if (_osMotorB != null) _osMotorB.PropertyChanged += OnMotorPropertyChangedB; } } private void OnMotorPropertyChangedB(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(osVMmotorSim.Nombre)) { Id_MotorB = ((osVMmotorSim)sender).Nombre; } } [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 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(PLCViewModel plc, int elapsedMilliseconds) { if (_osMotorA != null) { if (_osMotorA is osVMmotorSim motor) VelocidadActualA = motor.Velocidad; } if (_osMotorB != null) { if (_osMotorB is osVMmotorSim motor) VelocidadActualB = motor.Velocidad; } } public override void ucLoaded() { // El UserControl ya se ha cargado y podemos obtener las coordenadas para // crear el objeto de simulacion base.ucLoaded(); // 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)); } OnId_MotorAChanged(Id_MotorA); // Link Id_Motor = Motor OnId_MotorBChanged(Id_MotorB); // Link Id_Motor = Motor } 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; } } }