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 0000000..51669f8
Binary files /dev/null and b/Icons/duplicate.png differ
diff --git a/MainViewModel.cs b/MainViewModel.cs
index 669bdc4..8b898b6 100644
--- a/MainViewModel.cs
+++ b/MainViewModel.cs
@@ -58,7 +58,9 @@ namespace CtrEditor
public ICommand TBDisconnectPLCCommand { get; }
public ICommand TBEliminarUserControlCommand { get; }
+ public ICommand TBDuplicarUserControlCommand { get; }
+
public ICommand OpenWorkDirectoryCommand { get; }
// Evento que se dispara cuando se selecciona una nueva imagen
@@ -246,6 +248,7 @@ namespace CtrEditor
TBDisconnectPLCCommand = new RelayCommand(DisconnectPLC, () => 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)