diff --git a/Convertidores/Converters.cs b/Convertidores/Converters.cs index e711305..46ff7a0 100644 --- a/Convertidores/Converters.cs +++ b/Convertidores/Converters.cs @@ -10,6 +10,22 @@ using System.Windows.Media; namespace CtrEditor.Convertidores { + public class HalfWidthConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is double width) + { + return (width / 2.0) - (double.Parse(parameter.ToString()) / 2.0); + } + return 0; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } public class WidthPercentageConverter : IValueConverter { @@ -107,24 +123,55 @@ namespace CtrEditor.Convertidores { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - float meters = (float)value; - float factor = 1; - if (parameter != null) - if (parameter.ToString() == "0.5") factor = 0.5f; - else if (parameter.ToString() == "-0.5") factor = -0.5f; - else if (parameter.ToString() == "1.5") factor = 1.5f; + if (value == null) return 0; // Aseguramos que el valor no sea nulo + // Convertimos el valor de entrada en un número flotante + float meters = System.Convert.ToSingle(value); + + float factor = 1; // Valor por defecto del factor + + // Si el parámetro no es nulo, intentamos convertirlo a float + if (parameter != null) + { + string paramStr = parameter.ToString(); + + // Normalizamos el parámetro para asegurar que el punto sea el separador decimal + paramStr = paramStr.Replace(',', '.'); + + // Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal + if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor)) + { + factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa + } + } + + // Calculamos los píxeles llamando a la instancia de PixelToMeter y multiplicamos por el factor return PixelToMeter.Instance.calc.MetersToPixels(meters) * factor; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - float pixels = (float)value; - float factor = 1; + if (value == null) return 0; // Aseguramos que el valor no sea nulo + + // Convertimos el valor de entrada en un número flotante + float pixels = System.Convert.ToSingle(value); + + float factor = 1; // Valor por defecto del factor + + // Si el parámetro no es nulo, intentamos convertirlo a float if (parameter != null) - if (parameter.ToString() == "0.5") factor = 0.5f; - else if (parameter.ToString() == "-0.5") factor = -0.5f; - else if (parameter.ToString() == "1.5") factor = 1.5f; + { + string paramStr = parameter.ToString(); + + // Normalizamos el parámetro para asegurar que el punto sea el separador decimal + paramStr = paramStr.Replace(',', '.'); + + // Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal + if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor)) + { + factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa + } + } return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor; } diff --git a/CtrEditor.csproj b/CtrEditor.csproj index 44fca82..014de43 100644 --- a/CtrEditor.csproj +++ b/CtrEditor.csproj @@ -17,8 +17,10 @@ + + @@ -59,8 +61,10 @@ + + diff --git a/Icons/borrar.png b/Icons/borrar.png new file mode 100644 index 0000000..38557a7 Binary files /dev/null and b/Icons/borrar.png differ diff --git a/Icons/fotocelula.png b/Icons/fotocelula.png new file mode 100644 index 0000000..7669a16 Binary files /dev/null and b/Icons/fotocelula.png differ diff --git a/MainViewModel.cs b/MainViewModel.cs index 3ed9ca7..14483b9 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -56,6 +56,8 @@ namespace CtrEditor public ICommand TBConnectPLCCommand { get; } public ICommand TBDisconnectPLCCommand { get; } + public ICommand TBEliminarUserControlCommand { get; } + public ICommand OpenWorkDirectoryCommand { get; } // Evento que se dispara cuando se selecciona una nueva imagen @@ -66,6 +68,7 @@ namespace CtrEditor private bool isSimulationRunning; private bool isConnected; + private bool habilitarEliminarUserControl; public PLCViewModel plcViewModelData; private osBase _selectedItemOsList; private string _selectedImage = null; @@ -173,6 +176,11 @@ namespace CtrEditor { if (_selectedItemOsList != value) { + if (value != null) + habilitarEliminarUserControl = true; + else + habilitarEliminarUserControl = false; + _selectedItemOsList = value; OnPropertyChanged(nameof(SelectedItemOsList)); } @@ -236,6 +244,8 @@ namespace CtrEditor TBConnectPLCCommand = new RelayCommand(ConnectPLC, () => !IsConnected); TBDisconnectPLCCommand = new RelayCommand(DisconnectPLC, () => IsConnected); + TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl); + stopwatch_PLCRefresh = new Stopwatch(); stopwatch_SimRefresh = new Stopwatch(); } @@ -309,6 +319,12 @@ namespace CtrEditor } } + private void EliminarUserControl() + { + if (SelectedItemOsList is osBase objEliminar) + RemoverObjetoSimulable(objEliminar); + } + private void InitializeTipoSimulableList() { var baseType = typeof(osBase); diff --git a/MainWindow.xaml b/MainWindow.xaml index b65635a..74aa1f3 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -6,7 +6,7 @@ xmlns:Siemens="clr-namespace:CtrEditor.Siemens" xmlns:convert="clr-namespace:CtrEditor.Convertidores" xmlns:ObjetosSim="clr-namespace:CtrEditor.ObjetosSim" x:Class="CtrEditor.MainWindow" - Height="900" Width="1600" + Height="900" Width="1600" WindowState="Maximized" ResizeMode="CanResize" Title="{Binding directorioTrabajo}"> @@ -142,6 +142,7 @@ + @@ -167,6 +168,18 @@ + + + + + + + diff --git a/ObjetosSim/UserControls/ucPhotocell.xaml b/ObjetosSim/UserControls/ucPhotocell.xaml new file mode 100644 index 0000000..5e1854c --- /dev/null +++ b/ObjetosSim/UserControls/ucPhotocell.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ObjetosSim/UserControls/ucPhotocell.xaml.cs b/ObjetosSim/UserControls/ucPhotocell.xaml.cs new file mode 100644 index 0000000..af4c154 --- /dev/null +++ b/ObjetosSim/UserControls/ucPhotocell.xaml.cs @@ -0,0 +1,208 @@ +using CtrEditor.Convertidores; +using CtrEditor.Siemens; +using CtrEditor.Simulacion; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace CtrEditor.ObjetosSim.UserControls +{ + /// + /// Interaction logic for ucPhotocell.xaml + /// + public class osPhotocell : osBase + { + private float _ancho; + private float _altoPhotocell; + private float _left; + private float _top; + private float _angulo; + private string _nombre = "Photocell"; + private bool _luzCortada; + + private simBarrera Simulation_Photocell; + + public bool LuzCortada + { + get => _luzCortada; + set + { + if (_luzCortada != value) + { + _luzCortada = value; + OnPropertyChanged(nameof(LuzCortada)); + } + } + } + + public override float Left + { + get => _left; + set + { + _left = value; + ActualizarGeometrias(); + CanvasSetLeftinMeter(value); + OnPropertyChanged(nameof(Left)); + } + } + public override float Top + { + get => _top; + set + { + _top = value; + ActualizarGeometrias(); + CanvasSetTopinMeter(value); + OnPropertyChanged(nameof(Top)); + } + } + + public float Ancho + { + get => _ancho; + set + { + _ancho = value; + ActualizarGeometrias(); + OnPropertyChanged(nameof(Ancho)); + } + } + + public float Alto + { + get => _altoPhotocell; + set + { + _altoPhotocell = value; + ActualizarGeometrias(); + OnPropertyChanged(nameof(Alto)); + } + } + + public float Angulo + { + get => _angulo; + set + { + _angulo = value; + ActualizarGeometrias(); + OnPropertyChanged(nameof(Angulo)); + } + } + + public override string Nombre + { + get => _nombre; + set + { + if (_nombre != value) + { + _nombre = value; + OnPropertyChanged(nameof(Nombre)); + } + } + } + + private void ActualizarGeometrias() + { + if (_visualRepresentation is ucPhotocell uc) + UpdateRectangle(Simulation_Photocell, uc.Photocell, Alto, Ancho, Angulo); + } + + public osPhotocell() + { + Ancho = 1; + Alto = 0.03f; + } + + public override void UpdateGeometryStart() + { + // Se llama antes de la simulacion + ActualizarGeometrias(); + } + public override void UpdateControl(int elapsedMilliseconds) + { + LuzCortada = Simulation_Photocell.LuzCortada; + } + public override void UpdateGeometryStep() + { + Simulation_Photocell.LuzCortada = false; + } + public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { } + public override void ucLoaded() + { + // El UserControl ya se ha cargado y podemos obtener las coordenadas para + // crear el objeto de simulacion + ActualizarLeftTop(); + + if (_visualRepresentation is ucPhotocell uc) + Simulation_Photocell = AddBarrera(simulationManager, uc.Photocell, Alto, Ancho, Angulo); + } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + simulationManager.Remove(Simulation_Photocell); + } + + + } + + public partial class ucPhotocell : UserControl, IDataContainer + { + public osBase? Datos { get; set; } + + public ucPhotocell() + { + 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 (width == 0) return; + if (Datos is osPhotocell datos) + datos.Ancho = 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 osPhotocell datos) + datos.Angulo = Angle; + } + public void Highlight(bool State) { } + public int ZIndex() + { + return 1; + } + + } +} diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 7952e82..823873e 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -231,11 +231,22 @@ namespace CtrEditor.ObjetosSim simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } + public void UpdateRectangle(simBarrera simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) + { + if (simRect != null) + simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); + } + public simTransporte AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } + public simBarrera AddBarrera(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) + { + return simulationManager.AddBarrera(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); + } + public void UpdateOrCreateLine(simGuia simGuia, System.Windows.Shapes.Rectangle wpfRect) { if (simGuia != null) diff --git a/Simulacion/FPhysics.cs b/Simulacion/FPhysics.cs index 61af798..e9af1a8 100644 --- a/Simulacion/FPhysics.cs +++ b/Simulacion/FPhysics.cs @@ -223,7 +223,7 @@ namespace CtrEditor.Simulacion // Restablecer manejador de eventos de colisión Body.OnCollision += HandleCollision; - Body.OnSeparation += HandleOnSeparation; + //Body.OnSeparation += HandleOnSeparation; Body.UserData = this; // Importante para la identificación durante la colisión @@ -295,8 +295,7 @@ namespace CtrEditor.Simulacion private void HandleOnSeparation(Fixture fixtureA, Fixture fixtureB) { - if (fixtureB.Body.UserData is simBarrera Sensor) - Sensor.LuzCortada = false; + } private void ApplyConveyorEffect(simTransporte conveyor, Fixture circleFixture, float porcentajeCompartido) @@ -365,9 +364,9 @@ namespace CtrEditor.Simulacion return rectangle; } - public simTransporte AddBarrera(float width, float height, Vector2 position, float angle) + public simBarrera AddBarrera(float width, float height, Vector2 position, float angle) { - simTransporte rectangle = new simTransporte(world, width, height, position, angle); + simBarrera rectangle = new simBarrera(world, width, height, position, angle); Cuerpos.Add(rectangle); return rectangle; }