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; using CtrEditor.Convertidores; using CtrEditor.Siemens; using CtrEditor.Simulacion; using System.Windows.Media; using Microsoft.Xna.Framework; using FarseerPhysics.Dynamics; namespace CtrEditor.ObjetosSim { public interface IosBase { string Nombre { get; } 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 UpdateControl(); public abstract void UpdateGeometryStart(); public abstract void UpdateGeometryStep(); public abstract void UpdatePLC(PLCModel plc, int elapsedMilliseconds); public abstract void ucLoaded(); [JsonIgnore] public MainViewModel _mainViewModel; [JsonIgnore] public UserControl? VisualRepresentation { get => _visualRepresentation; set => _visualRepresentation = value; } [JsonIgnore] public SimulationManagerFP simulationManager; protected osBase ObtenerLink(string NameLink, Type tipoOsBase) { if (!string.IsNullOrEmpty(NameLink) && _mainViewModel != null) { foreach (var objetoSimulable in _mainViewModel.ObjetosSimulables) { if (tipoOsBase.IsInstanceOfType(objetoSimulable) && ((osBase)objetoSimulable).Nombre == NameLink) { return (osBase)objetoSimulable; } } } return null; } 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 (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(System.Windows.Shapes.Rectangle rect) { if (rect != null) { var _canvasLeft = CanvasGetLeftinMeter(); var _canvasTop = CanvasGetTopinMeter(); // Obtiene la transformada del objeto visual GeneralTransform transform = rect.TransformToAncestor(_visualRepresentation); // Obtiene la posición absoluta Point topLeft = transform.Transform(new Point(0, 0)); Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight)); return (new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y) + _canvasTop), new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.Y) + _canvasTop)); } else return (new Vector2(0, 0), new Vector2(0, 0)); } public (Vector2 Start, Vector2 End) GetCenterLineVectors(System.Windows.Shapes.Rectangle rect) { if (rect == null) return (new Vector2(0, 0), new Vector2(0, 0)); var _canvasLeft = CanvasGetLeftinMeter(); var _canvasTop = CanvasGetTopinMeter(); var transform = rect.TransformToAncestor(_visualRepresentation); // Puntos en coordenadas locales del rectángulo no rotado Point startLocal = new Point(0, rect.ActualHeight / 2); Point endLocal = new Point(rect.ActualWidth, rect.ActualHeight / 2); // Transformar estos puntos al sistema de coordenadas del ancestro Point transformedStart = transform.Transform(startLocal); Point transformedEnd = transform.Transform(endLocal); // Convierte a unidades de Farseer (metros en este caso) Vector2 start = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.Y) + _canvasTop); Vector2 end = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.Y) + _canvasTop); return (start, end); } public Vector2 GetRectangleCenter(System.Windows.Shapes.Rectangle wpfRect) { var coords = GetRectangleCoordinatesInMeter(wpfRect); Vector2 topLeft = coords.TopLeft; Vector2 bottomRight = coords.BottomRight; // Calcular el centro, ancho y alto en metros return new Vector2((topLeft.X + bottomRight.X) / 2, (topLeft.Y + bottomRight.Y) / 2); } public void UpdateRectangle(simRectangle simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { if (simRect != null) simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } public simRectangle AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } public void UpdateOrCreateLine(simLine simGuia, System.Windows.Shapes.Rectangle wpfRect) { if (simGuia != null) { var coords = GetCenterLineVectors(wpfRect); // Crear o actualizar simRectangle simGuia.Create( coords.Start,coords.End); // asumiendo que el ángulo inicial es 0 } } public simLine AddLine(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect) { var coords = GetCenterLineVectors(wpfRect); return simulationManager.AddLine(coords.Start, coords.End); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } [AttributeUsage(AttributeTargets.Property)] public class HiddenAttribute : Attribute { } }