diff --git a/MainViewModel.cs b/MainViewModel.cs index fa609e6..21b5f7d 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -15,10 +15,12 @@ using static System.Runtime.InteropServices.JavaScript.JSType; using System.Windows.Threading; using CtrEditor.ObjetosSim; using System.IO; -using System.Windows.Forms; +// using System.Windows.Forms; using System.Text.Json.Serialization; using System.Text.Json; using Newtonsoft.Json; +using System.Windows.Data; +using System.Windows; namespace CtrEditor { @@ -28,6 +30,7 @@ namespace CtrEditor public DatosDeTrabajo datosDeTrabajo { get; } public ObservableCollection listaImagenes { get; private set; } // Publicación de las claves del diccionario public ObservableCollection ListaOsBase { get; } = new ObservableCollection(); + private ObservableCollection _objetosSimulables = new ObservableCollection(); private readonly DispatcherTimer _timerSimulacion; @@ -39,7 +42,7 @@ namespace CtrEditor // Evento que se dispara cuando se selecciona una nueva imagen public event EventHandler ImageSelected; public event EventHandler TickSimulacion; - public event Action OnUserControlSelected; + public event Action OnUserControlSelected; public MainViewModel() { @@ -85,11 +88,13 @@ namespace CtrEditor { if (parameter is TipoSimulable tipoSimulable) { - var instance = Activator.CreateInstance(tipoSimulable.Tipo) as osBase; - if (instance != null) - { - ObjetosSimulables.Add(instance); - OnUserControlSelected?.Invoke(instance); + // 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); } } } @@ -181,23 +186,21 @@ namespace CtrEditor // // Lista de osBase // - private ObservableCollection objetosSimulables = new ObservableCollection(); + public ObservableCollection ObjetosSimulables { - get => objetosSimulables; + get => _objetosSimulables; set { - if (objetosSimulables != value) + if (_objetosSimulables != value) { - objetosSimulables = value; + _objetosSimulables = value; OnPropertyChanged(nameof(ObjetosSimulables)); } } } - - public void SaveStateObjetosSimulables() { if (_selectedImage != null) @@ -208,11 +211,11 @@ namespace CtrEditor NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.Auto }; - foreach (var obj in objetosSimulables) + foreach (var obj in ObjetosSimulables) { obj.VisualRepresentation = null; } - var serializedData = JsonConvert.SerializeObject(objetosSimulables, settings); + var serializedData = JsonConvert.SerializeObject(ObjetosSimulables, settings); File.WriteAllText(datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"), serializedData); } } @@ -235,11 +238,13 @@ namespace CtrEditor PreserveReferencesHandling = PreserveReferencesHandling.Objects, ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }; - objetosSimulables = JsonConvert.DeserializeObject>(jsonString, settings); - - foreach (var obj in objetosSimulables) + if (jsonString != null) { - OnUserControlSelected?.Invoke(obj); + ObjetosSimulables = JsonConvert.DeserializeObject>(jsonString, settings); + + // Ahora recorres la colección de objetos simulables + foreach (var objetoSimulable in ObjetosSimulables) + CrearUsercontrol(objetoSimulable); } } } @@ -247,6 +252,27 @@ namespace CtrEditor catch { /* Consider logging the error or handling it appropriately */ } } + 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 + UserControlFactory.AssignDatos(userControl, osObjeto); + + OnUserControlSelected?.Invoke(userControl); + return true; + } + return false; + } + + + + // Implementación de INotifyPropertyChanged... public event PropertyChangedEventHandler PropertyChanged; diff --git a/MainWindow.xaml b/MainWindow.xaml index 0d6ec2b..4c875c3 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -69,7 +69,10 @@ - + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 53b40cd..ff5fdf0 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -9,6 +9,7 @@ using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using CtrEditor.ObjetosSim; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace CtrEditor { @@ -53,61 +54,56 @@ namespace CtrEditor } } - private void AgregarUserControl(osBase NuevoOS) + private void AgregarUserControl(UserControl userControl) { - if (NuevoOS != null) + if (userControl is IDataContainer dataContainer) { - if (NuevoOS.VisualRepresentation is null) + var NuevoOS = dataContainer.Datos; + if (!NuevoOS.Inicializado) // Aun no fue inicializado { - UserControl userControl = UserControlFactory.GetControlForType(NuevoOS.GetType()); - NuevoOS.VisualRepresentation = userControl; + // Obtiene el factor de escala + var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform; + double scaleX = scaleTransform?.ScaleX ?? 1.0; + double scaleY = scaleTransform?.ScaleY ?? 1.0; - if (!NuevoOS.Inicializado) // Aun no fue inicializado - { - // Obtiene el factor de escala - var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform; - double scaleX = scaleTransform?.ScaleX ?? 1.0; - double scaleY = scaleTransform?.ScaleY ?? 1.0; + // Obtiene el área visible del ScrollViewer + double visibleWidth = ImagenEnTrabajoScrollViewer.ViewportWidth; + double visibleHeight = ImagenEnTrabajoScrollViewer.ViewportHeight; - // Obtiene el área visible del ScrollViewer - double visibleWidth = ImagenEnTrabajoScrollViewer.ViewportWidth; - double visibleHeight = ImagenEnTrabajoScrollViewer.ViewportHeight; + // Obtiene la posición actual del desplazamiento ajustada por el zoom + double offsetX = ImagenEnTrabajoScrollViewer.HorizontalOffset / scaleX; + double offsetY = ImagenEnTrabajoScrollViewer.VerticalOffset / scaleY; - // Obtiene la posición actual del desplazamiento ajustada por el zoom - double offsetX = ImagenEnTrabajoScrollViewer.HorizontalOffset / scaleX; - double offsetY = ImagenEnTrabajoScrollViewer.VerticalOffset / scaleY; + // Calcula el centro visible ajustado + double centerX = offsetX + (visibleWidth / scaleX) / 2; + double centerY = offsetY + (visibleHeight / scaleY) / 2; - // Calcula el centro visible ajustado - double centerX = offsetX + (visibleWidth / scaleX) / 2; - double centerY = offsetY + (visibleHeight / scaleY) / 2; - - // Ajusta la posición del UserControl para que esté centrado en el área visible - double left = centerX - (userControl.ActualWidth / 2); - double top = centerY - (userControl.ActualHeight / 2); - - // Establece la posición del UserControl - NuevoOS.Left = left; - NuevoOS.Top = top; - - NuevoOS.Inicializado = true; - } + // Ajusta la posición del UserControl para que esté centrado en el área visible + double left = centerX - (userControl.ActualWidth / 2); + double top = centerY - (userControl.ActualHeight / 2); // Establece la posición del UserControl - Canvas.SetLeft(userControl, NuevoOS.Left); - Canvas.SetTop(userControl, NuevoOS.Top); + NuevoOS.Left = left; + NuevoOS.Top = top; - // Suscribirse a eventos de mouse para marcar el Control - userControl.MouseEnter += UserControl_MouseEnter; - userControl.MouseLeave += UserControl_MouseLeave; - - // Suscribir a eventos de mouse para panning - userControl.MouseLeftButtonDown += UserControl_MouseLeftButtonDown; - userControl.MouseLeftButtonUp += UserControl_MouseLeftButtonUp; - userControl.MouseMove += UserControl_MouseMove; - - // Añade el UserControl al Canvas - ImagenEnTrabajoCanvas.Children.Add(userControl); + NuevoOS.Inicializado = true; } + + // Establece la posición del UserControl + Canvas.SetLeft(userControl, NuevoOS.Left); + Canvas.SetTop(userControl, NuevoOS.Top); + + // Suscribirse a eventos de mouse para marcar el Control + userControl.MouseEnter += UserControl_MouseEnter; + userControl.MouseLeave += UserControl_MouseLeave; + + // Suscribir a eventos de mouse para panning + userControl.MouseLeftButtonDown += UserControl_MouseLeftButtonDown; + userControl.MouseLeftButtonUp += UserControl_MouseLeftButtonUp; + userControl.MouseMove += UserControl_MouseMove; + + // Añade el UserControl al Canvas + ImagenEnTrabajoCanvas.Children.Add(userControl); } } @@ -203,8 +199,9 @@ namespace CtrEditor var newX = Canvas.GetLeft(_currentDraggingControl) + dx; var newY = Canvas.GetTop(_currentDraggingControl) + dy; - Canvas.SetLeft(_currentDraggingControl, newX); - Canvas.SetTop(_currentDraggingControl, newY); + if (_currentDraggingControl is IDataContainer dataContainer) + dataContainer.Move(newX, newY); + _startPointUserControl = currentPosition; // Actualiza el punto inicial para el siguiente movimiento } else if (_isRotatingUserControl) @@ -227,9 +224,11 @@ namespace CtrEditor double deltaY = currentPosition.Y - _startPointUserControl.Y; double angle = Math.Atan2(deltaY, deltaX) * (180 / Math.PI); - RotateTransform rotateTransform = control.RenderTransform as RotateTransform; - rotateTransform.Angle = angle; // - _initialAngleUserControl; // Asegúrate de ajustar esta parte según cómo calcules el ángulo inicial + //RotateTransform rotateTransform = control.RenderTransform as RotateTransform; + //rotateTransform.Angle = angle; // - _initialAngleUserControl; // Asegúrate de ajustar esta parte según cómo calcules el ángulo inicial + if (control is IDataContainer dataContainer) + dataContainer.Rotate(angle); // Actualizar el ángulo mostrado _angleDisplayTextBlock.Text = $"Ángulo: {angle:F2}°"; @@ -252,17 +251,8 @@ namespace CtrEditor double newWidth = Math.Max(control.ActualWidth + widthChange, control.MinWidth); control.Width = newWidth; // Asegurar que no sea menor que el mínimo - // Actualizar el ancho de los elementos internos - if (control.Content is Panel panel) - { - foreach (var child in panel.Children) - { - if (child is Rectangle rect) - { - rect.Width = newWidth; // Establece el nuevo ancho - } - } - } + if (control is IDataContainer dataContainer) + dataContainer.Resize(newWidth, 0); // Actualizar el punto de inicio para el próximo evento de movimiento _startPointUserControl = currentPosition; @@ -392,6 +382,40 @@ namespace CtrEditor e.Handled = true; // Evita el procesamiento adicional del evento } + private void ListaOs_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + PanelEdicion.Children.Clear(); // Limpiar el panel existente + + if (e.AddedItems.Count > 0 && e.AddedItems[0] is osBase selectedObject) + CargarPropiedadesosDatos(selectedObject); + } + + private void CargarPropiedadesosDatos(osBase selectedObject) + { + PanelEdicion.Children.Clear(); // Limpiar el panel existente + + // Reflexión para obtener todas las propiedades del objeto seleccionado + var properties = selectedObject.GetType().GetProperties(); + + foreach (var property in properties) + { + // Crear un Label y un TextBox para cada propiedad + var label = new Label { Content = property.Name }; + var textBox = new TextBox { Width = 200, Margin = new Thickness(2) }; + textBox.SetBinding(TextBox.TextProperty, new Binding(property.Name) + { + Source = selectedObject, + Mode = BindingMode.TwoWay, + UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged + }); + + // Agregar controles al StackPanel + PanelEdicion.Children.Add(label); + PanelEdicion.Children.Add(textBox); + } + + } + private void MainViewModel_TickSimulacion(object sender, TickSimulacionEventArgs e) { // aquí puedes agregar la lógica para actualizar tus UserControl diff --git a/ObjetosSim/UserControlFactory.cs b/ObjetosSim/UserControlFactory.cs index b3118ff..0241e50 100644 --- a/ObjetosSim/UserControlFactory.cs +++ b/ObjetosSim/UserControlFactory.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,7 +10,7 @@ namespace CtrEditor.ObjetosSim { public static class UserControlFactory { - public static UserControl GetControlForType(Type tipoObjeto) + public static UserControl? GetControlForType(Type tipoObjeto) { if (tipoObjeto == typeof(osBotella)) return new ucBotella(); @@ -18,9 +19,42 @@ namespace CtrEditor.ObjetosSim // Puedes añadir más condiciones para otros tipos + return null; + } + + public static osBase? GetInstanceForType(Type tipoObjeto) + { + if (tipoObjeto == typeof(osBotella)) + return new osBotella(); + if (tipoObjeto == typeof(osTransporteTTop)) + return new osTransporteTTop(); + + // Puedes añadir más condiciones para otros tipos return null; } + + public static osBase? CreateInstanceAndPopulate(Type tipoObjeto, string jsonString) + { + osBase? instance = GetInstanceForType(tipoObjeto); + if (instance != null) + { + // Deserializa los datos desde jsonString y popula la instancia + JsonConvert.PopulateObject(jsonString, instance); + } + return instance; + } + + public static void AssignDatos(UserControl userControl, osBase datos) + { + if (userControl is IDataContainer dataContainer) + { + dataContainer.Datos = datos; + userControl.DataContext = datos; + datos.VisualRepresentation = userControl; + } + } } + } diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 2f604c8..7a2361a 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Text.Json.Serialization; using System.Threading.Tasks; using System.Windows.Controls; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace CtrEditor.ObjetosSim { @@ -12,33 +14,79 @@ namespace CtrEditor.ObjetosSim public interface IosBase { string Nombre { get; } - void Update(); + void Update(); } - - public abstract class osBase : IosBase + public interface IDataContainer { + osBase? Datos { get; set; } + void Resize(double width, double height); + void Move(double Left, double Top); + void Rotate(double Angle); + } + + public abstract class osBase : INotifyPropertyChanged, IosBase + { + private string _nombre = "Base"; + public double _left; + public double _top; + + public bool Inicializado = false; + public double Left + { + get => _left; + + set + { + _left = value; + if (_visualRepresentation != null) + Canvas.SetLeft(_visualRepresentation, _left); + OnPropertyChanged(nameof(Left)); + } + } + public double Top + { + get => _top; + + set + { + _top = value; + if (_visualRepresentation != null) + Canvas.SetTop(_visualRepresentation, _top); + + OnPropertyChanged(nameof(Top)); + } + } + private UserControl? _visualRepresentation = null; + public string Nombre + { + get => _nombre; + set + { + if (_nombre != value) + { + _nombre = value; + OnPropertyChanged(nameof(Nombre)); + } + } + } + + public abstract void Update(); + + [JsonIgnore] public UserControl? VisualRepresentation { get => _visualRepresentation; set => _visualRepresentation = value; } + public event PropertyChangedEventHandler PropertyChanged; - // Método para inicializar la representación visual, si es necesario - //public void InitializeVisualRepresentation() - //{ - // // Suponiendo que existe un método estático para obtener el UserControl adecuado - // _visualRepresentation = UserControlFactory.GetControlForType(this.GetType()); - //} - public string Nombre => "Base"; - public abstract void Update(); - public bool Inicializado = false; - public double Left { get; set; } - public double Top { get; set; } - - + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } } } diff --git a/ObjetosSim/ucBotella.xaml b/ObjetosSim/ucBotella.xaml index d85b0cd..f15fcde 100644 --- a/ObjetosSim/ucBotella.xaml +++ b/ObjetosSim/ucBotella.xaml @@ -1,5 +1,6 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + DataContext="{Binding RelativeSource={RelativeSource Self}}"> \ No newline at end of file diff --git a/ObjetosSim/ucBotella.xaml.cs b/ObjetosSim/ucBotella.xaml.cs index 4dff6c7..c5901ee 100644 --- a/ObjetosSim/ucBotella.xaml.cs +++ b/ObjetosSim/ucBotella.xaml.cs @@ -25,18 +25,31 @@ namespace CtrEditor.ObjetosSim public double diametro { get; set; } // Otros datos y métodos relevantes para la simulación - public new string Nombre => "Botella"; + private string _nombre = "Botella"; public override void Update() { // implementation of Update method } } - public partial class ucBotella : UserControl + public partial class ucBotella : UserControl, IDataContainer { + public osBase? Datos { get; set; } + public ucBotella() { InitializeComponent(); } + public void Resize(double width, double height) { } + public void Move(double Left, double Top) + { + if (Datos != null) + { + Datos.Left = Left; + Datos.Top = Top; + } + } + public void Rotate(double Angle) { } + } } diff --git a/ObjetosSim/ucTransporteTTop.xaml b/ObjetosSim/ucTransporteTTop.xaml index 21aaf6e..5793473 100644 --- a/ObjetosSim/ucTransporteTTop.xaml +++ b/ObjetosSim/ucTransporteTTop.xaml @@ -4,10 +4,13 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:CtrEditor" - mc:Ignorable="d" - DataContext="{Binding RelativeSource={RelativeSource Self}}"> + mc:Ignorable="d"> - + + + + + diff --git a/ObjetosSim/ucTransporteTTop.xaml.cs b/ObjetosSim/ucTransporteTTop.xaml.cs index 3161db8..8eb02de 100644 --- a/ObjetosSim/ucTransporteTTop.xaml.cs +++ b/ObjetosSim/ucTransporteTTop.xaml.cs @@ -12,6 +12,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace CtrEditor.ObjetosSim { @@ -22,24 +23,79 @@ namespace CtrEditor.ObjetosSim public class osTransporteTTop : osBase { - public double diametro { get; set; } - public double Ancho { get; set; } - public double Alto { get; set; } - // Otros datos y métodos relevantes para la simulación + private string _nombre = "Transporte TTOP"; + + private double _Ancho; + private double _Alto; + private double _Angulo; + + public double diametro { get; set; } + public double Ancho { + get { return _Ancho; } + set + { + _Ancho = value; + OnPropertyChanged(nameof(Ancho)); + } + } + public double Alto { + get { return _Alto; } + set + { + _Alto = value; + OnPropertyChanged(nameof(Alto)); + } + } + public double Angulo + { + get { return _Angulo; } + set + { + _Angulo = value; + OnPropertyChanged(nameof(Angulo)); + } + } + + public osTransporteTTop() + { + Ancho = 100; + Alto = 10; + } - public new string Nombre => "Transporte TTOP"; public override void Update() { // implementation of Update method } } - public partial class ucTransporteTTop : UserControl + public partial class ucTransporteTTop : UserControl, IDataContainer { + public osBase? Datos { get; set; } + public ucTransporteTTop() { InitializeComponent(); } - public osTransporteTTop Datos { get; set; } + public void Resize(double width, double height) + { + if (Datos is osTransporteTTop datos) + datos.Ancho = width; + } + public void Move(double Left, double Top) + { + if (Datos != null) + { + Datos.Left = Left; + Datos.Top = Top; + } + } + public void Rotate(double Angle) { + if (Datos != null) + if (Datos is osTransporteTTop datos) + datos.Angulo = Angle; + } } } + + +