Mejorado de HydPump
This commit is contained in:
parent
3f21061524
commit
d968aa9a2f
|
@ -0,0 +1,364 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Media;
|
||||
using CtrEditor.HydraulicSimulator;
|
||||
using CtrEditor.ObjetosSim;
|
||||
using CtrEditor.FuncionesBase;
|
||||
using HydraulicSimulator.Models;
|
||||
using Newtonsoft.Json;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||
{
|
||||
/// <summary>
|
||||
/// Bomba hidráulica que implementa las interfaces del simulador hidráulico
|
||||
/// </summary>
|
||||
public partial class osHydPump : osBase, IHydraulicPump, IosBase
|
||||
{
|
||||
#region Properties
|
||||
|
||||
private double _pumpHead = 50.0; // metros
|
||||
private double _maxFlow = 0.01; // m³/s (36 m³/h)
|
||||
private double _speedRatio = 1.0;
|
||||
private bool _isRunning = true;
|
||||
private int _pumpDirection = 1;
|
||||
private double _currentFlow = 0.0;
|
||||
private double _currentPressure = 0.0;
|
||||
|
||||
// Propiedades visuales
|
||||
[ObservableProperty]
|
||||
[property: Category("🎨 Apariencia")]
|
||||
[property: Description("Ancho de la bomba en metros")]
|
||||
[property: Name("Ancho")]
|
||||
private float ancho = 0.15f;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("🎨 Apariencia")]
|
||||
[property: Description("Alto de la bomba en metros")]
|
||||
[property: Name("Alto")]
|
||||
private float alto = 0.10f;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("🎨 Apariencia")]
|
||||
[property: Description("Color visual de la bomba")]
|
||||
[property: Name("Color")]
|
||||
private Brush colorButton_oculto = Brushes.Blue;
|
||||
|
||||
[Category("🔧 Bomba Hidráulica")]
|
||||
[DisplayName("Cabeza de bomba")]
|
||||
[Description("Cabeza de la bomba a caudal cero (m)")]
|
||||
public double PumpHead
|
||||
{
|
||||
get => _pumpHead;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _pumpHead, Math.Max(0, value)))
|
||||
{
|
||||
InvalidateHydraulicNetwork();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Category("🔧 Bomba Hidráulica")]
|
||||
[DisplayName("Caudal máximo")]
|
||||
[Description("Caudal máximo de la bomba (m³/s)")]
|
||||
public double MaxFlow
|
||||
{
|
||||
get => _maxFlow;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _maxFlow, Math.Max(0.001, value)))
|
||||
{
|
||||
InvalidateHydraulicNetwork();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Category("🔧 Bomba Hidráulica")]
|
||||
[DisplayName("Velocidad relativa")]
|
||||
[Description("Velocidad relativa de la bomba (0.0 a 1.0)")]
|
||||
public double SpeedRatio
|
||||
{
|
||||
get => _speedRatio;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _speedRatio, Math.Max(0.0, Math.Min(1.0, value)));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("🔧 Bomba Hidráulica")]
|
||||
[DisplayName("Funcionando")]
|
||||
[Description("Indica si la bomba está encendida")]
|
||||
public bool IsRunning
|
||||
{
|
||||
get => _isRunning;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _isRunning, value);
|
||||
}
|
||||
}
|
||||
|
||||
[Category("🔧 Bomba Hidráulica")]
|
||||
[DisplayName("Dirección")]
|
||||
[Description("Dirección de la bomba (+1 o -1)")]
|
||||
[ItemsSource(typeof(PumpDirectionItemsSource))]
|
||||
public int PumpDirection
|
||||
{
|
||||
get => _pumpDirection;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _pumpDirection, value == -1 ? -1 : 1))
|
||||
{
|
||||
InvalidateHydraulicNetwork();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Category("📊 Estado Actual")]
|
||||
[DisplayName("Caudal actual")]
|
||||
[Description("Caudal actual de la bomba (m³/s)")]
|
||||
[JsonIgnore]
|
||||
public double CurrentFlow
|
||||
{
|
||||
get => _currentFlow;
|
||||
private set => SetProperty(ref _currentFlow, value);
|
||||
}
|
||||
|
||||
[Category("📊 Estado Actual")]
|
||||
[DisplayName("Presión actual")]
|
||||
[Description("Presión actual en la bomba (Pa)")]
|
||||
[JsonIgnore]
|
||||
public double CurrentPressure
|
||||
{
|
||||
get => _currentPressure;
|
||||
private set => SetProperty(ref _currentPressure, value);
|
||||
}
|
||||
|
||||
[Category("📊 Estado Actual")]
|
||||
[DisplayName("Presión (bar)")]
|
||||
[Description("Presión actual en la bomba (bar)")]
|
||||
[JsonIgnore]
|
||||
public double CurrentPressureBar => CurrentPressure / 100000.0;
|
||||
|
||||
[Category("📊 Estado Actual")]
|
||||
[DisplayName("Caudal (L/min)")]
|
||||
[Description("Caudal actual en L/min")]
|
||||
[JsonIgnore]
|
||||
public double CurrentFlowLMin => CurrentFlow * 60000.0; // m³/s a L/min
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor y Métodos Base
|
||||
|
||||
private string nombre = NombreClase();
|
||||
|
||||
[Category("🏷️ Identificación")]
|
||||
[Description("Nombre identificativo del objeto")]
|
||||
[Name("Nombre")]
|
||||
public override string Nombre
|
||||
{
|
||||
get => nombre;
|
||||
set => SetProperty(ref nombre, value);
|
||||
}
|
||||
|
||||
public override void OnMove(float LeftPixels, float TopPixels)
|
||||
{
|
||||
// Los objetos hidráulicos no necesitan actualizar geometría física
|
||||
}
|
||||
|
||||
public override void OnResize(float Delta_Width, float Delta_Height)
|
||||
{
|
||||
Ancho += Delta_Width;
|
||||
Alto += Delta_Height;
|
||||
}
|
||||
|
||||
public osHydPump()
|
||||
{
|
||||
Nombre = "Bomba Hidráulica";
|
||||
}
|
||||
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Los objetos hidráulicos se registran automáticamente
|
||||
// cuando inicia la simulación a través de las interfaces
|
||||
}
|
||||
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
// Los objetos hidráulicos actualizan sus resultados
|
||||
// a través de ApplyHydraulicResults()
|
||||
}
|
||||
|
||||
public override void UpdateControl(int elapsedMilliseconds)
|
||||
{
|
||||
// Actualizar el color según el estado
|
||||
if (IsRunning)
|
||||
ColorButton_oculto = Brushes.Green;
|
||||
else
|
||||
ColorButton_oculto = Brushes.Gray;
|
||||
}
|
||||
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// Los objetos hidráulicos no necesitan geometría física
|
||||
base.ucLoaded();
|
||||
}
|
||||
|
||||
public override void ucUnLoaded()
|
||||
{
|
||||
// Los objetos hidráulicos no tienen geometría que limpiar
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHydraulicComponent Implementation
|
||||
|
||||
[JsonIgnore]
|
||||
public bool HasHydraulicComponents => true;
|
||||
|
||||
public List<HydraulicNodeDefinition> GetHydraulicNodes()
|
||||
{
|
||||
var nodes = new List<HydraulicNodeDefinition>
|
||||
{
|
||||
new HydraulicNodeDefinition($"{Nombre}_In", false, null, "Entrada de la bomba"),
|
||||
new HydraulicNodeDefinition($"{Nombre}_Out", false, null, "Salida de la bomba")
|
||||
};
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public List<HydraulicElementDefinition> GetHydraulicElements()
|
||||
{
|
||||
var elements = new List<HydraulicElementDefinition>();
|
||||
|
||||
if (HasHydraulicComponents)
|
||||
{
|
||||
// Crear bomba con parámetros actuales
|
||||
var pump = new PumpHQ(
|
||||
h0: PumpHead,
|
||||
q0: MaxFlow,
|
||||
speedRel: IsRunning ? SpeedRatio : 0.0, // Si no está funcionando, velocidad = 0
|
||||
direction: PumpDirection
|
||||
);
|
||||
|
||||
var pumpElement = new HydraulicElementDefinition(
|
||||
$"{Nombre}_Pump",
|
||||
$"{Nombre}_In",
|
||||
$"{Nombre}_Out",
|
||||
pump,
|
||||
$"Bomba {Nombre}"
|
||||
);
|
||||
|
||||
elements.Add(pumpElement);
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void UpdateHydraulicProperties()
|
||||
{
|
||||
// Aquí se pueden hacer validaciones o ajustes antes de la simulación
|
||||
if (!IsRunning)
|
||||
{
|
||||
SpeedRatio = 0.0;
|
||||
}
|
||||
|
||||
if (SpeedRatio < 0.0) SpeedRatio = 0.0;
|
||||
if (SpeedRatio > 1.0) SpeedRatio = 1.0;
|
||||
|
||||
Debug.WriteLine($"Bomba {Nombre}: Velocidad={SpeedRatio:F2}, Funcionando={IsRunning}");
|
||||
}
|
||||
|
||||
public void ApplyHydraulicResults(Dictionary<string, double> flows, Dictionary<string, double> pressures)
|
||||
{
|
||||
// Buscar resultados para esta bomba
|
||||
string pumpBranchName = $"{Nombre}_Pump";
|
||||
string inletNodeName = $"{Nombre}_In";
|
||||
string outletNodeName = $"{Nombre}_Out";
|
||||
|
||||
if (flows.ContainsKey(pumpBranchName))
|
||||
{
|
||||
CurrentFlow = flows[pumpBranchName];
|
||||
}
|
||||
|
||||
if (pressures.ContainsKey(inletNodeName))
|
||||
{
|
||||
CurrentPressure = pressures[inletNodeName];
|
||||
}
|
||||
else if (pressures.ContainsKey(outletNodeName))
|
||||
{
|
||||
CurrentPressure = pressures[outletNodeName];
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHydraulicFlowReceiver Implementation
|
||||
|
||||
public void SetFlow(double flow)
|
||||
{
|
||||
CurrentFlow = flow;
|
||||
}
|
||||
|
||||
public double GetFlow()
|
||||
{
|
||||
return CurrentFlow;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHydraulicPressureReceiver Implementation
|
||||
|
||||
public void SetPressure(double pressure)
|
||||
{
|
||||
CurrentPressure = pressure;
|
||||
}
|
||||
|
||||
public double GetPressure()
|
||||
{
|
||||
return CurrentPressure;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
/// <summary>
|
||||
/// Invalida la red hidráulica para forzar reconstrucción
|
||||
/// </summary>
|
||||
private void InvalidateHydraulicNetwork()
|
||||
{
|
||||
// Si tenemos acceso al MainViewModel, invalidar la red
|
||||
if (_mainViewModel?.hydraulicSimulationManager != null)
|
||||
{
|
||||
_mainViewModel.hydraulicSimulationManager.InvalidateNetwork();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Interface Implementation
|
||||
|
||||
public static string NombreClase() => "Bomba Hidráulica";
|
||||
public static string NombreCategoria() => "Componentes Hidráulicos";
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proveedor de items para la dirección de la bomba
|
||||
/// </summary>
|
||||
public class PumpDirectionItemsSource : IItemsSource
|
||||
{
|
||||
public Xceed.Wpf.Toolkit.PropertyGrid.Attributes.ItemCollection GetValues()
|
||||
{
|
||||
var items = new Xceed.Wpf.Toolkit.PropertyGrid.Attributes.ItemCollection();
|
||||
items.Add(1, "Adelante (+1)");
|
||||
items.Add(-1, "Atrás (-1)");
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,13 +2,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Controls;
|
||||
using System.Numerics;
|
||||
using System.Windows.Media;
|
||||
using CtrEditor.HydraulicSimulator;
|
||||
using CtrEditor.ObjetosSim;
|
||||
using CtrEditor.FuncionesBase;
|
||||
using CtrEditor.Simulacion;
|
||||
using HydraulicSimulator.Models;
|
||||
using Newtonsoft.Json;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
|
@ -17,11 +14,10 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
|||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||
{
|
||||
/// <summary>
|
||||
/// Ejemplo de bomba hidráulica que implementa las interfaces del simulador hidráulico
|
||||
/// Bomba hidráulica que implementa las interfaces del simulador hidráulico
|
||||
/// </summary>
|
||||
public partial class osPumpExample : osBase, IHydraulicPump, IosBase
|
||||
public partial class osHydPump : osBase, IHydraulicPump, IosBase
|
||||
{
|
||||
private simPumpExample SimGeometria;
|
||||
#region Properties
|
||||
|
||||
private double _pumpHead = 50.0; // metros
|
||||
|
@ -32,7 +28,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
private double _currentFlow = 0.0;
|
||||
private double _currentPressure = 0.0;
|
||||
|
||||
// Propiedades físicas y visuales
|
||||
// Propiedades visuales
|
||||
[ObservableProperty]
|
||||
[property: Category("🎨 Apariencia")]
|
||||
[property: Description("Ancho de la bomba en metros")]
|
||||
|
@ -45,44 +41,12 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
[property: Name("Alto")]
|
||||
private float alto = 0.10f;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("🎨 Apariencia")]
|
||||
[property: Description("Profundidad de la bomba en metros")]
|
||||
[property: Name("Profundidad")]
|
||||
private float profundidad = 0.08f;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("🎨 Apariencia")]
|
||||
[property: Description("Color visual de la bomba")]
|
||||
[property: Name("Color")]
|
||||
private Brush colorButton_oculto = Brushes.Blue;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("⚖️ Física")]
|
||||
[property: Description("Masa del objeto en kg")]
|
||||
[property: Name("Masa")]
|
||||
private float mass = 5.0f;
|
||||
|
||||
partial void OnAnchoChanged(float value)
|
||||
{
|
||||
SimGeometria?.SetDimensions(new Vector3(value, Alto, Profundidad));
|
||||
}
|
||||
|
||||
partial void OnAltoChanged(float value)
|
||||
{
|
||||
SimGeometria?.SetDimensions(new Vector3(Ancho, value, Profundidad));
|
||||
}
|
||||
|
||||
partial void OnProfundidadChanged(float value)
|
||||
{
|
||||
SimGeometria?.SetDimensions(new Vector3(Ancho, Alto, value));
|
||||
}
|
||||
|
||||
partial void OnMassChanged(float value)
|
||||
{
|
||||
SimGeometria?.SetMass(value);
|
||||
}
|
||||
|
||||
[Category("🔧 Bomba Hidráulica")]
|
||||
[DisplayName("Cabeza de bomba")]
|
||||
[Description("Cabeza de la bomba a caudal cero (m)")]
|
||||
|
@ -202,7 +166,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
|
||||
public override void OnMove(float LeftPixels, float TopPixels)
|
||||
{
|
||||
UpdateAfterMove();
|
||||
// Los objetos hidráulicos no necesitan actualizar geometría física
|
||||
}
|
||||
|
||||
public override void OnResize(float Delta_Width, float Delta_Height)
|
||||
|
@ -211,110 +175,41 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
Alto += Delta_Height;
|
||||
}
|
||||
|
||||
public Vector2 GetCentro()
|
||||
{
|
||||
return new Vector2(Left + Ancho / 2, Top + Alto / 2);
|
||||
}
|
||||
|
||||
public void SetCentro(float x, float y)
|
||||
{
|
||||
Left = x - Ancho / 2;
|
||||
Top = y - Alto / 2;
|
||||
}
|
||||
|
||||
public void SetCentro(Vector2 centro)
|
||||
{
|
||||
Left = centro.X - Ancho / 2;
|
||||
Top = centro.Y - Alto / 2;
|
||||
}
|
||||
|
||||
private void ActualizarGeometrias()
|
||||
{
|
||||
if (SimGeometria != null && !RemoverDesdeSimulacion)
|
||||
{
|
||||
SimGeometria.SetPosition(GetCentro());
|
||||
}
|
||||
}
|
||||
|
||||
public osPumpExample()
|
||||
public osHydPump()
|
||||
{
|
||||
Nombre = "Bomba Hidráulica";
|
||||
}
|
||||
|
||||
public void UpdateAfterMove()
|
||||
{
|
||||
if (!RemoverDesdeSimulacion)
|
||||
{
|
||||
ActualizarGeometrias();
|
||||
SimGeometria?.SetDimensions(new Vector3(Ancho, Alto, Profundidad));
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Se llama cuando inicia la simulación - crear geometría si no existe
|
||||
if (SimGeometria == null)
|
||||
{
|
||||
SimGeometria = simulationManager.AddPumpExample(new Vector3(Ancho, Alto, Profundidad), GetCentro(), Mass);
|
||||
SimGeometria.SimObjectType = "PumpExample";
|
||||
SimGeometria.WpfObject = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActualizarGeometrias();
|
||||
SimGeometria?.SetDimensions(new Vector3(Ancho, Alto, Profundidad));
|
||||
SimGeometria?.SetMass(Mass);
|
||||
}
|
||||
// Los objetos hidráulicos se registran automáticamente
|
||||
// cuando inicia la simulación a través de las interfaces
|
||||
}
|
||||
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
// Se llama durante cada paso de la simulación
|
||||
if (SimGeometria != null)
|
||||
{
|
||||
// Actualizar posición desde la simulación hacia WPF
|
||||
SetCentro(SimGeometria.Center);
|
||||
|
||||
// Actualizar propiedades hidráulicas en la simulación
|
||||
SimGeometria.UpdateHydraulicProperties(PumpHead, MaxFlow, SpeedRatio, IsRunning, PumpDirection);
|
||||
|
||||
// Obtener resultados de la simulación hidráulica
|
||||
CurrentFlow = SimGeometria.GetCurrentFlow();
|
||||
CurrentPressure = SimGeometria.GetCurrentPressure();
|
||||
}
|
||||
// Los objetos hidráulicos actualizan sus resultados
|
||||
// a través de ApplyHydraulicResults()
|
||||
}
|
||||
|
||||
public override void UpdateControl(int elapsedMilliseconds)
|
||||
{
|
||||
if (SimGeometria != null)
|
||||
{
|
||||
SetCentro(SimGeometria.Center);
|
||||
|
||||
// Actualizar el color según el estado
|
||||
if (IsRunning)
|
||||
ColorButton_oculto = Brushes.Green;
|
||||
else
|
||||
ColorButton_oculto = Brushes.Gray;
|
||||
|
||||
// Actualizar valores actuales desde la simulación
|
||||
CurrentFlow = SimGeometria.GetCurrentFlow();
|
||||
CurrentPressure = SimGeometria.GetCurrentPressure();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
// Los objetos hidráulicos no necesitan geometría física
|
||||
base.ucLoaded();
|
||||
SimGeometria = simulationManager.AddPumpExample(new Vector3(Ancho, Alto, Profundidad), GetCentro(), Mass);
|
||||
}
|
||||
|
||||
public override void ucUnLoaded()
|
||||
{
|
||||
// El UserControl se esta eliminando
|
||||
// eliminar el objeto de simulacion
|
||||
simulationManager.Remove(SimGeometria);
|
||||
// Los objetos hidráulicos no tienen geometría que limpiar
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<UserControl x:Class="CtrEditor.ObjetosSim.HydraulicComponents.ucHydPump"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="60" d:DesignWidth="80">
|
||||
<Grid>
|
||||
<!-- Fondo de la bomba -->
|
||||
<Ellipse x:Name="PumpBackground"
|
||||
Fill="LightSteelBlue"
|
||||
Stroke="DarkSlateGray"
|
||||
StrokeThickness="2"/>
|
||||
|
||||
<!-- Indicador de dirección -->
|
||||
<Polygon x:Name="DirectionArrow"
|
||||
Fill="DarkBlue"
|
||||
Points="30,25 50,35 30,45"
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<Polygon.RenderTransform>
|
||||
<RotateTransform x:Name="ArrowRotation" Angle="0"/>
|
||||
</Polygon.RenderTransform>
|
||||
</Polygon>
|
||||
|
||||
<!-- Texto de identificación -->
|
||||
<TextBlock x:Name="PumpLabel"
|
||||
Text="P"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontWeight="Bold"
|
||||
FontSize="16"
|
||||
Foreground="White"
|
||||
Margin="0,0,0,0"/>
|
||||
|
||||
<!-- Indicador de estado (LED) -->
|
||||
<Ellipse x:Name="StatusLED"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Fill="Red"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Margin="0,5,5,0"/>
|
||||
|
||||
<!-- Conexiones de entrada y salida -->
|
||||
<Rectangle x:Name="InletConnection"
|
||||
Width="10"
|
||||
Height="4"
|
||||
Fill="DarkSlateGray"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Margin="-5,0,0,0"/>
|
||||
|
||||
<Rectangle x:Name="OutletConnection"
|
||||
Width="10"
|
||||
Height="4"
|
||||
Fill="DarkSlateGray"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,-5,0"/>
|
||||
|
||||
<!-- Información de estado (opcional, visible en modo debug) -->
|
||||
<Border x:Name="StatusInfo"
|
||||
Background="Black"
|
||||
Opacity="0.8"
|
||||
CornerRadius="3"
|
||||
Visibility="Collapsed"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Bottom"
|
||||
Margin="5">
|
||||
<StackPanel Orientation="Vertical" Margin="3">
|
||||
<TextBlock x:Name="FlowText"
|
||||
Text="0.0 L/min"
|
||||
Foreground="White"
|
||||
FontSize="8"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock x:Name="PressureText"
|
||||
Text="0.0 bar"
|
||||
Foreground="White"
|
||||
FontSize="8"
|
||||
HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,225 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using CtrEditor.ObjetosSim;
|
||||
using CtrEditor.FuncionesBase;
|
||||
|
||||
namespace CtrEditor.ObjetosSim.HydraulicComponents
|
||||
{
|
||||
/// <summary>
|
||||
/// UserControl para la bomba hidráulica
|
||||
/// </summary>
|
||||
public partial class ucHydPump : UserControl, IDataContainer
|
||||
{
|
||||
public osBase? Datos { get; set; }
|
||||
public int zIndex_fromFrames { get; set; } = 0;
|
||||
|
||||
private Storyboard? _rotationAnimation;
|
||||
private bool _isHighlighted = false;
|
||||
|
||||
public ucHydPump()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
this.Unloaded += OnUnloaded;
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucLoaded();
|
||||
UpdateVisualState();
|
||||
}
|
||||
|
||||
private void OnUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucUnLoaded();
|
||||
}
|
||||
|
||||
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is osHydPump pump)
|
||||
{
|
||||
Datos = pump;
|
||||
pump.PropertyChanged += OnPumpPropertyChanged;
|
||||
UpdateVisualState();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPumpPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(osHydPump.IsRunning) ||
|
||||
e.PropertyName == nameof(osHydPump.SpeedRatio) ||
|
||||
e.PropertyName == nameof(osHydPump.PumpDirection) ||
|
||||
e.PropertyName == nameof(osHydPump.CurrentFlow) ||
|
||||
e.PropertyName == nameof(osHydPump.CurrentPressure))
|
||||
{
|
||||
UpdateVisualState();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actualiza el estado visual de la bomba
|
||||
/// </summary>
|
||||
private void UpdateVisualState()
|
||||
{
|
||||
if (Datos is not osHydPump pump) return;
|
||||
|
||||
try
|
||||
{
|
||||
Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
UpdateStatusLED(pump);
|
||||
UpdateRotationAnimation(pump);
|
||||
UpdateDirectionArrow(pump);
|
||||
UpdateStatusInfo(pump);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"Error updating pump visual state: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actualiza el LED de estado
|
||||
/// </summary>
|
||||
private void UpdateStatusLED(osHydPump pump)
|
||||
{
|
||||
if (pump.IsRunning && pump.SpeedRatio > 0)
|
||||
{
|
||||
StatusLED.Fill = new SolidColorBrush(Colors.LimeGreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusLED.Fill = new SolidColorBrush(Colors.Red);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actualiza la animación de rotación
|
||||
/// </summary>
|
||||
private void UpdateRotationAnimation(osHydPump pump)
|
||||
{
|
||||
_rotationAnimation?.Stop();
|
||||
|
||||
if (pump.IsRunning && pump.SpeedRatio > 0)
|
||||
{
|
||||
// Crear animación de rotación
|
||||
var rotateTransform = new RotateTransform();
|
||||
PumpBackground.RenderTransform = rotateTransform;
|
||||
PumpBackground.RenderTransformOrigin = new Point(0.5, 0.5);
|
||||
|
||||
var animation = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = 360,
|
||||
Duration = TimeSpan.FromSeconds(2.0 / pump.SpeedRatio), // Más rápido con mayor velocidad
|
||||
RepeatBehavior = RepeatBehavior.Forever
|
||||
};
|
||||
|
||||
_rotationAnimation = new Storyboard();
|
||||
Storyboard.SetTarget(animation, rotateTransform);
|
||||
Storyboard.SetTargetProperty(animation, new PropertyPath(RotateTransform.AngleProperty));
|
||||
_rotationAnimation.Children.Add(animation);
|
||||
_rotationAnimation.Begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
PumpBackground.RenderTransform = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actualiza la flecha de dirección
|
||||
/// </summary>
|
||||
private void UpdateDirectionArrow(osHydPump pump)
|
||||
{
|
||||
if (pump.PumpDirection == -1)
|
||||
{
|
||||
ArrowRotation.Angle = 180; // Invertir flecha
|
||||
DirectionArrow.Fill = new SolidColorBrush(Colors.Orange);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrowRotation.Angle = 0;
|
||||
DirectionArrow.Fill = new SolidColorBrush(Colors.DarkBlue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actualiza la información de estado
|
||||
/// </summary>
|
||||
private void UpdateStatusInfo(osHydPump pump)
|
||||
{
|
||||
FlowText.Text = $"{pump.CurrentFlowLMin:F1} L/min";
|
||||
PressureText.Text = $"{pump.CurrentPressureBar:F2} bar";
|
||||
|
||||
// Mostrar información si hay datos relevantes
|
||||
if (Math.Abs(pump.CurrentFlow) > 0.001 || Math.Abs(pump.CurrentPressure) > 1000)
|
||||
{
|
||||
StatusInfo.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusInfo.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDataContainer Implementation
|
||||
|
||||
public void Highlight(bool state)
|
||||
{
|
||||
_isHighlighted = state;
|
||||
|
||||
if (state)
|
||||
{
|
||||
PumpBackground.Stroke = new SolidColorBrush(Colors.Yellow);
|
||||
PumpBackground.StrokeThickness = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
PumpBackground.Stroke = new SolidColorBrush(Colors.DarkSlateGray);
|
||||
PumpBackground.StrokeThickness = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseEnter(e);
|
||||
if (!_isHighlighted)
|
||||
{
|
||||
// Mostrar información al pasar el mouse
|
||||
StatusInfo.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
if (!_isHighlighted && Datos is osHydPump pump)
|
||||
{
|
||||
// Ocultar información si no hay datos relevantes
|
||||
if (Math.Abs(pump.CurrentFlow) < 0.001 && Math.Abs(pump.CurrentPressure) < 1000)
|
||||
{
|
||||
StatusInfo.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ZIndexEnum ZIndex_Base()
|
||||
{
|
||||
return ZIndexEnum.Estaticos;
|
||||
}
|
||||
|
||||
~ucHydPump()
|
||||
{
|
||||
_rotationAnimation?.Stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<UserControl x:Class="CtrEditor.ObjetosSim.HydraulicComponents.ucPumpExample"
|
||||
<UserControl x:Class="CtrEditor.ObjetosSim.HydraulicComponents.ucHydPump"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
/// <summary>
|
||||
/// UserControl para la bomba hidráulica de ejemplo
|
||||
/// </summary>
|
||||
public partial class ucPumpExample : UserControl, IDataContainer
|
||||
public partial class ucHydPump : UserControl, IDataContainer
|
||||
{
|
||||
public osBase? Datos { get; set; }
|
||||
public int zIndex_fromFrames { get; set; } = 0;
|
||||
|
@ -20,7 +20,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
private Storyboard? _rotationAnimation;
|
||||
private bool _isHighlighted = false;
|
||||
|
||||
public ucPumpExample()
|
||||
public ucHydPump()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
|
@ -41,7 +41,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
|
||||
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is osPumpExample pump)
|
||||
if (DataContext is osHydPump pump)
|
||||
{
|
||||
Datos = pump;
|
||||
pump.PropertyChanged += OnPumpPropertyChanged;
|
||||
|
@ -51,11 +51,11 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
|
||||
private void OnPumpPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(osPumpExample.IsRunning) ||
|
||||
e.PropertyName == nameof(osPumpExample.SpeedRatio) ||
|
||||
e.PropertyName == nameof(osPumpExample.PumpDirection) ||
|
||||
e.PropertyName == nameof(osPumpExample.CurrentFlow) ||
|
||||
e.PropertyName == nameof(osPumpExample.CurrentPressure))
|
||||
if (e.PropertyName == nameof(osHydPump.IsRunning) ||
|
||||
e.PropertyName == nameof(osHydPump.SpeedRatio) ||
|
||||
e.PropertyName == nameof(osHydPump.PumpDirection) ||
|
||||
e.PropertyName == nameof(osHydPump.CurrentFlow) ||
|
||||
e.PropertyName == nameof(osHydPump.CurrentPressure))
|
||||
{
|
||||
UpdateVisualState();
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
/// </summary>
|
||||
private void UpdateVisualState()
|
||||
{
|
||||
if (Datos is not osPumpExample pump) return;
|
||||
if (Datos is not osHydPump pump) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
/// <summary>
|
||||
/// Actualiza el LED de estado
|
||||
/// </summary>
|
||||
private void UpdateStatusLED(osPumpExample pump)
|
||||
private void UpdateStatusLED(osHydPump pump)
|
||||
{
|
||||
if (pump.IsRunning && pump.SpeedRatio > 0)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
/// <summary>
|
||||
/// Actualiza la animación de rotación
|
||||
/// </summary>
|
||||
private void UpdateRotationAnimation(osPumpExample pump)
|
||||
private void UpdateRotationAnimation(osHydPump pump)
|
||||
{
|
||||
_rotationAnimation?.Stop();
|
||||
|
||||
|
@ -136,7 +136,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
/// <summary>
|
||||
/// Actualiza la flecha de dirección
|
||||
/// </summary>
|
||||
private void UpdateDirectionArrow(osPumpExample pump)
|
||||
private void UpdateDirectionArrow(osHydPump pump)
|
||||
{
|
||||
if (pump.PumpDirection == -1)
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
/// <summary>
|
||||
/// Actualiza la información de estado
|
||||
/// </summary>
|
||||
private void UpdateStatusInfo(osPumpExample pump)
|
||||
private void UpdateStatusInfo(osHydPump pump)
|
||||
{
|
||||
FlowText.Text = $"{pump.CurrentFlowLMin:F1} L/min";
|
||||
PressureText.Text = $"{pump.CurrentPressureBar:F2} bar";
|
||||
|
@ -202,7 +202,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
if (!_isHighlighted && Datos is osPumpExample pump)
|
||||
if (!_isHighlighted && Datos is osHydPump pump)
|
||||
{
|
||||
// Ocultar información si no hay datos relevantes
|
||||
if (Math.Abs(pump.CurrentFlow) < 0.001 && Math.Abs(pump.CurrentPressure) < 1000)
|
||||
|
@ -217,7 +217,7 @@ namespace CtrEditor.ObjetosSim.HydraulicComponents
|
|||
return ZIndexEnum.Estaticos;
|
||||
}
|
||||
|
||||
~ucPumpExample()
|
||||
~ucHydPump()
|
||||
{
|
||||
_rotationAnimation?.Stop();
|
||||
}
|
||||
|
|
|
@ -1168,14 +1168,6 @@ namespace CtrEditor.Simulacion
|
|||
return botella;
|
||||
}
|
||||
|
||||
public simPumpExample AddPumpExample(Vector3 dimensions, Vector2 position, float mass)
|
||||
{
|
||||
var pump = new simPumpExample(simulation, _deferredActions, dimensions, position, mass);
|
||||
Cuerpos.Add(pump);
|
||||
RegisterObjectHandle(pump);
|
||||
return pump;
|
||||
}
|
||||
|
||||
public simTransporte AddRectangle(float width, float height, Vector2 position, float angle)
|
||||
{
|
||||
var transporte = new simTransporte(simulation, _deferredActions, width, height, position, angle, this);
|
||||
|
|
Loading…
Reference in New Issue