using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Text; using System.Text.Json.Serialization; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using static System.Runtime.InteropServices.JavaScript.JSType; namespace CtrEditor.ObjetosSim { public interface IosBase { string Nombre { get; } void ConnectSimManager(SimulationManager simulationManager); void UpdateControl(); } public interface IDataContainer { osBase? Datos { get; set; } void Resize(float width, float height); void Move(float Left, float Top); void Rotate(float Angle); void Highlight(bool State); int ZIndex(); } public abstract class osBase : INotifyPropertyChanged, IosBase { public abstract float Left { get; set; } public abstract float Top { get; set; } public bool Inicializado = false; protected UserControl? _visualRepresentation = null; public abstract string Nombre { get; set; } public abstract void ConnectSimManager(SimulationManager simulationManager); public abstract void UpdateControl(); public abstract void UpdateGeometry(); [JsonIgnore] public UserControl? VisualRepresentation { get => _visualRepresentation; set => _visualRepresentation = value; } public void CanvasSetLeftinMeter(float left) { if (_visualRepresentation != null) Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(left)); } public float CanvasGetLeftinMeter() { if (_visualRepresentation != null) return PixelToMeter.Instance.calc.PixelsToMeters((float)Canvas.GetLeft(_visualRepresentation)); else return 0f; } public void CanvasSetTopinMeter(float top) { if (_visualRepresentation != null) Canvas.SetTop(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(top)); } public float CanvasGetTopinMeter() { if (_visualRepresentation != null) return PixelToMeter.Instance.calc.PixelsToMeters((float)Canvas.GetTop(_visualRepresentation)); else return 0f; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class PixelToMeter { // Instancia privada estática, parte del patrón Singleton private static PixelToMeter? _instance; public UnitConverter calc = new UnitConverter(0.01f); // Propiedad pública estática para acceder a la instancia public static PixelToMeter Instance { get { if (_instance == null) { _instance = new PixelToMeter(); } return _instance; } } } public class MeterToPixelConverter : IValueConverter { 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; 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 (parameter != null) if (parameter.ToString() == "0.5") factor = 0.5f; else if (parameter.ToString() == "-0.5") factor = -0.5f; return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor; } } public class DistanceToMarginConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double distance) { return new Thickness(0, 0, 0, PixelToMeter.Instance.calc.MetersToPixels((float)distance)); // Ajustar Bottom a 'distance' } return new Thickness(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException("ConvertBack is not supported."); } } public class UnitConverter { // La escala representa cuántos metros hay en un píxel public float Scale { get; private set; } public UnitConverter(float scale) { if (scale <= 0) throw new ArgumentException("Scale must be greater than zero."); Scale = scale; } // Convierte una distancia en metros a píxeles public float MetersToPixels(float meters) { return meters / Scale; } // Convierte una distancia en píxeles a metros public float PixelsToMeters(float pixels) { return pixels * Scale; } // Configurar o ajustar la escala public void SetScale(float newScale) { if (newScale <= 0) throw new ArgumentException("Scale must be greater than zero."); Scale = newScale; } } }