CtrEditor/MainViewModel.cs

381 lines
13 KiB
C#
Raw Normal View History

using System;
2024-05-02 11:06:45 -03:00
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using Ookii.Dialogs.Wpf;
using System.Collections.ObjectModel;
using System.Windows.Media;
using System.Windows.Media.Imaging;
2024-05-03 05:13:25 -03:00
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Windows.Threading;
using CtrEditor.ObjetosSim;
using CtrEditor.Siemens;
using System.IO;
// using System.Windows.Forms;
using System.Text.Json.Serialization;
using System.Text.Json;
using Newtonsoft.Json;
using System.Windows.Data;
using System.Windows;
using static System.Resources.ResXFileRef;
2024-05-11 11:58:55 -03:00
using CtrEditor.Convertidores;
using CtrEditor.Simulacion;
2024-05-02 11:06:45 -03:00
namespace CtrEditor
{
2024-05-03 05:13:25 -03:00
2024-05-02 11:06:45 -03:00
public class MainViewModel : INotifyPropertyChanged
{
public DatosDeTrabajo datosDeTrabajo { get; }
public ObservableCollection<string> listaImagenes { get; private set; } // Publicación de las claves del diccionario
public ObservableCollection<TipoSimulable> ListaOsBase { get; } = new ObservableCollection<TipoSimulable>();
private ObservableCollection<osBase> _objetosSimulables = new ObservableCollection<osBase>();
public PLCViewModel _plcViewModelData;
public SimulationManagerFP simulationManager = new SimulationManagerFP();
2024-05-06 12:31:45 -03:00
2024-05-03 05:13:25 -03:00
private readonly DispatcherTimer _timerSimulacion;
public ICommand StartSimulationCommand { get; }
public ICommand StopSimulationCommand { get; }
public ICommand ItemDoubleClickCommand { get; private set; }
2024-05-02 11:06:45 -03:00
// Evento que se dispara cuando se selecciona una nueva imagen
public event EventHandler<string> ImageSelected;
2024-05-03 05:13:25 -03:00
public event EventHandler<TickSimulacionEventArgs> TickSimulacion;
public event Action<UserControl> OnUserControlSelected;
2024-05-02 11:06:45 -03:00
public MainViewModel()
{
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
datosDeTrabajo = new DatosDeTrabajo();
// Inicializa el PLCViewModel
_plcViewModelData = new PLCViewModel();
InitializeTipoSimulableList();
ItemDoubleClickCommand = new ParameterizedRelayCommand(ExecuteDoubleClick);
2024-05-03 05:13:25 -03:00
_timerSimulacion = new DispatcherTimer();
_timerSimulacion.Interval = TimeSpan.FromMilliseconds(16); // ajusta el intervalo según sea necesario
2024-05-03 05:13:25 -03:00
_timerSimulacion.Tick += OnTickSimulacion;
StartSimulationCommand = new RelayCommand(StartSimulation);
StopSimulationCommand = new RelayCommand(StopSimulation);
}
public void LoadInitialData()
{
// Suponiendo que "SelectedImage" es una propiedad que al establecerse dispara "ImageSelected"
directorioTrabajo = EstadoPersistente.Instance.directorio;
}
private TipoSimulable _selectedItem = null;
public TipoSimulable SelectedItem
{
get => _selectedItem;
set
{
if (_selectedItem != value)
{
_selectedItem = value;
OnPropertyChanged(nameof(SelectedItem)); // Notificar que la propiedad ha cambiado
}
}
}
private void ExecuteDoubleClick(object parameter)
{
if (parameter is TipoSimulable tipoSimulable)
{
// Crear una nueva instancia del osBase correspondiente
osBase? newosBase = UserControlFactory.GetInstanceForType(tipoSimulable.Tipo);
if (newosBase != null)
{
if (CrearUsercontrol(newosBase))
// Añadir el nuevo osBase a la colección de objetos simulables
ObjetosSimulables.Add(newosBase);
}
}
}
private void InitializeTipoSimulableList()
{
var baseType = typeof(osBase);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsSubclassOf(baseType) && !type.IsAbstract);
foreach (var type in types)
{
ListaOsBase.Add(new TipoSimulable { Nombre = type.Name, Tipo = type });
}
2024-05-03 05:13:25 -03:00
}
private void StartSimulation()
{
foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdateGeometryStart();
simulationManager.Debug_DrawInitialBodies();
2024-05-03 05:13:25 -03:00
_timerSimulacion.Start();
simulationManager.stopwatch.Start();
2024-05-03 05:13:25 -03:00
}
private void StopSimulation()
{
_timerSimulacion.Stop();
simulationManager.stopwatch.Stop();
2024-05-02 11:06:45 -03:00
}
2024-05-03 05:13:25 -03:00
private void OnTickSimulacion(object sender, EventArgs e)
{
foreach (var objetoSimulable in ObjetosSimulables)
2024-05-11 15:55:44 -03:00
{
if (_plcViewModelData.IsConnected)
objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface);
objetoSimulable.UpdateGeometryStep();
2024-05-11 15:55:44 -03:00
}
simulationManager.Step();
2024-05-06 12:31:45 -03:00
foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdateControl();
2024-05-03 05:13:25 -03:00
}
2024-05-02 11:06:45 -03:00
2024-05-06 12:31:45 -03:00
//protected virtual void OnTickSimulacion(TickSimulacionEventArgs e)
//{
// TickSimulacion?.Invoke(this, e);
//}
public string directorioTrabajo
2024-05-02 11:06:45 -03:00
{
get => EstadoPersistente.Instance.directorio;
2024-05-02 11:06:45 -03:00
set
{
2024-05-02 11:26:45 -03:00
if (value != null)
{
EstadoPersistente.Instance.directorio = value; // Actualizar el estado persistente
2024-05-02 11:26:45 -03:00
EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado
datosDeTrabajo.CargarImagenes();
listaImagenes = new ObservableCollection<string>(datosDeTrabajo.Imagenes.Keys); // Actualizar claves
SelectedImage = null;
if (listaImagenes.FirstOrDefault() != null)
SelectedImage = listaImagenes.FirstOrDefault();
OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad
OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado
2024-05-02 11:26:45 -03:00
}
2024-05-02 11:06:45 -03:00
}
}
public PLCViewModel PLCViewModel
{
get { return _plcViewModelData; }
set
{
_plcViewModelData = value;
OnPropertyChanged(nameof(PLCViewModel));
}
}
private string _selectedImage = null;
public string SelectedImage
{
get => _selectedImage;
set
{
if (_selectedImage != value && value != null)
{
StopSimulation();
SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen
_selectedImage = value;
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen
LoadStateObjetosSimulables();
}
_selectedImage = value;
OnPropertyChanged(nameof(SelectedImage));
}
}
2024-05-04 16:27:04 -03:00
private osBase _selectedItemOsList;
public osBase SelectedItemOsList
{
get => _selectedItemOsList;
set
{
if (_selectedItemOsList != value)
{
_selectedItemOsList = value;
OnPropertyChanged(nameof(SelectedItemOsList));
}
}
}
2024-05-02 11:06:45 -03:00
public ICommand OpenWorkDirectoryCommand { get; }
private void OpenWorkDirectory()
{
var dialog = new VistaFolderBrowserDialog();
if (dialog.ShowDialog() == true) // Mostrar el diálogo y comprobar si el resultado es positivo
{
directorioTrabajo = dialog.SelectedPath; // Actualizar la propiedad que también actualiza el estado persistente
2024-05-02 11:06:45 -03:00
}
}
//
// Lista de osBase
//
public ObservableCollection<osBase> ObjetosSimulables
{
get => _objetosSimulables;
set
{
if (_objetosSimulables != value)
{
_objetosSimulables = value;
OnPropertyChanged(nameof(ObjetosSimulables));
}
}
}
public void SaveStateObjetosSimulables()
{
if (_selectedImage != null)
{
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto
};
foreach (var obj in ObjetosSimulables)
{
obj.VisualRepresentation = null;
obj.simulationManager = null;
}
// Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter
var dataToSerialize = new SimulationData
{
ObjetosSimulables = ObjetosSimulables,
UnitConverter = PixelToMeter.Instance.calc,
PLC_ConnectionData = PLCViewModel
};
var serializedData = JsonConvert.SerializeObject(dataToSerialize, settings);
File.WriteAllText(datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"), serializedData);
}
}
public void LoadStateObjetosSimulables()
{
try
{
ObjetosSimulables.Clear();
simulationManager.Clear();
if (_selectedImage != null)
{
string jsonPath = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json");
if (File.Exists(jsonPath))
{
string jsonString = File.ReadAllText(jsonPath);
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
ObjectCreationHandling = ObjectCreationHandling.Replace,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
var simulationData = JsonConvert.DeserializeObject<SimulationData>(jsonString, settings);
if (simulationData != null)
{
if (simulationData.ObjetosSimulables is not null)
ObjetosSimulables = simulationData.ObjetosSimulables;
if (simulationData.PLC_ConnectionData is not null)
PLCViewModel = simulationData.PLC_ConnectionData;
else
PLCViewModel = new PLCViewModel();
PixelToMeter.Instance.calc = simulationData.UnitConverter;
// Recorrer la colección de objetos simulables
foreach (var objetoSimulable in ObjetosSimulables)
CrearUsercontrol(objetoSimulable);
}
}
}
}
catch { /* Consider logging the error or handling it appropriately */ }
}
2024-05-02 11:06:45 -03:00
private bool CrearUsercontrol(osBase osObjeto)
{
Type tipoObjeto = osObjeto.GetType();
// Obtén el UserControl correspondiente para el tipo de objeto
UserControl? userControl = UserControlFactory.GetControlForType(tipoObjeto);
if (userControl != null)
{
// Asignar los datos al UserControl
2024-05-06 12:31:45 -03:00
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager);
OnUserControlSelected?.Invoke(userControl);
return true;
}
return false;
}
// Implementación de INotifyPropertyChanged...
2024-05-02 11:06:45 -03:00
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
2024-05-03 05:13:25 -03:00
}
public class SimulationData
{
public ObservableCollection<osBase> ObjetosSimulables { get; set; }
public UnitConverter UnitConverter { get; set; }
public PLCViewModel PLC_ConnectionData { get; set; }
}
public class TipoSimulable
{
public string Nombre { get; set; }
public Type Tipo { get; set; }
}
public class TickSimulacionEventArgs : EventArgs
{
// Aquí puedes agregar propiedades o campos para pasar información adicional
// en el evento TickSimulacion
2024-05-02 11:06:45 -03:00
}
}