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; using CtrEditor.FuncionesBase; 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 Guías Unión"; } private string nombre = NombreClase(); [property: Category("Identificación")] [property: Description("Nombre identificativo del objeto")] [property: Name("Nombre")] public override string Nombre { get => nombre; set => SetProperty(ref nombre, value); } [ObservableProperty] [property: Category("Apariencia")] [property: Description("Color del transporte")] [property: Name("Color")] Color color; [ObservableProperty] [property: Category("Enlace PLC")] [property: Description("Tag para activar enlace con motor")] [property: Name("Tag Activación Motor")] string tag_ReleActivatedMotor; [ObservableProperty] [property: Category("Enlace PLC")] [property: Description("Motor A enlazado")] [property: Name("Motor A")] [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: Category("Enlace PLC")] [property: Description("Motor B enlazado")] [property: Name("Motor B")] [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] [property: Category("Simulación")] [property: Description("Velocidad actual del motor A")] [property: Name("Velocidad A")] public float velocidadActualA; partial void OnVelocidadActualAChanged(float value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteA; SetSpeed(transporte); } } [ObservableProperty] [property: Category("Configuración")] [property: Description("Invertir dirección del motor A")] [property: Name("Invertir A")] bool invertirDireccionA; partial void OnInvertirDireccionAChanged(bool value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteA; SetSpeed(transporte); ActualizarStoryboards(transporte); } } [ObservableProperty] [property: Category("Simulación")] [property: Description("Velocidad actual del motor B")] [property: Name("Velocidad B")] public float velocidadActualB; partial void OnVelocidadActualBChanged(float value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteB; SetSpeed(transporte); } } [ObservableProperty] [property: Category("Configuración")] [property: Description("Invertir dirección del motor B")] [property: Name("Invertir B")] bool invertirDireccionB; partial void OnInvertirDireccionBChanged(bool value) { if (_visualRepresentation is ucTransporteGuiasUnion uc) { var transporte = uc.TransporteB; SetSpeed(transporte); ActualizarStoryboards(transporte); } } public override void OnResize(float Delta_Width, float Delta_Height) { AnchoRecto += Delta_Width; } [ObservableProperty] [property: Category("Configuración")] [property: Description("Ancho de las secciones rectas")] [property: Name("Ancho Recto")] public float anchoRecto; [ObservableProperty] [property: Category("Configuración")] [property: Description("Ancho de la sección central")] [property: Name("Ancho Central")] public float anchoCentral; partial void OnAnchoRectoChanged(float value) { AnchoTransporte_oculto = anchoRecto + anchoCentral; } partial void OnAnchoCentralChanged(float value) { AnchoTransporte_oculto = anchoRecto + anchoCentral; } [ObservableProperty] [property: Category("Información")] [property: Description("Ancho total del transporte calculado")] [property: Name("Ancho Total")] public float anchoTransporte_oculto; [ObservableProperty] [property: Category("Configuración")] [property: Description("Coeficiente de fricción")] [property: Name("Coeficiente Fricción")] public float frictionCoefficient; [ObservableProperty] [property: Category("Configuración")] [property: Description("Velocidad máxima a 50Hz")] [property: Name("Velocidad Max 50Hz")] public float velMax50hz; [ObservableProperty] [property: Category("Configuración")] [property: Description("Tiempo de rampa")] [property: Name("Tiempo Rampa")] public float tiempoRampa; [ObservableProperty] [property: Category("Información")] [property: Description("Estado de marcha")] [property: Name("En Marcha")] public bool esMarcha; [ObservableProperty] [property: Category("Configuración")] [property: Description("Distancia entre elementos")] [property: Name("Distancia")] private float distance; [ObservableProperty] [property: Category("Configuración")] [property: Description("Alto de las guías")] [property: Name("Alto Guía")] 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 override void OnMoveResizeRotate() { ActualizarGeometrias(); } 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(); Tag_ReleActivatedMotor = "1"; } 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) if (LeerBitTag(Tag_ReleActivatedMotor)) VelocidadActualA = motor.Velocidad; else VelocidadActualA = 0; } if (_osMotorB != null) { if (_osMotorB is osVMmotorSim motor) if (LeerBitTag(Tag_ReleActivatedMotor)) VelocidadActualB = motor.Velocidad; else VelocidadActualB = 0; } } 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 int zIndex_fromFrames { 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 Highlight(bool State) { } public ZIndexEnum ZIndex_Base() { return ZIndexEnum.Estaticos; } } }