From 334b1a2fd8c0937d0a12e17297bb2857d57719f5 Mon Sep 17 00:00:00 2001 From: Miguel Date: Mon, 20 May 2024 14:05:34 +0200 Subject: [PATCH] Creado boton Duplicar --- CtrEditor.csproj | 2 + Icons/duplicate.png | Bin 0 -> 7037 bytes MainViewModel.cs | 80 ++++++++++++++++------- MainWindow.xaml | 10 ++- ObjetosSim/UserControls/ucFiller.xaml.cs | 32 +++++++-- ObjetosSim/osBase.cs | 39 +++++++++++ 6 files changed, 132 insertions(+), 31 deletions(-) create mode 100644 Icons/duplicate.png diff --git a/CtrEditor.csproj b/CtrEditor.csproj index 014de43..acafe06 100644 --- a/CtrEditor.csproj +++ b/CtrEditor.csproj @@ -20,6 +20,7 @@ + @@ -64,6 +65,7 @@ + diff --git a/Icons/duplicate.png b/Icons/duplicate.png new file mode 100644 index 0000000000000000000000000000000000000000..51669f837bab9414055abf69b99f46b51970375b GIT binary patch literal 7037 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 IsConnected); TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl); + TBDuplicarUserControlCommand = new RelayCommand(DuplicarUserControl, () => habilitarEliminarUserControl); stopwatch_PLCRefresh = new Stopwatch(); stopwatch_SimRefresh = new Stopwatch(); @@ -320,6 +323,45 @@ namespace CtrEditor } } + private void DuplicarUserControl() + { + if (SelectedItemOsList is osBase objDuplicar) + { + StopSimulation(); + DisconnectPLC(); + + objDuplicar.SalvarDatosNoSerializables(); + + var settings = new JsonSerializerSettings + { + Formatting = Formatting.Indented, + NullValueHandling = NullValueHandling.Ignore, + TypeNameHandling = TypeNameHandling.All + }; + + try + { + // Serializar + var serializedData = JsonConvert.SerializeObject(objDuplicar, settings); + // Duplicar + var NuevoObjetoDuplicado = JsonConvert.DeserializeObject(serializedData, settings); + if (NuevoObjetoDuplicado != null) + { + NuevoObjetoDuplicado.Nombre += "_Duplicado"; + ObjetosSimulables.Add(NuevoObjetoDuplicado); + CrearUserControlDesdeObjetoSimulable(NuevoObjetoDuplicado); + } + } + catch + { + // Log error or handle it accordingly + } + finally { + objDuplicar.RestaurarDatosNoSerializables(); + } + } + } + private void EliminarUserControl() { if (SelectedItemOsList is osBase objEliminar) @@ -458,25 +500,21 @@ namespace CtrEditor if (_selectedImage != null) { StopSimulation(); - PLCViewModel.Disconnect(); + DisconnectPLC(); - // Crear copias temporales de las propiedades que serán anuladas - var tempVisualRepresentations = new Dictionary(); - var tempSimulationManagers = new Dictionary(); - var tempMainViewModels = new Dictionary(); + // Ruta del archivo a ser guardado + var path = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"); + + // Verificar si el archivo ya existe y crear un respaldo + if (File.Exists(path)) + { + var backupPath = Path.ChangeExtension(path, ".bak"); + File.Copy(path, backupPath, true); // Copia el archivo existente a un nuevo archivo .bak, sobrescribiendo si es necesario + } foreach (var obj in ObjetosSimulables) - { // Guardar referencias temporales - tempVisualRepresentations[obj] = obj.VisualRepresentation; - tempSimulationManagers[obj] = obj.simulationManager; - tempMainViewModels[obj] = obj._mainViewModel; - - // Anular propiedades para la serialización - obj.VisualRepresentation = null; - obj.simulationManager = null; - obj._mainViewModel = null; - } + obj.SalvarDatosNoSerializables(); var settings = new JsonSerializerSettings { @@ -495,26 +533,20 @@ namespace CtrEditor // Serializar var serializedData = JsonConvert.SerializeObject(dataToSerialize, settings); - File.WriteAllText(datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"), serializedData); + File.WriteAllText(path, serializedData); // Escribir el nuevo archivo JSON // Restaurar las propiedades originales de los objetos foreach (var obj in ObjetosSimulables) - { - obj.VisualRepresentation = tempVisualRepresentations[obj]; - obj.simulationManager = tempSimulationManagers[obj]; - obj._mainViewModel = tempMainViewModels[obj]; - } + obj.RestaurarDatosNoSerializables(); } } - - public void LoadStateObjetosSimulables() { try { StopSimulation(); - PLCViewModel.Disconnect(); + DisconnectPLC(); ObjetosSimulables.Clear(); simulationManager.Clear(); if (_selectedImage != null) diff --git a/MainWindow.xaml b/MainWindow.xaml index 74aa1f3..1adaa0e 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -54,8 +54,8 @@ - - + + @@ -177,6 +177,12 @@ + diff --git a/ObjetosSim/UserControls/ucFiller.xaml.cs b/ObjetosSim/UserControls/ucFiller.xaml.cs index af5ef81..7ff7e0f 100644 --- a/ObjetosSim/UserControls/ucFiller.xaml.cs +++ b/ObjetosSim/UserControls/ucFiller.xaml.cs @@ -207,18 +207,40 @@ namespace CtrEditor.ObjetosSim { TiempoRestante = 3600 / (Botellas_hora * (Velocidad_actual_percentual / 100.0f)); - var UltimaBotellla = GetLastElement(Botellas); - if (UltimaBotellla == null || (UltimaBotellla != null && !(UltimaBotellla.Left == Left && UltimaBotellla.Top == Top))) + var X = Left + OffsetLeftSalida; + var Y = Top + OffsetTopSalida; + + var UltimaBotella = GetLastElement(Botellas); + if (UltimaBotella == null) { - var Botella = _mainViewModel.CrearObjetoSimulable(typeof(osBotella), Left + OffsetLeftSalida, Top + OffsetTopSalida); - Botella.AutoCreated = true; - Botellas.Add((osBotella)Botella); + // No hay botellas, se puede crear una nueva directamente + var nuevaBotella = _mainViewModel.CrearObjetoSimulable(typeof(osBotella), X, Y); + ((osBotella)nuevaBotella).Diametro = Diametro_botella; + nuevaBotella.AutoCreated = true; + Botellas.Add((osBotella)nuevaBotella); + } + else + { + // Calcular la distancia entre el centro de la última botella y la nueva posición + float distancia = (float)Math.Sqrt(Math.Pow(UltimaBotella.Left - X, 2) + Math.Pow(UltimaBotella.Top - Y, 2)); + float distanciaMinima = Diametro_botella / 2; // Asumiendo que el diámetro de la nueva botella es similar + + if (distancia > distanciaMinima) + { + var nuevaBotella = _mainViewModel.CrearObjetoSimulable(typeof(osBotella), X, Y); + ((osBotella)nuevaBotella).Diametro = Diametro_botella; + nuevaBotella.AutoCreated = true; + Botellas.Add((osBotella)nuevaBotella); + } } } } else + { TiempoRestante = 0; + } } + public override void ucLoaded() { // El UserControl ya se ha cargado y podemos obtener las coordenadas para diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 34e5c4c..b10e2cc 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -19,6 +19,7 @@ using Microsoft.Xna.Framework; using FarseerPhysics.Dynamics; using Siemens.Simatic.Simulation.Runtime; using System.Windows.Media.Imaging; +using System.Windows.Input; namespace CtrEditor.ObjetosSim { @@ -41,6 +42,28 @@ namespace CtrEditor.ObjetosSim int ZIndex(); } + public class DataSaveToSerialize + { + private MainViewModel? _mainViewModel; + private UserControl? VisualRepresentation; + private SimulationManagerFP? simulationManager; + + public DataSaveToSerialize(MainViewModel a, UserControl b, SimulationManagerFP c ) + { + _mainViewModel = a; + VisualRepresentation = b; + simulationManager = c; + } + + public void DataRestoreAfterSerialize(out MainViewModel a, out UserControl b, out SimulationManagerFP c) + { + a = _mainViewModel; + b = VisualRepresentation; + c = simulationManager; + } + } + + public abstract class osBase : INotifyPropertyChanged { public virtual string Nombre { get; set; } = "osBase"; @@ -52,6 +75,9 @@ namespace CtrEditor.ObjetosSim public bool AutoCreated = false; public bool RemoverDesdeSimulacion = false; // La simulacion indica que se debe remover + [JsonIgnore] + private DataSaveToSerialize DataSave; + [JsonIgnore] protected UserControl? _visualRepresentation = null; @@ -74,6 +100,19 @@ namespace CtrEditor.ObjetosSim [JsonIgnore] public SimulationManagerFP simulationManager; + public void SalvarDatosNoSerializables() + { + DataSave = new DataSaveToSerialize(_mainViewModel,_visualRepresentation,simulationManager); + _mainViewModel = null; + _visualRepresentation = null; + simulationManager = null; + } + public void RestaurarDatosNoSerializables() + { + if (DataSave == null) return; + DataSave.DataRestoreAfterSerialize(out _mainViewModel,out _visualRepresentation,out simulationManager); + } + protected osBase ObtenerLink(string NameLink, Type tipoOsBase) { if (!string.IsNullOrEmpty(NameLink) && _mainViewModel != null)