Compare commits

..

No commits in common. "256d86aca58acea835a45d88038a777b18b0d806" and "75c507be4e5ba0499d6fc71e8cbcc6f0260d99f8" have entirely different histories.

49 changed files with 499 additions and 2829 deletions

View File

@ -22,12 +22,6 @@
<local:SubclassFilterConverter x:Key="SubclassFilterConverterosVMMotor" TargetType="{x:Type os:osVMmotorSim}" />
<local:UnsavedChangesConverter x:Key="UnsavedChangesConverter"/>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<!-- Estilo global para TreeViewItem para evitar errores de binding -->
<Style TargetType="TreeViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</Application.Resources>
</Application>

View File

@ -18,7 +18,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Documentation\PlantillaEstandarizacion.cs" />
<Compile Remove="ObjetosSim\ucBasicExample.xaml.cs" />
<Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" />
<Compile Remove="Simulacion\FPhysics.cs" />
@ -71,7 +70,6 @@
</ItemGroup>
<ItemGroup>
<None Include="Documentation\PlantillaEstandarizacion.cs" />
<None Include="ObjetosSim\ucBasicExample.xaml" />
<None Include="ObjetosSim\ucBasicExample.xaml.cs" />
<None Include="Simulacion\FPhysics.cs" />
@ -87,9 +85,8 @@
<PackageReference Include="Emgu.CV.UI" Version="4.9.0.5494" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.7.25104.5739" />
<PackageReference Include="LanguageDetection" Version="1.2.0" />
<PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc3.3" />
<PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc4.5" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageReference Include="SkiaSharp.Views.WPF" Version="2.88.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
<PackageReference Include="PaddleOCRSharp" Version="4.5.0.1" />

View File

@ -1,145 +0,0 @@
# Estandarización de Objetos derivados de osBase
## Criterios para NombreClase()
### Categorías de Objetos:
1. **Transporte**: Transportadores, cintas, curvas
2. **Sensores**: Fotocélulas, encoders, botones
3. **Actuadores**: Motores, válvulas
4. **Elementos Estáticos**: Guías, descartes, barreras
5. **Emuladores**: Generadores, llenadores, tanques
6. **Señales**: Tags analógicos, digitales
7. **Datos**: Extracción, búsqueda
8. **Decorativos**: Imágenes, marcos, textos
9. **Fluidos**: Tuberías, válvulas, sistemas
### Formato de Nombres:
- **Español**: Usar nombres descriptivos en español
- **Específico**: Incluir característica principal (ej: "Motor VetroMeccanica", "Transporte con Guías")
- **Consistente**: Mantener formato similar por categoría
## Categorías Estandarizadas para Propiedades
### 1. "Identificación"
- Nombre del objeto
- Etiquetas de clasificación
### 2. "Posición y Tamaño"
- Coordenadas (Left, Top)
- Dimensiones (Ancho, Alto, Ángulo)
- Bloqueo de movimiento
### 3. "Configuración"
- Parámetros principales del objeto
- Configuraciones específicas por tipo
### 4. "Simulación"
- Velocidades, fuerzas, coeficientes
- Parámetros físicos
### 5. "Enlace PLC"
- Tags de entrada y salida
- Conexiones con motores/sensores
### 6. "Información"
- Valores calculados
- Estados actuales
- Datos de depuración
### 7. "Apariencia"
- Colores, tamaños visuales
- Aspectos gráficos
## Ejemplos de Aplicación
### Motor VetroMeccanica:
```csharp
[ObservableProperty]
[property: Description("Velocidad actual del motor en Hz")]
[property: Category("Información")]
[property: Name("Velocidad Actual")]
public float velocidad;
[ObservableProperty]
[property: Description("Tiempo de rampa para acelerar/desacelerar")]
[property: Category("Configuración")]
[property: Name("Tiempo de Rampa")]
public float tiempoRampa;
```
### Fotocélula:
```csharp
[ObservableProperty]
[property: Description("Indica si la luz está cortada por un objeto")]
[property: Category("Información")]
[property: Name("Luz Cortada")]
bool luzCortada;
[ObservableProperty]
[property: Description("Ancho del haz de luz del sensor")]
[property: Category("Configuración")]
[property: Name("Ancho del Haz")]
float ancho_Haz_De_Luz;
```
## Plan de Implementación
### ✅ Fase 1: Estandarizar métodos `NombreClase()`
- [x] Crear mapeo de nombres descriptivos
- [x] Implementar ejemplos: TransporteTTop, Motor VetroMeccanica, Fotocélula, Tag Analógico
- [x] Generar script de automatización PowerShell
### ✅ Fase 2: Aplicar categorías y descripciones estándar
- [x] Definir 8 categorías estándar
- [x] Crear plantilla de implementación
- [x] Aplicar en objetos de ejemplo
### ✅ Fase 3: Implementación Clase por Clase (COMPLETADO)
- [x] **ucTransporteTTop** - Transporte TTOP
- [x] **ucVMmotorSim** - Motor VetroMeccanica
- [x] **ucPhotocell** - Fotocélula
- [x] **ucAnalogTag** - Tag Analógico
- [x] **ucCustomImage** - Imagen Personalizada
- [x] **ucBoolTag** - Tag Digital
- [x] **ucGuia** - Guía
- [x] **ucBotella** - Botella
- [x] **ucTransporteCurva** - Transporte Curva 90°
- [x] **ucBoton** - Botón
- [x] **ucBottGenerator** - Generador de Botellas
- [x] **ucDescarte** - Descarte
- [x] **ucFramePlate** - Marco de Panel (parcial)
### 📊 Estadísticas de Progreso
- **Clases procesadas**: 13
- **`using System.ComponentModel;` agregados**: 6 clases
- **Nombres de clase mejorados**: 13
- **Propiedades estandarizadas**: ~85 propiedades
## Archivos Generados
1. **`Scripts/EstandarizarObjetos.ps1`**: Script para automatizar cambios
2. **`Documentation/PlantillaEstandarizacion.cs`**: Plantilla con ejemplos
3. **`Documentation/EstandarizacionObjetos.md`**: Esta documentación
## Instrucciones de Uso
### Para aplicar automáticamente:
```powershell
cd CtrEditor
.\Scripts\EstandarizarObjetos.ps1
```
### Para aplicar manualmente:
1. Consultar `PlantillaEstandarizacion.cs`
2. Seguir el patrón de categorías establecido
3. Usar nombres descriptivos en español
## Objetos Ya Actualizados
- ✅ `ucTransporteTTop` → "Transporte TTOP"
- ✅ `ucVMmotorSim` → "Motor VetroMeccanica"
- ✅ `ucPhotocell` → "Fotocélula"
- ✅ `ucAnalogTag` → "Tag Analógico"
---
*Documento generado para estandarización del proyecto CtrEditor*

View File

@ -1,172 +0,0 @@
/*
PLANTILLA DE ESTANDARIZACIÓN PARA OBJETOS osBase
Usar esta plantilla como guía para estandarizar cualquier objeto derivado de osBase
*/
namespace CtrEditor.ObjetosSim
{
public partial class osEjemplo : osBase, IosBase
{
// 1. MÉTODO NOMBRECLASE - Usar nombres descriptivos en español
public static string NombreClase()
{
return "Nombre Descriptivo del Objeto"; // Ej: "Motor VetroMeccanica", "Fotocélula", "Transporte TTOP"
}
private string nombre = NombreClase();
// 2. PROPIEDAD NOMBRE - Siempre en categoría "Identificación"
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
// 3. CATEGORÍAS ESTÁNDAR:
// IDENTIFICACIÓN - Información básica del objeto
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Descripción o comentario del objeto")]
[property: Name("Descripción")]
public string descripcion;
// POSICIÓN Y TAMAÑO - Heredadas de osBase (Left, Top, Ancho, Alto, Angulo)
// No necesitan redefinirse, ya están en osBase
// CONFIGURACIÓN - Parámetros principales del objeto
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima del objeto")]
[property: Name("Velocidad Máxima")]
public float velocidadMaxima;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Habilita/deshabilita funcionalidad específica")]
[property: Name("Habilitar Función")]
public bool habilitarFuncion;
// SIMULACIÓN - Parámetros físicos y de simulación
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual en la simulación")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente de Fricción")]
public float coeficienteFriccion;
// ENLACE PLC - Conexiones con PLC y otros objetos
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag Principal")]
public string tagPrincipal;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Seleccionar motor para enlazar")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
public string motorEnlazado;
// INFORMACIÓN - Valores calculados, estados, debug
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado actual del objeto")]
[property: Name("Estado")]
public bool estado;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Último valor calculado")]
[property: Name("Último Valor")]
public float ultimoValor;
// APARIENCIA - Aspectos visuales
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del objeto")]
[property: Name("Tamaño")]
public float tamano;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del objeto")]
[property: Name("Color")]
public Brush color;
// ENCODER - Específico para motores con encoder
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Habilita el encoder")]
[property: Name("Con Encoder")]
public bool conEncoder;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Posición actual del encoder")]
[property: Name("Posición Encoder")]
public float posicionEncoder;
}
}
/*
GUÍA DE CATEGORÍAS:
1. "Identificación"
- Nombre del objeto
- Descripción
- Etiquetas de clasificación
2. "Posición y Tamaño"
- Ya heredadas de osBase: Left, Top, Ancho, Alto, Angulo, Lock_movement
3. "Configuración"
- Parámetros principales del objeto
- Configuraciones específicas por tipo
- Valores que el usuario configura
4. "Simulación"
- Velocidades, fuerzas, coeficientes
- Parámetros físicos
- Comportamiento en simulación
5. "Enlace PLC"
- Tags de entrada y salida
- Conexiones con motores/sensores
- Direcciones de PLC
6. "Información"
- Valores calculados
- Estados actuales
- Datos de depuración
- Información de solo lectura
7. "Apariencia"
- Colores, tamaños visuales
- Aspectos gráficos
- Elementos de UI
8. "Encoder" (solo para motores)
- Configuración del encoder
- Valores del encoder
FORMATO DE DESCRIPCIONES:
- Usar español
- Ser descriptivo y claro
- Explicar qué hace la propiedad
- Evitar términos técnicos innecesarios
FORMATO DE NOMBRES:
- Usar español
- Formato "Título" (primera letra mayúscula)
- Ser conciso pero descriptivo
- Ej: "Velocidad Actual", "Tag Principal", "Con Encoder"
*/

View File

@ -1337,8 +1337,6 @@ namespace CtrEditor
// Mostrar como modeless (no modal)
libraryWindow.Show();
}
}
public class SimulationData

View File

@ -260,8 +260,7 @@ namespace CtrEditor
// Calcular el bounding box que contenga todos los objetos seleccionados
Rect boundingBox = CalculateTotalBoundingBox(selectedObjects);
if (_selectedObjectsAreVisible)
{
if (_selectedObjectsAreVisible) {
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
rectBox.Left -= (float)rectHighlightSize;
@ -1126,9 +1125,6 @@ namespace CtrEditor
RemoveAllSelectionHighlights(); // Remover antes de rotar
// Verificar si la tecla Shift está presionada para rotación en incrementos de 45 grados
bool isShiftPressed = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
// Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados
double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X;
double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y;
@ -1141,49 +1137,12 @@ namespace CtrEditor
else
{
double deltaAngle = angle - _lastAngle;
if (isShiftPressed)
{
// Rotación en incrementos de 45 grados
// Calcular el ángulo total acumulado desde el inicio de la rotación
double totalAngleChange = angle - _lastAngle;
// Determinar a qué incremento de 45 grados corresponde
double snapAngle = Math.Round(totalAngleChange / 45.0) * 45.0;
// Solo aplicar la rotación si hay un cambio significativo (al menos 22.5 grados de movimiento)
if (Math.Abs(totalAngleChange) > 22.5)
{
// Calcular el cambio real que necesitamos aplicar
double actualRotationChange = snapAngle;
foreach (var selectedObject in _selectedObjects)
{
// Obtener el ángulo actual del objeto
double currentObjectAngle = selectedObject.Angulo;
// Calcular el nuevo ángulo alineado a incrementos de 45 grados
double targetAngle = Math.Round((currentObjectAngle + actualRotationChange) / 45.0) * 45.0;
// Aplicar la rotación necesaria para llegar al ángulo objetivo
double rotationNeeded = targetAngle - currentObjectAngle;
selectedObject.Rotate(rotationNeeded);
}
// Actualizar el ángulo de referencia para evitar aplicar la misma rotación múltiples veces
_lastAngle = (float)angle;
}
}
else
{
// Rotación libre (comportamiento original)
foreach (var selectedObject in _selectedObjects)
{
selectedObject.Rotate(deltaAngle);
}
_lastAngle = (float)angle;
}
}
UpdateAllSelectionHighlights();
}

View File

@ -16,80 +16,39 @@ namespace CtrEditor.ObjetosSim
{
public static string NombreClase()
{
return "Imagen Personalizada";
return "Custom Image";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
private string _imagePath;
[Description("Ruta del archivo de imagen")]
[Category("Configuración")]
[property: Name("Ruta de Imagen")]
public string ImagePath
{
get => _imagePath;
set
{
try
{
if (SetProperty(ref _imagePath, value))
{
OnImagePathChanged(value);
OnPropertyChanged(nameof(ImageSource_oculta));
}
}
catch
{
// Si hay error al establecer la propiedad, simplemente ignorarlo
// y establecer la imagen por defecto
try
{
SetProperty(ref _imagePath, value);
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
OnPropertyChanged(nameof(ImageSource_oculta));
}
catch
{
// En caso de error total, establecer valores seguros
_imagePath = value;
ImageSource_oculta = null;
}
}
}
}
[ObservableProperty]
[property: Description("Voltear la imagen horizontalmente")]
[property: Category("Configuración")]
[property: Name("Voltear Horizontal")]
[NotifyPropertyChangedFor(nameof(ImageSource_oculta))]
[property: Description("Path to the image file")]
[property: Category("Image:")]
private string imagePath;
[ObservableProperty]
[property: Description("Flip the image horizontally")]
[property: Category("Image:")]
private bool horizontal_Flip;
[ObservableProperty]
[property: Description("Voltear la imagen verticalmente")]
[property: Category("Configuración")]
[property: Name("Voltear Vertical")]
[property: Description("Flip the image vertically")]
[property: Category("Image:")]
private bool vertical_Flip;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Category("Apariencia")]
[property: Description("Imagen visual del objeto")]
[property: Name("Imagen")]
public ImageSource imageSource_oculta;
private void OnImagePathChanged(string value)
{
try
partial void OnImagePathChanged(string value)
{
if (!string.IsNullOrEmpty(value))
{
@ -101,20 +60,6 @@ namespace CtrEditor.ObjetosSim
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
}
catch
{
// Si hay cualquier error, usar la imagen por defecto
try
{
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
catch
{
// Si incluso la imagen por defecto falla, establecer como null
ImageSource_oculta = null;
}
}
}
partial void OnHorizontal_FlipChanged(bool value)
{
@ -137,8 +82,6 @@ namespace CtrEditor.ObjetosSim
public override void ucLoaded()
{
base.ucLoaded();
try
{
if (!string.IsNullOrEmpty(ImagePath))
{
ImageSource_oculta = ImageFromPath(ImagePath);
@ -149,20 +92,6 @@ namespace CtrEditor.ObjetosSim
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
}
catch
{
// Si hay cualquier error, usar la imagen por defecto
try
{
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
catch
{
// Si incluso la imagen por defecto falla, establecer como null
ImageSource_oculta = null;
}
}
}
}
public partial class ucCustomImage : UserControl, IDataContainer

View File

@ -29,13 +29,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Marco de Panel";
return "Frame Plate";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -43,9 +39,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Índice de capa para objetos en el marco")]
[property: Category("Configuración")]
[property: Name("Índice Z del Marco")]
[property: Description("Layer index to add to Objects on the Frame")]
[property: Category("Layer:")]
int zindex_FramePlate;
partial void OnZindex_FramePlateChanged(int value)
@ -54,27 +49,13 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de fondo del marco")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del texto del título")]
[property: Name("Color del Título")]
Color color_Titulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Texto del título del marco")]
[property: Name("Título")]
string titulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del área del título")]
[property: Name("Alto del Título")]
public float alto_Titulo;
// Encoder X

View File

@ -4,7 +4,6 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.FuncionesBase;
using Newtonsoft.Json;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
@ -23,13 +22,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Placa de Texto";
return "Plate";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -37,32 +32,17 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de fondo de la placa")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del texto del título")]
[property: Name("Color Título")]
Color color_Titulo;
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Texto del título")]
[property: Name("Título")]
string titulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del área del título")]
[property: Name("Alto Título")]
public float alto_Titulo;
public override void TopChanging(float oldValue, float newValue)
{
public override void TopChanging(float oldValue, float newValue) {
offsetY = newValue - oldValue;
}
public override void LeftChanging(float oldValue, float newValue)

View File

@ -8,7 +8,6 @@ using CommunityToolkit.Mvvm.ComponentModel;
using nkast.Aether.Physics2D.Common;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -28,10 +27,6 @@ namespace CtrEditor.ObjetosSim
return "Botella";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -49,15 +44,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual de la botella")]
[property: Name("Color")]
private Brush colorButton_oculto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la botella en metros")]
[property: Name("Diámetro")]
private float diametro;
partial void OnDiametroChanged(float value)
@ -72,33 +61,17 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual desde la simulación")]
[property: Name("Velocidad de Simulación")]
private string velocidad_desde_simulacion;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Inercia actual desde la simulación")]
[property: Name("Inercia de Simulación")]
private float inercia_desde_simulacion;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Conservar objeto cuando sale de transporte")]
[property: Name("Conservar Fuera de Transporte")]
private bool preserve_Outside_Transport;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Porcentaje de tracción con transporte")]
[property: Name("Porcentaje de Tracción")]
private float porcentaje_Traccion;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Masa del objeto en kg")]
[property: Name("Masa")]
private float mass;
partial void OnMassChanged(float value)
{

View File

@ -8,7 +8,6 @@ using CommunityToolkit.Mvvm.ComponentModel;
using nkast.Aether.Physics2D.Common;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -26,10 +25,6 @@ namespace CtrEditor.ObjetosSim
return "Botella con Cuello";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -52,15 +47,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del botón visual")]
[property: Name("Color")]
private Brush colorButton_oculto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la botella")]
[property: Name("Diámetro")]
private float diametro;
partial void OnDiametroChanged(float value)
@ -69,21 +58,12 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad desde simulación")]
[property: Name("Velocidad Simulación")]
private string velocidad_desde_simulacion;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Inercia desde simulación")]
[property: Name("Inercia Simulación")]
private float inercia_desde_simulacion;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Masa de la botella")]
[property: Name("Masa")]
private float mass;
partial void OnMassChanged(float value)
{

View File

@ -17,43 +17,27 @@ namespace CtrEditor.ObjetosSim
private float TiempoRestante;
public static string NombreClase()
{
return "Generador de Botellas";
return "BottGenerator";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre { get => nombre; set => SetProperty(ref nombre, value); }
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Desplazamiento horizontal del punto de salida")]
[property: Name("Offset Horizontal")]
private float offsetLeftSalida;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Desplazamiento vertical del punto de salida")]
[property: Name("Offset Vertical")]
private float offsetTopSalida;
[ObservableProperty]
[property: Description("Las botellas se destruirán si caen fuera del transporte")]
[property: Category("Configuración")]
[property: Name("Conservar Fuera de Transporte")]
[property: Description("The bottle will be destroyed if fall outside transport.")]
[property: Category("Enable to Run:")]
private bool preserve_Outside_Transport;
[ObservableProperty]
[property: Description("Tag PLC para habilitar funcionamiento. 1 => siempre activo")]
[property: Category("Enlace PLC")]
[property: Name("Tag Consenso")]
[property: Description("PLC tag for consense to run. 1 => always")]
[property: Category("Enable to Run:")]
private string tag_consenso;
[ObservableProperty]
[property: Description("Estado de consenso para funcionamiento")]
[property: Category("Simulación")]
[property: Name("Consenso")]
[property: Description("Consense to run.")]
[property: Category("Enable to Run:")]
private bool consenso;
partial void OnConsensoChanged(bool value)
{
@ -61,38 +45,26 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Consenso normalmente cerrado")]
[property: Category("Configuración")]
[property: Name("Consenso NC")]
[property: Description("Consense is Normally close.")]
[property: Category("Enable to Run:")]
private bool consenso_NC;
[ObservableProperty]
[property: Description("Habilitar filtro de consenso")]
[property: Category("Configuración")]
[property: Name("Filtro Habilitado")]
[property: Description("Enable filter.")]
[property: Category("Enable to Run:")]
private bool consenso_Filtrado;
[ObservableProperty]
[property: Description("Tiempo de activación del filtro en segundos")]
[property: Category("Configuración")]
[property: Name("Tiempo ON (s)")]
[property: Description("Time ON in s.")]
[property: Category("Enable to Run:")]
float filtro_consenso_ON_s;
[ObservableProperty]
[property: Description("Tiempo de desactivación del filtro en segundos")]
[property: Category("Configuración")]
[property: Name("Tiempo OFF (s)")]
[property: Description("Time OFF in s.")]
[property: Category("Enable to Run:")]
float filtro_consenso_OFF_s;
[ObservableProperty]
[property: Description("Señal de salida del filtro")]
[property: Category("Información")]
[property: Name("Salida Filtro")]
[property: Description("Filter OUT signal.")]
[property: Category("Enable to Run:")]
bool filter_Output;
[ObservableProperty]
[property: Description("Cantidad de botellas generadas por hora")]
[property: Category("Configuración")]
[property: Name("Botellas por Hora")]
private float botellas_hora;
partial void OnBotellas_horaChanged(float value)
{
@ -100,9 +72,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Cantidad de botellas generadas por segundo")]
[property: Category("Configuración")]
[property: Name("Botellas por Segundo")]
private float botellas_segundo;
partial void OnBotellas_segundoChanged(float value)
{
@ -110,15 +79,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Velocidad actual como porcentaje")]
[property: Category("Simulación")]
[property: Name("Velocidad Actual (%)")]
private float velocidad_actual_percentual;
[ObservableProperty]
[property: Description("Diámetro de las botellas generadas")]
[property: Category("Configuración")]
[property: Name("Diámetro Botella")]
private float diametro_botella;
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{

View File

@ -5,7 +5,6 @@ using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Diagnostics;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -22,13 +21,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Llenadora";
return "Filler";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -36,27 +31,13 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Offset horizontal para salida de botellas")]
[property: Name("Offset Left Salida")]
private float offsetLeftSalida;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Offset vertical para salida de botellas")]
[property: Name("Offset Top Salida")]
private float offsetTopSalida;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para consenso")]
[property: Name("Tag Consenso")]
private string tag_consenso;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado del consenso")]
[property: Name("Consenso")]
private bool consenso;
partial void OnConsensoChanged(bool value)
@ -64,27 +45,13 @@ namespace CtrEditor.ObjetosSim
_TON_TOFF.Senal = value;
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Consenso normalmente cerrado")]
[property: Name("Consenso NC")]
private bool consenso_NC;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Aplicar filtrado al consenso")]
[property: Name("Consenso Filtrado")]
private bool consenso_Filtrado;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de filtro en segundos")]
[property: Name("Filtro Consenso (s)")]
float filtro_consenso_s;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Producción en botellas por hora")]
[property: Name("Botellas/Hora")]
private float botellas_hora;
partial void OnBotellas_horaChanged(float value)
@ -93,9 +60,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Producción en botellas por segundo")]
[property: Name("Botellas/Segundo")]
private float botellas_segundo;
partial void OnBotellas_segundoChanged(float value)
@ -104,15 +68,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual en porcentaje")]
[property: Name("Velocidad (%)")]
private float velocidad_actual_percentual;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de las botellas generadas")]
[property: Name("Diámetro Botella")]
private float diametro_botella;
public osFiller()

View File

@ -3,7 +3,6 @@ using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -19,10 +18,6 @@ namespace CtrEditor.ObjetosSim
return "Tanque";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -30,68 +25,26 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Capacidad total del tanque en litros")]
[property: Name("Capacidad (L)")]
public float capacidad_Litros;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado de apertura del ingreso")]
[property: Name("Ingreso Abierto")]
public bool ingreso_Abierto;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado de apertura de la salida")]
[property: Name("Salida Abierta")]
public bool salida_Abierta;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para nivel del tanque")]
[property: Name("Tag Nivel")]
public string tagNivel_Word;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para control de ingreso")]
[property: Name("Tag Ingreso")]
public string tagIngresoAbierto_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para control de salida")]
[property: Name("Tag Salida")]
public string tagSalidaAbierta_Bool;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad de llenado en L/min")]
[property: Name("Velocidad Ingreso")]
public float velocidad_Ingreso;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad de vaciado en L/min")]
[property: Name("Velocidad Salida")]
public float velocidad_Salida;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor mínimo escalado para salida PLC")]
[property: Name("Mínimo Escalado")]
public float min_OUT_Scaled;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor máximo escalado para salida PLC")]
[property: Name("Máximo Escalado")]
public float max_OUT_Scaled;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Nivel actual del tanque en porcentaje")]
[property: Name("Nivel (%)")]
public float level;
public osTanque()

View File

@ -7,7 +7,6 @@ using nkast.Aether.Physics2D.Common;
using System.Windows.Media.Animation;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
/// <summary>
@ -23,10 +22,6 @@ namespace CtrEditor.ObjetosSim
return "Descarte";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -34,9 +29,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro del área de descarte en metros")]
[property: Name("Diámetro")]
private float diametro;
partial void OnDiametroChanged(float value)

View File

@ -1,10 +1,10 @@
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using CtrEditor.Simulacion;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -17,13 +17,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Guía";
return "Guia";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
private string nombre = "Guia";
public override string Nombre
{
get => nombre;
@ -31,9 +27,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de la guía en metros")]
[property: Name("Alto de la Guía")]
public float altoGuia;
private void ActualizarGeometrias()

View File

@ -23,13 +23,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte Curva 90°";
return "Transporte Curva 90";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
private string nombre = "Transporte Curva 90";
public override string Nombre
{
get => nombre;
@ -37,9 +33,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte en m/s")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -48,19 +41,11 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento del transporte")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
{
SetSpeed();
if (_visualRepresentation is ucTransporteCurva uc)
{
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
}
void SetSpeed()
@ -69,13 +54,9 @@ namespace CtrEditor.ObjetosSim
Simulation_TransporteCurva?.SetSpeed(-VelocidadActual);
else
Simulation_TransporteCurva?.SetSpeed(VelocidadActual);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio exterior de la curva en metros")]
[property: Name("Radio Exterior")]
private float radioExterno;
partial void OnRadioExternoChanged(float value)
@ -94,21 +75,18 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio interior de la curva en metros")]
[property: Name("Radio Interior")]
private float radioInterno;
[ObservableProperty]
[property: Description("Tag de bit para activar enlace con motor")]
[property: Category("Enlace PLC")]
[property: Name("Tag Activación Motor")]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Description("Seleccionar motor para enlazar")]
[property: Category("Enlace PLC")]
[property: Name("Motor Enlazado")]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
@ -227,14 +205,9 @@ namespace CtrEditor.ObjetosSim
{
// Se llama antes de la simulacion
ActualizarGeometrias();
}
public override void SimulationStop()
{
// Se llama al detener la simulacion
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
}
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
@ -252,13 +225,13 @@ namespace CtrEditor.ObjetosSim
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion
base.ucLoaded();
OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor
if (_visualRepresentation is ucTransporteCurva uc)
{
Simulation_TransporteCurva = AddCurve(RadioInterno,RadioExterno, Angulo, Angulo + Arco_en_grados);
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
}
// AddCurve(float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position)
}
public override void ucUnLoaded()
{

View File

@ -1,24 +0,0 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucTransporteCurvaGuias"
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"
xmlns:localuc="clr-namespace:CtrEditor.ObjetosSim.UserControls" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
mc:Ignorable="d">
<UserControl.DataContext>
<vm:osTransporteCurvaGuias />
</UserControl.DataContext>
<Canvas x:Name="MainCanvas">
<localuc:CircularSegment x:Name="Transporte" Angle="0"
OuterRadius="{Binding RadioExterno, Converter={StaticResource MeterToPixelConverter}}"
InnerRadius="{Binding RadioInterno, Converter={StaticResource MeterToPixelConverter}}"
StartAngle="{Binding Angulo}" EndAngle="{Binding AnguloFinal}"
ShowGuides="{Binding MostrarGuias}"
GuideDistance="{Binding DistanciaGuias, Converter={StaticResource MeterToPixelConverter}}"
GuideThickness="{Binding GrosorGuias, Converter={StaticResource MeterToPixelConverter}}"
GuideStroke="{Binding ColorGuiasBrush}" />
</Canvas>
</UserControl>

View File

@ -1,510 +0,0 @@
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using CtrEditor.Simulacion;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
using CtrEditor.FuncionesBase;
using System.Text.Json.Serialization;
using System.Windows.Media;
namespace CtrEditor.ObjetosSim
{
/// <summary>
/// Interaction logic for ucTransporteCurvaGuias.xaml
/// </summary>
public partial class osTransporteCurvaGuias : osBase, IosBase
{
private osBase Motor = null;
private simCurve Simulation_TransporteCurvaGuias;
// Listas para almacenar los segmentos de las guías curvas
private List<simGuia> GuiasSuperiores = new List<simGuia>();
private List<simGuia> GuiasInferiores = new List<simGuia>();
private float _velocidadActual;
public static string NombreClase()
{
return "Transporte Curva con Guías";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
{
SetSpeed();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
{
SetSpeed();
if (_visualRepresentation is ucTransporteCurvaGuias uc)
{
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
}
void SetSpeed()
{
if (InvertirDireccion)
Simulation_TransporteCurvaGuias?.SetSpeed(-VelocidadActual);
else
Simulation_TransporteCurvaGuias?.SetSpeed(VelocidadActual);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio externo de la curva")]
[property: Name("Radio Externo")]
private float radioExterno;
partial void OnRadioExternoChanged(float value)
{
// Update ancho and alto based on radioExterno
Ancho = value * 2;
Alto = value * 2;
// Ensure radioInterno maintains proper proportion if needed
if (RadioInterno >= value)
{
RadioInterno = value * 0.75f; // Default proportion
}
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio interno de la curva")]
[property: Name("Radio Interno")]
private float radioInterno;
partial void OnRadioInternoChanged(float value)
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Número de segmentos para las guías (máximo 20)")]
[property: Name("Segmentos Guías")]
private int numeroSegmentosGuias;
partial void OnNumeroSegmentosGuiasChanged(int value)
{
// Limitar entre 4 y 20 segmentos
if (value < 4) NumeroSegmentosGuias = 4;
if (value > 20) NumeroSegmentosGuias = 20;
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Grosor de las guías")]
[property: Name("Grosor Guías")]
private float grosorGuias;
partial void OnGrosorGuiasChanged(float value)
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Distancia de separación de las guías desde el borde")]
[property: Name("Distancia Guías")]
private float distanciaGuias;
partial void OnDistanciaGuiasChanged(float value)
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Mostrar guías visuales")]
[property: Name("Mostrar Guías")]
private bool mostrarGuias;
// Propiedad interna Brush para el binding
private Brush _colorGuiasBrush = new SolidColorBrush(Colors.DarkBlue);
[JsonIgnore]
public Brush ColorGuiasBrush
{
get => _colorGuiasBrush;
set
{
if (_colorGuiasBrush != value)
{
_colorGuiasBrush = value;
OnPropertyChanged(nameof(ColorGuiasBrush));
// Extraer el color del brush y actualizar la propiedad Color
if (value is SolidColorBrush solidBrush)
{
colorGuias = solidBrush.Color;
OnPropertyChanged(nameof(ColorGuias));
}
}
}
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de las guías")]
[property: Name("Color Guías")]
private Color colorGuias = Colors.DarkBlue;
partial void OnColorGuiasChanged(Color value)
{
// Sincronizar con la propiedad Brush
ColorGuiasBrush = new SolidColorBrush(value);
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con motor")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al transporte")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
[JsonIgnore]
private PropertyChangedEventHandler motorPropertyChangedHandler;
partial void OnId_MotorChanged(string value)
{
if (Motor != null && motorPropertyChangedHandler != null)
Motor.PropertyChanged -= motorPropertyChangedHandler;
if (_mainViewModel != null && !string.IsNullOrEmpty(value))
{
Motor = (osVMmotorSim)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => s is osVMmotorSim motor && motor.Nombre == value);
if (Motor != null)
{
motorPropertyChangedHandler = (sender, e) =>
{
if (e.PropertyName == nameof(osVMmotorSim.Nombre))
{
Id_Motor = ((osVMmotorSim)sender).Nombre;
}
};
Motor.PropertyChanged += motorPropertyChangedHandler;
}
}
}
public override void AnguloChanged(float value)
{
OnPropertyChanged(nameof(AnguloFinal));
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Arco de la curva en grados")]
[property: Name("Arco (grados)")]
[NotifyPropertyChangedFor(nameof(AnguloFinal))]
private float arco_en_grados;
partial void OnArco_en_gradosChanged(float value)
{
ActualizarGeometrias();
}
[Hidden]
public float AnguloFinal
{
get => Angulo + Arco_en_grados;
}
private void ActualizarGeometrias()
{
if (_visualRepresentation is ucTransporteCurvaGuias uc)
{
UpdateCurve(Simulation_TransporteCurvaGuias, RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
ActualizarGuiasCurvas();
SetSpeed();
}
}
private void ActualizarGuiasCurvas()
{
// Limpiar guías existentes
EliminarGuiasExistentes();
// Crear nuevas guías
CrearGuiasCurvas();
}
private void EliminarGuiasExistentes()
{
foreach (var guia in GuiasSuperiores)
{
simulationManager?.Remove(guia);
}
foreach (var guia in GuiasInferiores)
{
simulationManager?.Remove(guia);
}
GuiasSuperiores.Clear();
GuiasInferiores.Clear();
}
private void CrearGuiasCurvas()
{
if (NumeroSegmentosGuias < 4 || simulationManager == null)
return;
float radioGuiaSuperior = RadioExterno + DistanciaGuias;
float radioGuiaInferior = RadioInterno - DistanciaGuias;
// Asegurar que el radio interior de la guía no sea negativo
if (radioGuiaInferior < 0.01f)
radioGuiaInferior = 0.01f;
// Convertir ángulos a radianes
float anguloInicioRad = simBase.GradosARadianes(Angulo);
float anguloFinalRad = simBase.GradosARadianes(AnguloFinal);
float rangoAngular = anguloFinalRad - anguloInicioRad;
// Calcular el paso angular entre segmentos
float pasoAngular = rangoAngular / NumeroSegmentosGuias;
// Obtener el centro una vez para todo el método
nkast.Aether.Physics2D.Common.Vector2 centro = GetCurveCenterInMeter(RadioExterno);
// Crear segmentos para guía superior (externa)
for (int i = 0; i < NumeroSegmentosGuias; i++)
{
float angulo1 = anguloInicioRad + i * pasoAngular;
float angulo2 = anguloInicioRad + (i + 1) * pasoAngular;
nkast.Aether.Physics2D.Common.Vector2 punto1 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaSuperior * (float)Math.Cos(angulo1),
radioGuiaSuperior * (float)Math.Sin(angulo1)
);
nkast.Aether.Physics2D.Common.Vector2 punto2 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaSuperior * (float)Math.Cos(angulo2),
radioGuiaSuperior * (float)Math.Sin(angulo2)
);
// Ajustar por la posición del objeto
punto1 += centro;
punto2 += centro;
simGuia guiaSegmento = simulationManager.AddLine(punto1, punto2);
GuiasSuperiores.Add(guiaSegmento);
}
// Crear segmentos para guía inferior (interna)
for (int i = 0; i < NumeroSegmentosGuias; i++)
{
float angulo1 = anguloInicioRad + i * pasoAngular;
float angulo2 = anguloInicioRad + (i + 1) * pasoAngular;
nkast.Aether.Physics2D.Common.Vector2 punto1 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaInferior * (float)Math.Cos(angulo1),
radioGuiaInferior * (float)Math.Sin(angulo1)
);
nkast.Aether.Physics2D.Common.Vector2 punto2 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaInferior * (float)Math.Cos(angulo2),
radioGuiaInferior * (float)Math.Sin(angulo2)
);
// Ajustar por la posición del objeto
punto1 += centro;
punto2 += centro;
simGuia guiaSegmento = simulationManager.AddLine(punto1, punto2);
GuiasInferiores.Add(guiaSegmento);
}
}
public override void OnMoveResizeRotate()
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;
public override void OnResize(float Delta_Width, float Delta_Height)
{
// Calculate the proportional change factor
float widthChangeFactor = (Ancho + Delta_Width) / Ancho;
float heightChangeFactor = (Alto + Delta_Height) / Alto;
// Use the average or minimum change factor to maintain aspect ratio
float changeFactor = Math.Min(widthChangeFactor, heightChangeFactor);
// Save the original radiuses for calculating position adjustments
float originalRadioExterno = RadioExterno;
// Apply the change factor to both radios
RadioExterno *= changeFactor;
RadioInterno *= changeFactor;
// Calculate position adjustment to keep the component centered
float radiusDifference = RadioExterno - originalRadioExterno;
// Adjust Left and Top to maintain center position
// We move by negative half the difference because the component expands outward
Left -= radiusDifference;
Top -= radiusDifference;
// Ensure minimums
if (RadioExterno < 0.1f)
RadioExterno = 0.1f;
if (RadioInterno < 0.05f)
RadioInterno = 0.05f;
// Ensure radioInterno is always less than radioExterno
if (RadioInterno >= RadioExterno)
RadioInterno = RadioExterno * 0.75f;
}
public osTransporteCurvaGuias()
{
RadioExterno = 1.3f;
RadioInterno = 1f;
Ancho = RadioExterno * 2; // Set initial width based on external radius
Alto = RadioExterno * 2; // Set initial height based on external radius
Arco_en_grados = 90;
Tag_ReleActivatedMotor = "1";
NumeroSegmentosGuias = 12; // Valor por defecto
GrosorGuias = 0.03f;
DistanciaGuias = 0.05f;
MostrarGuias = true; // Mostrar guías por defecto
}
public override void UpdateGeometryStart()
{
// Se llama antes de la simulacion
ActualizarGeometrias();
}
public override void SimulationStop()
{
// Se llama al detener la simulacion
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
{
if (Motor is osVMmotorSim motor)
if (LeerBitTag(Tag_ReleActivatedMotor))
VelocidadActual = motor.Velocidad;
else
VelocidadActual = 0;
}
}
public override void ucLoaded()
{
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion
base.ucLoaded();
OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor
if (_visualRepresentation is ucTransporteCurvaGuias uc)
{
Simulation_TransporteCurvaGuias = AddCurve(RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
CrearGuiasCurvas(); // Crear las guías curvas
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
}
}
public override void ucUnLoaded()
{
// El UserControl se esta eliminando
// eliminar el objeto de simulacion
simulationManager?.Remove(Simulation_TransporteCurvaGuias);
EliminarGuiasExistentes();
}
}
public partial class ucTransporteCurvaGuias : UserControl, IDataContainer
{
public osBase? Datos { get; set; }
public int zIndex_fromFrames { get; set; }
public ucTransporteCurvaGuias()
{
InitializeComponent();
this.Loaded += OnLoaded;
this.Unloaded += OnUnloaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Datos?.ucLoaded();
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
Datos?.ucUnLoaded();
}
public void Highlight(bool State) { }
public ZIndexEnum ZIndex_Base()
{
return ZIndexEnum.Estaticos;
}
}
}

View File

@ -25,13 +25,10 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte con Guías";
return "Transporte Guias";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -39,9 +36,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -50,9 +44,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -76,21 +67,16 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del transporte")]
[property: Name("Color")]
Color color = Colors.Blue;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con motor")]
[property: Name("Tag Activación Motor")]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al transporte")]
[property: Name("Motor Enlazado")]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
@ -125,9 +111,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Actuar como freno")]
[property: Name("Es Freno")]
public bool esFreno;
partial void OnEsFrenoChanged(bool value)
@ -137,39 +120,16 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Distancia entre guías")]
[property: Name("Distancia")]
private float distance;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de las guías")]
[property: Name("Alto Guía")]
private float altoGuia;
private void ActualizarGeometrias()

View File

@ -28,13 +28,10 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte Guías Unión";
return "Transporte Guias Union";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -42,21 +39,16 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del transporte")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con motor")]
[property: Name("Tag Activación Motor")]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor A enlazado")]
[property: Name("Motor A")]
[property: Description("Link to Motor A")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_MotorA;
@ -82,9 +74,8 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor B enlazado")]
[property: Name("Motor B")]
[property: Description("Link to Motor B")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_MotorB;
@ -110,9 +101,6 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del motor A")]
[property: Name("Velocidad A")]
public float velocidadActualA;
partial void OnVelocidadActualAChanged(float value)
@ -125,9 +113,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invertir dirección del motor A")]
[property: Name("Invertir A")]
bool invertirDireccionA;
partial void OnInvertirDireccionAChanged(bool value)
@ -143,9 +128,6 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del motor B")]
[property: Name("Velocidad B")]
public float velocidadActualB;
partial void OnVelocidadActualBChanged(float value)
@ -158,9 +140,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invertir dirección del motor B")]
[property: Name("Invertir B")]
bool invertirDireccionB;
partial void OnInvertirDireccionBChanged(bool value)
@ -180,15 +159,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho de las secciones rectas")]
[property: Name("Ancho Recto")]
public float anchoRecto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho de la sección central")]
[property: Name("Ancho Central")]
public float anchoCentral;
@ -203,45 +175,19 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Ancho total del transporte calculado")]
[property: Name("Ancho Total")]
public float anchoTransporte_oculto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Distancia entre elementos")]
[property: Name("Distancia")]
private float distance;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de las guías")]
[property: Name("Alto Guía")]
private float altoGuia;
void ActualizarStoryboards(Rectangle transporte)

View File

@ -23,13 +23,11 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte TTOP";
return "Transporte";
}
private string nombre = NombreClase();
private string nombre = "Transporte TTOP";
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
[property: Category("Id:")]
public override string Nombre
{
get => nombre;
@ -37,9 +35,7 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte en m/s")]
[property: Name("Velocidad Actual")]
[property: Category("Simulation:")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -48,9 +44,7 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento del transporte")]
[property: Name("Invertir Dirección")]
[property: Category("Simulation:")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -73,15 +67,13 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Tag de bit para activar enlace con motor")]
[property: Category("Enlace PLC")]
[property: Name("Tag Activación Motor")]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Description("Seleccionar motor para enlazar")]
[property: Category("Enlace PLC")]
[property: Name("Motor Enlazado")]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
@ -112,27 +104,16 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción entre objetos y superficie")]
[property: Name("Coeficiente de Fricción")]
[property: Category("Setup:")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Máxima 50Hz")]
[property: Category("Setup:")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa para acelerar/desacelerar")]
[property: Name("Tiempo de Rampa")]
[property: Category("Setup:")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Indica si el transporte está en marcha")]
[property: Name("En Marcha")]
[property: Category("Setup:")]
public bool esMarcha;

View File

@ -26,13 +26,11 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte TTOP Doble Inversor";
return "Transporte Dual Inverter";
}
private string nombre = NombreClase();
private string nombre = "Transporte TTOP Dual Inverter";
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
[property: Category("Id:")]
public override string Nombre
{
get => nombre;
@ -40,9 +38,7 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
[property: Category("Simulation:")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -51,9 +47,7 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
[property: Category("Simulation:")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -76,28 +70,24 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con inversor A")]
[property: Name("Tag Activación Motor A")]
[property: Description("Bit to enable Link to Inverter A")]
[property: Category("PLC link:")]
string tag_ReleActivatedMotor_A;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con inversor B")]
[property: Name("Tag Activación Motor B")]
[property: Description("Bit to enable Link to Inverter B")]
[property: Category("PLC link:")]
string tag_ReleActivatedMotor_B;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Enlace a inversor A")]
[property: Name("Motor A")]
[property: Description("Link to Inverter A")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor_A;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Enlace a inversor B")]
[property: Name("Motor B")]
[property: Description("Link to Inverter B")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor_B;
@ -151,27 +141,16 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
[property: Category("Setup:")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
[property: Category("Setup:")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
[property: Category("Setup:")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
[property: Category("Setup:")]
public bool esMarcha;

View File

@ -25,30 +25,20 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Motor VetroMeccanica";
return "VetroMeccanica Motor";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Category("Apariencia")]
[property: Description("Imagen visual del motor")]
[property: Name("Imagen")]
public ImageSource imageSource_oculta;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del motor")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -57,45 +47,28 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de actualización en milisegundos")]
[property: Name("Tiempo de Actualización")]
public float refresh_Time_ms;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad proporcional en porcentaje")]
[property: Name("Velocidad Proporcional")]
public float proporcional_Speed;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima para rampa")]
[property: Name("Velocidad Máxima Rampa")]
public float max_Speed_for_Ramp;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Contacto normalmente cerrado de trip del VFD")]
[property: Name("VFD Trip NC")]
bool vFD_Trip_NC;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa para acelerar/desacelerar")]
[property: Name("Tiempo de Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Description("Habilita lectura del encoder del motor simulado en PLC")]
[property: Category("Encoder")]
[property: Name("Motor con Encoder")]
[property: Description("Enable read of the Motor encoder simulated on PLC.")]
[property: Category("Encoder:")]
bool motor_With_Encoder;
[ObservableProperty]
[property: Description("Valor actual de la posición del encoder")]
[property: Category("Encoder")]
[property: Name("Posición Actual")]
[property: Description("Actual Value of the encoder position.")]
[property: Category("Encoder:")]
public float actual_Position;
partial void OnTiempoRampaChanged(float value)
@ -106,15 +79,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de encendido del motor")]
[property: Name("Encendido")]
bool encendido;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Número del motor en el PLC")]
[property: Name("Número de Motor PLC")]
int pLC_NumeroMotor;
partial void OnPLC_NumeroMotorChanged(int value)
@ -126,27 +92,16 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Bloque de datos del motor en el PLC")]
[property: Name("DB del Motor")]
int pLC_DB_Motor;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Relación de transmisión")]
[property: Name("Ratio")]
public float ratio;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del motor")]
[property: Name("Velocidad")]
public float velocidad;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de giro")]
[property: Name("Sentido Contrario")]
public bool sentido_contrario;

View File

@ -74,13 +74,10 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
public static string NombreClase()
{
return "Buscador de Plantillas";
return "Search Templates";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -88,9 +85,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ejecutar búsqueda de plantillas")]
[property: Name("Buscar Plantillas")]
[property: Category("Tag Extraction:")]
bool search_templates;
partial void OnSearch_templatesChanged(bool oldValue, bool newValue)
@ -101,22 +96,16 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Capturar imagen de referencia")]
[property: Name("Tomar Clip")]
[property: Category("Tag Extraction:")]
bool tomarClip;
// En lugar de almacenar Mat directamente, guardaremos una representación serializable
[ObservableProperty]
[property: Category("Información")]
[property: Description("Datos de región capturada")]
[property: Name("Datos Región")]
[property: Category("Tag Extraction:")]
byte[] capturedRegionData;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Indica si la región fue capturada")]
[property: Name("Región Capturada")]
[property: Category("Tag Extraction:")]
[property: ReadOnly(true)]
bool regionCapturada;
@ -126,27 +115,19 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
// Propiedades para almacenar las dimensiones de la captura
[ObservableProperty]
[property: Category("Información")]
[property: Description("Ancho de región capturada")]
[property: Name("Ancho Capturado")]
[property: Category("Tag Extraction:")]
int capturedWidth;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Alto de región capturada")]
[property: Name("Alto Capturado")]
[property: Category("Tag Extraction:")]
int capturedHeight;
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Exportar datos OCR")]
[property: Name("Exportar OCR")]
[property: Category("Tag Extraction:")]
bool export_ocr;
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Texto exportado OCR")]
[property: Name("Texto Export OCR")]
[property: Category("Tag Extraction:")]
string text_export_ocr;

View File

@ -17,13 +17,9 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
{
public static string NombreClase()
{
return "Extractor de Tags";
return "Extraccion Tags";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -36,28 +32,20 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ejecutar extracción de tag")]
[property: Name("Extraer")]
[property: Category("Tag Extraction:")]
bool extraer;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Eliminar saltos de línea del texto extraído")]
[property: Name("Eliminar Enter")]
[property: Category("Tag Extraction:")]
bool eliminar_enters;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Idioma para reconocimiento OCR")]
[property: Name("Idioma OCR")]
[property: Category("Tag Extraction:")]
[property: ItemsSource(typeof(IdiomasItemsSource<Idiomas>))]
string idioma_Extraccion;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Patrón de extracción de texto")]
[property: Name("Tipo de Patrón")]
[property: Category("Tag Extraction:")]
[property: ItemsSource(typeof(TagPatternItemsSource<TagPattern>))]
string pattern_Type;
@ -109,9 +97,8 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
private osBuscarCoincidencias Search_Templates;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Plantillas de búsqueda asociadas")]
[property: Name("Plantillas Búsqueda")]
[property: Description("Link to Search Templates")]
[property: Category("Tag Extraction:")]
[property: ItemsSource(typeof(osBaseItemsSource<osBuscarCoincidencias>))]
string id_Search_Templates;
@ -136,46 +123,33 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Texto extraído mediante OCR")]
[property: Name("Tag Extraído")]
[property: Category("Tag Extraction:")]
string tag_extract;
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Clase del objeto para exportación")]
[property: Name("Clase")]
[property: Category("Export:")]
string clase;
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Nombre de la columna para exportación")]
[property: Name("Nombre Columna")]
[property: Category("Export:")]
string collumn_name;
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Número de columna Excel")]
[property: Name("Número Columna")]
[property: Description("Excel collumn.")]
[property: Category("Export:")]
int collumn_number;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Número de copia del objeto")]
[property: Name("Número de Copia")]
[property: Category("Tag Extraction:")]
[property: ReadOnly(true)]
int copy_Number;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Mostrar ventana de depuración OCR")]
[property: Name("Mostrar Debug")]
[property: Category("Tag Extraction:")]
bool show_Debug_Window;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Opacidad del objeto")]
[property: Name("Opacidad")]
float opacity_oculto;
public osExtraccionTag()

View File

@ -1,11 +1,11 @@
using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -18,13 +18,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Botón";
return "Boton";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -32,34 +28,19 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Texto mostrado en el botón")]
[property: Name("Texto del Botón")]
string button_Name;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tipo normalmente cerrado")]
[property: Name("Normalmente Cerrado")]
public bool tipo_NC;
[ObservableProperty]
[property: Hidden]
[property: Category("Apariencia")]
[property: Description("Color cuando está presionado")]
[property: Name("Color Presionado")]
Color color_Pressed;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del texto del botón")]
[property: Name("Color del Texto")]
Color color_Titulo;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color principal del botón")]
[property: Name("Color")]
Color color;
partial void OnColorChanged(Color value)
@ -69,15 +50,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Hidden]
[property: Category("Apariencia")]
[property: Description("Color actual del botón")]
[property: Name("Color Actual")]
private Color colorButton;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del botón")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -86,9 +61,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado actual del botón")]
[property: Name("Estado")]
public bool estado;
partial void OnEstadoChanged(bool value)
@ -104,15 +76,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag PLC")]
public string tag;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para controlar luz indicadora")]
[property: Name("Tag Luz")]
public string tag_Luz;
public void ButtonDownCommand()
@ -148,8 +114,7 @@ namespace CtrEditor.ObjetosSim
else ColorButton = Color;
}
public override void UpdatePLCPrimerCiclo()
{
public override void UpdatePLCPrimerCiclo() {
// Escribimos el valor actual al iniciar la conexion
// Esto es util para NC principalmente

View File

@ -17,14 +17,10 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Encoder de Motor";
return "Encoder Motor";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -32,46 +28,35 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual del encoder")]
[property: Name("Color")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del motor")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Pulsos por vuelta del encoder")]
[property: Name("Pulsos por Vuelta")]
[property: Category("Encoder Config:")]
public float pulsos_Por_Vuelta;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Ratio de giros por 50Hz")]
[property: Name("Ratio Giros 50Hz")]
[property: Category("Encoder Config:")]
public float ratio_Giros_50hz;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Valor actual del encoder")]
[property: Name("Valor Actual")]
[property: Category("Encoder Status:")]
public float valor_Actual;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al encoder")]
[property: Name("Motor Enlazado")]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para valor del encoder")]
[property: Name("Tag Valor")]
[property: Description("Tag para escribir el valor del encoder")]
[property: Category("PLC link:")]
string tag_Valor;
partial void OnId_MotorChanged(string value)

View File

@ -21,10 +21,6 @@ namespace CtrEditor.ObjetosSim
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -32,46 +28,35 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual del encoder")]
[property: Name("Color")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del motor")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Pulsos por Hz por segundo (K)")]
[property: Name("Pulsos por Hz")]
[property: Description("Pulsos por Hz por segundo : K")]
[property: Category("Encoder Config:")]
public float pulsos_Por_Hz;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Valor actual del encoder")]
[property: Name("Valor Actual")]
[property: Category("Encoder Status:")]
public float valor_Actual;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al encoder")]
[property: Name("Motor Enlazado")]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para escribir valor del encoder")]
[property: Name("Tag Valor Escritura")]
[property: Description("Tag para escribir el valor del encoder")]
[property: Category("PLC link:")]
string tag_Valor;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para leer valor del encoder (tiene prioridad sobre motor)")]
[property: Name("Tag Valor Lectura")]
[property: Description("Tag para leer el valor del encoder. Este tag tiene prioridad sobre el Motor. Si se usa solo se lee el tag para actualizar la posicion.")]
[property: Category("PLC link:")]
string tag_ReadValor;

View File

@ -24,14 +24,10 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Encoder de Engranaje";
return "Ruota Fonica";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -39,15 +35,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para señal de pulso")]
[property: Name("Tag PLC")]
public string tag;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado actual del pulso")]
[property: Name("Pulso")]
public bool pulso;
partial void OnPulsoChanged(bool value)
@ -67,15 +56,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual del encoder")]
[property: Name("Color")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del encoder")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
public override void AnguloChanged(float value)
@ -85,15 +67,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Tiempo entre pulsos en ms")]
[property: Name("Tiempo de Pulso")]
public float tiempo_Pulso;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Pulsos generados por segundo")]
[property: Name("Pulsos por Segundo")]
public float pulsos_Por_Segundo;
partial void OnPulsos_Por_SegundoChanged(float value)
@ -102,9 +78,6 @@ namespace CtrEditor.ObjetosSim
Giros_segundo_a_100 = (float)((pulsos_Por_Segundo / Dientes) * 100 / VelocidadActual);
}
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Ejecutar homing del encoder")]
[property: Name("Homing")]
private bool homing;
partial void OnHomingChanged(bool value)
@ -114,33 +87,14 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Número de dientes del encoder")]
[property: Name("Cantidad de Dientes")]
public float dientes;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio interno del encoder")]
[property: Name("Radio Interno")]
public float radio_Interno;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio externo del encoder")]
[property: Name("Radio Externo")]
public float radio_Externo;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Ancho de los dientes (0-1)")]
[property: Name("Ancho de Dientes")]
public float ancho_Dientes;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Giros por segundo al 100%")]
[property: Name("Giros/seg al 100%")]
public float giros_segundo_a_100;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -150,9 +104,8 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al encoder")]
[property: Name("Motor Enlazado")]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;

View File

@ -1,4 +1,5 @@
using CtrEditor.Simulacion;

using CtrEditor.Simulacion;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
@ -24,13 +25,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Fotocélula";
return "Photocell";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -38,15 +35,13 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Color del sensor")]
[property: Category("Apariencia")]
[property: Name("Color")]
[property: Description("Color")]
[property: Category("Layout:")]
Brush color;
[ObservableProperty]
[property: Description("Indica si la luz está cortada por un objeto")]
[property: Category("Información")]
[property: Name("Luz Cortada")]
[property: Description("Light cut")]
[property: Category("Debug:")]
bool luzCortada;
partial void OnLuzCortadaChanged(bool value)
@ -65,12 +60,10 @@ namespace CtrEditor.ObjetosSim
Frecuency = 0;
}
if (!value)
{
if (!value) {
Lenght_positive_pulse = (float) (timer.Elapsed.TotalMilliseconds - timer_lastPositive);
timer_lastNegative = timer.Elapsed.TotalMilliseconds;
}
else
} else
{
Lenght_negative_pulse = (float)(timer.Elapsed.TotalMilliseconds - timer_lastNegative);
timer_lastPositive = timer.Elapsed.TotalMilliseconds;
@ -81,21 +74,18 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Ancho del haz de luz del sensor")]
[property: Category("Configuración")]
[property: Name("Ancho del Haz")]
[property: Description("Size of the Light.")]
[property: Category("Setup:")]
float ancho_Haz_De_Luz;
[ObservableProperty]
[property: Description("Distancia al cuello de la botella")]
[property: Category("Información")]
[property: Name("Distancia al Cuello")]
[property: Description("Distance to the neck.")]
[property: Category("Debug:")]
float distancia_cuello;
[ObservableProperty]
[property: Description("Tipo de detección: cuello de botella o botella completa")]
[property: Category("Configuración")]
[property: Name("Detectar Cuello")]
[property: Description("Type of detection: Neck of the bottle or Complete bottle.")]
[property: Category("Setup:")]
bool detectarCuello;
partial void OnDetectarCuelloChanged(bool value)
@ -107,9 +97,8 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Description("Filtro de frecuencia para la señal")]
[property: Category("Configuración")]
[property: Name("Filtro de Frecuencia")]
[property: Description("Filter signal.")]
[property: Category("Setup:")]
float filter_Frecuency;
partial void OnFilter_FrecuencyChanged(float value)
@ -119,33 +108,24 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Frecuencia calculada")]
[property: Name("Frecuencia")]
[property: Category("Debug:")]
float frecuency;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Duración del pulso positivo")]
[property: Name("Duración Pulso Positivo")]
[property: Category("Debug:")]
float lenght_positive_pulse;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Duración del pulso negativo")]
[property: Name("Duración Pulso Negativo")]
[property: Category("Debug:")]
float lenght_negative_pulse;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Tiempo de flanco positivo a flanco positivo")]
[property: Name("Tiempo FP a FP")]
[property: Category("Debug:")]
float lenght_FP_to_FP;
[ObservableProperty]
[property: Description("Tipo de contacto: Normalmente Cerrado")]
[property: Category("Configuración")]
[property: Name("Tipo NC")]
[property: Description("Type Filter signal.")]
[property: Category("Setup:")]
public bool tipo_NC;
partial void OnTipo_NCChanged(bool value)
@ -154,9 +134,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag de salida de la fotocélula")]
[property: Name("Tag de Salida")]
public string tagPhotocell_OUT;
@ -222,8 +199,7 @@ namespace CtrEditor.ObjetosSim
OnLuzCortadaChanged(LuzCortada);
}
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) {
}
public override void ucLoaded()
{

View File

@ -17,13 +17,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Sensor de Temperatura";
return "Temperatura";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -31,27 +27,13 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para valor de temperatura")]
[property: Name("Tag PLC")]
public string tag;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor mínimo escalado")]
[property: Name("Mínimo Escalado")]
public float min_OUT_Scaled;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor máximo escalado")]
[property: Name("Máximo Escalado")]
public float max_OUT_Scaled;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Valor actual de temperatura")]
[property: Name("Temperatura")]
public float value;
partial void OnValueChanged(float value)

View File

@ -1,4 +1,3 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
@ -13,26 +12,9 @@ namespace CtrEditor.ObjetosSim
/// <summary>
/// Atributo para marcar propiedades que deben usar el editor de etiquetas
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class TagEditorAttribute : Attribute
{
public Type? EditorType { get; }
public TagEditorAttribute(Type? editorType = null)
{
EditorType = editorType;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class NameAttribute : Attribute
{
public string DisplayName { get; }
public NameAttribute(string displayName)
{
DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName));
}
public TagEditorAttribute() { }
}
/// <summary>

View File

@ -1,11 +1,11 @@
using LibS7Adv;

using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json.Linq;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -21,13 +21,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Tag Analógico";
return "Analog Tag";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -35,9 +31,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del tag")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -47,49 +40,23 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag")]
public string tag;
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Descripción del tag")]
[property: Name("Descripción")]
public string descripcion;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor mínimo de entrada escalado")]
[property: Name("Mínimo Entrada")]
public float min_IN_Scaled;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor máximo de entrada escalado")]
[property: Name("Máximo Entrada")]
public float max_IN_Scaled;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor mínimo de salida escalado")]
[property: Name("Mínimo Salida")]
public float min_OUT_Scaled;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor máximo de salida escalado")]
[property: Name("Máximo Salida")]
public float max_OUT_Scaled;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Valor actual del tag")]
[property: Name("Valor")]
public float value;
partial void OnValueChanged(float value)

View File

@ -27,7 +27,7 @@
Width="16" Height="25" VerticalAlignment="Center" HorizontalAlignment="Center"
Background="{Binding Color, Converter={StaticResource ColorToBrushConverter}}" />
<Label Content="{Binding Descripcion}" Grid.Column="1" VerticalAlignment="Center"
Background="{Binding Color, Converter={StaticResource ColorToBrushConverter}}"
Background="{Binding Color}"
Visibility="{Binding Show_Description, Converter={StaticResource BooleanToVisibilityConverter}}" />
<CheckBox Grid.Column="2" VerticalAlignment="Center" IsChecked="{Binding Estado}"
Background="{Binding Color_oculto}" />

View File

@ -6,7 +6,6 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json.Linq;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -22,13 +21,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Tag Digital";
return "Bool Tag";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -36,27 +31,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de fondo cuando está activo")]
[property: Name("Color de Fondo")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del tag")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado actual del tag")]
[property: Name("Estado")]
public bool estado;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Mostrar descripción en el objeto")]
[property: Name("Mostrar Descripción")]
public bool show_Description;
partial void OnEstadoChanged(bool value)
@ -69,9 +52,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del tag")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -80,16 +60,10 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag PLC")]
[NotifyPropertyChangedFor(nameof(Estado))]
public string tag;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Descripción del tag")]
[property: Name("Descripción")]
public string descripcion;
public osBoolTag()

View File

@ -2,7 +2,6 @@
using System.Windows;
using System.Windows.Controls;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
@ -16,22 +15,15 @@ namespace CtrEditor.ObjetosSim
public TagsConsensos Consensos = new TagsConsensos();
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Lista de tags para consenso")]
[property: Name("Tags")]
public List<string> tags;
// Otros datos y métodos relevantes para la simulación
public static string NombreClase()
{
return "Consenso Genérico";
return "Consensi";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -39,9 +31,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tamaño del consenso")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)

View File

@ -7,7 +7,6 @@ using System.Windows.Shapes;
using LibS7Adv;
using System.Runtime.Intrinsics;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -24,13 +23,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Trazador de 3 Señales";
return "Trace3";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -38,75 +33,31 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la serie 1")]
[property: Name("Color Serie 1")]
private Brush color_Serie_1;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la serie 2")]
[property: Name("Color Serie 2")]
private Brush color_Serie_2;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la serie 3")]
[property: Name("Color Serie 3")]
private Brush color_Serie_3;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del trazador")]
[property: Name("Alto")]
float alto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del trazador")]
[property: Name("Ancho")]
float ancho;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Serie 1 es tipo booleana")]
[property: Name("Serie 1 Bool")]
bool serie1_Tipo_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para serie 1")]
[property: Name("Tag Serie 1")]
string tag_Serie1;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Serie 2 es tipo booleana")]
[property: Name("Serie 2 Bool")]
bool serie2_Tipo_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para serie 2")]
[property: Name("Tag Serie 2")]
string tag_Serie2;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Serie 3 es tipo booleana")]
[property: Name("Serie 3 Bool")]
bool serie3_Tipo_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para serie 3")]
[property: Name("Tag Serie 3")]
string tag_Serie3;
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Título del trazador")]
[property: Name("Título")]
string titulo;
[ObservableProperty]
@ -138,9 +89,6 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Máximo número de elementos a mostrar")]
[property: Name("Max Elementos")]
float max_Cantidad_Elementos;
public osTrace3()
@ -331,8 +279,7 @@ namespace CtrEditor.ObjetosSim
{
Datos?.ucUnLoaded();
}
public void Resize(float width, float height)
{
public void Resize(float width, float height) {
if (Datos is osTrace3 datos)
{
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
@ -347,8 +294,7 @@ namespace CtrEditor.ObjetosSim
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
}
}
public float Angle() { return 0; }
public void Rotate(float Angle) { }
public float Angle() { return 0; } public void Rotate(float Angle) { }
public void Highlight(bool State) { }
public ZIndexEnum ZIndex_Base()
{

View File

@ -11,7 +11,6 @@ using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.Defaults;
using System.Diagnostics;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -29,13 +28,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Trazador Simple";
return "Trace";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -43,33 +38,18 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del trazador")]
[property: Name("Alto")]
float alto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del trazador")]
[property: Name("Ancho")]
float ancho;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para la serie de datos")]
[property: Name("Tag Serie")]
string tag_serie;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Nombre del eje X")]
[property: Name("Nombre Eje X")]
string x_Series_Name;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Nombre del eje Y")]
[property: Name("Nombre Eje Y")]
string y_Series_Name;
private readonly ObservableCollection<ObservableValue> _observableValues;
@ -110,8 +90,7 @@ namespace CtrEditor.ObjetosSim
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Tag_serie != null && Tag_serie.Length > 0)
{
if (Tag_serie != null && Tag_serie.Length > 0) {
var value = LeerBitTag(Tag_serie) == false ? 0 : 1;
data.Add(value);
}
@ -165,8 +144,7 @@ namespace CtrEditor.ObjetosSim
{
Datos?.ucUnLoaded();
}
public void Resize(float width, float height)
{
public void Resize(float width, float height) {
if (Datos is osTraceSimple datos)
{
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
@ -181,8 +159,7 @@ namespace CtrEditor.ObjetosSim
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
}
}
public float Angle() { return 0; }
public void Rotate(float Angle) { }
public float Angle() { return 0; } public void Rotate(float Angle) { }
public void Highlight(bool State) { }
public ZIndexEnum ZIndex_Base()
{

View File

@ -190,26 +190,12 @@ namespace CtrEditor.ObjetosSim
continue;
var displayNameAttr = property.Attributes.OfType<DisplayNameAttribute>().FirstOrDefault();
var customNameAttr = property.Attributes.OfType<NameAttribute>().FirstOrDefault();
string displayName;
if (customNameAttr != null)
{
displayName = customNameAttr.DisplayName;
}
else if (displayNameAttr != null)
{
displayName = displayNameAttr.DisplayName;
}
else
{
displayName = property.Name.Replace("_", " ");
}
var propertyDefinition = new PropertyDefinition
{
TargetProperties = new[] { property.Name },
DisplayName = displayName
DisplayName = displayNameAttr != null
? displayNameAttr.DisplayName
: property.Name.Replace("_", " ")
};
// Aquí se añaden todas las propiedades; para "ImagePath" no se requiere

View File

@ -5,24 +5,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CtrEditor.ObjetosSim.UserControls"
mc:Ignorable="d" Name="circularSegmentControl">
<Canvas Name="mainCanvas">
<Path Name="path" Stroke="Black" StrokeThickness="1">
<Path.Fill>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute">
<VisualBrush.Transform>
<TransformGroup>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</VisualBrush.Transform>
<VisualBrush.Visual>
<Canvas Width="20" Height="20">
<!-- Patrón de rayas radiales que simulan el movimiento tangencial -->
<Rectangle Fill="LightGray" Width="10" Height="10" Canvas.Left="0" Canvas.Top="0"/>
<Rectangle Fill="GhostWhite" Width="10" Height="10" Canvas.Left="0" Canvas.Top="10"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Path.Fill>
<Canvas>
<Path Name="path" Stroke="Black" Fill="LightBlue" StrokeThickness="1">
<Path.RenderTransform>
<RotateTransform Angle="{Binding Angle, ElementName=circularSegmentControl}"/>
</Path.RenderTransform>

View File

@ -1,7 +1,6 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace CtrEditor.ObjetosSim.UserControls
{
@ -55,95 +54,21 @@ namespace CtrEditor.ObjetosSim.UserControls
public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register("EndAngle", typeof(double), typeof(CircularSegment), new PropertyMetadata(90.0, OnPropertyChanged));
// Nuevas propiedades para las guías
public bool ShowGuides
{
get { return (bool)GetValue(ShowGuidesProperty); }
set { SetValue(ShowGuidesProperty, value); }
}
public static readonly DependencyProperty ShowGuidesProperty =
DependencyProperty.Register("ShowGuides", typeof(bool), typeof(CircularSegment), new PropertyMetadata(false, OnPropertyChanged));
public double GuideDistance
{
get { return (double)GetValue(GuideDistanceProperty); }
set { SetValue(GuideDistanceProperty, value); }
}
public static readonly DependencyProperty GuideDistanceProperty =
DependencyProperty.Register("GuideDistance", typeof(double), typeof(CircularSegment), new PropertyMetadata(5.0, OnPropertyChanged));
public double GuideThickness
{
get { return (double)GetValue(GuideThicknessProperty); }
set { SetValue(GuideThicknessProperty, value); }
}
public static readonly DependencyProperty GuideThicknessProperty =
DependencyProperty.Register("GuideThickness", typeof(double), typeof(CircularSegment), new PropertyMetadata(2.0, OnPropertyChanged));
public static readonly DependencyProperty GuideStrokeProperty =
DependencyProperty.Register("GuideStroke", typeof(Brush), typeof(CircularSegment), new PropertyMetadata(new SolidColorBrush(Colors.DarkBlue), OnGuidePropertyChanged));
public Brush GuideStroke
{
get { return (Brush)GetValue(GuideStrokeProperty); }
set { SetValue(GuideStrokeProperty, value); }
}
public CircularSegment()
{
InitializeComponent();
this.Loaded += CircularSegment_Loaded;
}
private void CircularSegment_Loaded(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("CircularSegment_Loaded called");
DrawSegment();
}
// Propiedad pública para acceder al Path desde código externo
public System.Windows.Shapes.Path TransportePath => path;
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as CircularSegment)?.DrawSegment();
}
private static void OnGuidePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as CircularSegment)?.DrawSegment();
}
private void DrawSegment()
{
System.Diagnostics.Debug.WriteLine($"DrawSegment called - ShowGuides: {ShowGuides}");
if (OuterRadius <= 0 || InnerRadius <= 0 || StartAngle == EndAngle)
return;
// Limpiar canvas existente - mantener solo el path principal
for (int i = mainCanvas.Children.Count - 1; i >= 0; i--)
{
if (mainCanvas.Children[i] != path)
{
mainCanvas.Children.RemoveAt(i);
}
}
DrawMainSegment();
if (ShowGuides)
{
System.Diagnostics.Debug.WriteLine("About to call DrawGuides()");
DrawGuides();
}
}
private void DrawMainSegment()
{
PathGeometry geometry = new PathGeometry();
PathFigure figure = new PathFigure();
@ -175,76 +100,5 @@ namespace CtrEditor.ObjetosSim.UserControls
geometry.Figures.Add(figure);
path.Data = geometry;
}
private void DrawGuides()
{
Point center = new Point(OuterRadius, OuterRadius);
// Calcular radios de las guías
double outerGuideRadius = OuterRadius + GuideDistance;
double innerGuideRadius = InnerRadius - GuideDistance;
System.Diagnostics.Debug.WriteLine($"DrawGuides - Creating guides with radii: Outer={outerGuideRadius}, Inner={innerGuideRadius}");
// Asegurar que el radio interior no sea negativo
if (innerGuideRadius < 1.0)
innerGuideRadius = 1.0;
// Crear guía exterior
CreateGuideArc(center, outerGuideRadius, "OuterGuide");
// Crear guía interior solo si el radio es válido
if (innerGuideRadius > 1.0)
{
CreateGuideArc(center, innerGuideRadius, "InnerGuide");
}
}
private void CreateGuideArc(Point center, double radius, string name)
{
var guidePath = new System.Windows.Shapes.Path
{
Name = name,
Stroke = GuideStroke,
StrokeThickness = GuideThickness,
Fill = null
};
// Crear geometría del arco
double radiansStart = StartAngle * Math.PI / 180.0;
double radiansEnd = EndAngle * Math.PI / 180.0;
Point startPoint = new Point(
center.X + radius * Math.Cos(radiansStart),
center.Y + radius * Math.Sin(radiansStart)
);
Point endPoint = new Point(
center.X + radius * Math.Cos(radiansEnd),
center.Y + radius * Math.Sin(radiansEnd)
);
// Crear el arco usando ArcSegment
var pathGeometry = new PathGeometry();
var pathFigure = new PathFigure
{
StartPoint = startPoint
};
var arcSegment = new ArcSegment
{
Point = endPoint,
Size = new Size(radius, radius),
SweepDirection = SweepDirection.Clockwise,
IsLargeArc = Math.Abs(EndAngle - StartAngle) > 180
};
pathFigure.Segments.Add(arcSegment);
pathGeometry.Figures.Add(pathFigure);
guidePath.Data = pathGeometry;
System.Diagnostics.Debug.WriteLine($"Adding guide {name} to canvas");
mainCanvas.Children.Add(guidePath);
}
}
}

View File

@ -71,8 +71,8 @@ namespace CtrEditor.ObjetosSim
[JsonIgnore]
private System.Threading.Timer timer = null;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
public bool isVisFilter;
@ -80,15 +80,13 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Bloquear movimiento del objeto")]
[property: Name("Bloquear Movimiento")]
[property: Description("Lock object to mouse movement.")]
[property: Category("Layout:")]
private bool lock_movement;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coordenada X del objeto")]
[property: Name("Izquierda")]
[property: Description("X coordinate.")]
[property: Category("Layout:")]
private float left;
public void CheckData()
@ -116,9 +114,8 @@ namespace CtrEditor.ObjetosSim
public virtual void LeftChanging(float oldValue, float newValue) { }
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coordenada Y del objeto")]
[property: Name("Superior")]
[property: Description("Y coordinate.")]
[property: Category("Layout:")]
private float top;
partial void OnTopChanged(float value)
@ -140,9 +137,8 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del objeto")]
[property: Name("Ancho")]
[property: Description("Widht.")]
[property: Category("Layout:")]
private float ancho;
partial void OnAnchoChanged(float value)
@ -152,9 +148,8 @@ namespace CtrEditor.ObjetosSim
public virtual void AnchoChanged(float value) { }
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del objeto")]
[property: Name("Alto")]
[property: Description("Height.")]
[property: Category("Layout:")]
private float alto;
partial void OnAltoChanged(float value)
@ -165,9 +160,8 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ángulo de rotación del objeto")]
[property: Name("Ángulo")]
[property: Description("Angle.")]
[property: Category("Layout:")]
private float angulo;
partial void OnAnguloChanged(float value)
@ -183,9 +177,8 @@ namespace CtrEditor.ObjetosSim
public virtual void AnguloChanging(float oldValue, float newValue) { }
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Etiquetas para clasificar el objeto. Use # antes de cada etiqueta (ej: #motor #bomba #critico)")]
[property: Name("Etiquetas")]
[property: Category("General:")]
[property: Editor(typeof(TagPropertyEditor), typeof(TagPropertyEditor))]
[property: TagEditor]
private string etiquetas = "";
@ -297,9 +290,8 @@ namespace CtrEditor.ObjetosSim
// Group as FacePlate
[ObservableProperty]
[property: Category("Agrupación")]
[property: Description("Enlace a una placa de texto como ancla")]
[property: Name("Panel Grupo")]
[property: Description("This is a link to a faceplate. It works like an anchor.")]
[property: Category("Group:")]
[property: ItemsSource(typeof(osBaseItemsSource<osTextPlate>))]
private string group_Panel;
@ -341,9 +333,8 @@ namespace CtrEditor.ObjetosSim
// Group as FacePlate
[ObservableProperty]
[property: Category("Agrupación")]
[property: Description("Enlace a un marco que se mueve automáticamente como ancla")]
[property: Name("Panel Marco")]
[property: Description("This is a link to a FromPlate that moves automatically. It works like an anchor.")]
[property: Category("Group:")]
[property: ItemsSource(typeof(osBaseItemsSource<osFramePlate>))]
private string group_FramePanel;
@ -353,28 +344,28 @@ namespace CtrEditor.ObjetosSim
private bool isUpdatingFromFramePlate = false;
// Variables para rotación orbital alrededor del FramePlate
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_RelativeX;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_RelativeY;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_InitialAngle;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_PivotX;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_PivotY;
@ -763,9 +754,8 @@ namespace CtrEditor.ObjetosSim
// All Pages Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Habilitar este objeto para ser usado en todas las páginas")]
[property: Name("Habilitado en Todas Páginas")]
[property: Description("Enable this object to be used in all pages.")]
[property: Category("Layout:")]
private bool enable_On_All_Pages;
@ -789,9 +779,8 @@ namespace CtrEditor.ObjetosSim
// Local Data for Global Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Habilitar datos locales de este objeto global en todas las páginas")]
[property: Name("Datos Locales para Todas")]
[property: Description("Enable local data of this global Object on all pages.")]
[property: Category("Layout:")]
private bool enable_Local_Data_for_All;
partial void OnEnable_Local_Data_for_AllChanged(bool value)
@ -806,9 +795,8 @@ namespace CtrEditor.ObjetosSim
// Local Data for Global Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Habilitar datos locales de este objeto global en esta página")]
[property: Name("Datos Locales")]
[property: Description("Enable local data of this global Object on this page.")]
[property: Category("Layout:")]
[property: JsonIgnore]
private bool enable_Local_Data;
@ -922,9 +910,7 @@ namespace CtrEditor.ObjetosSim
private List<string> showOnThisPagesList;
private bool show_On_This_Page;
[property: Category("Información")]
[property: Description("Mostrar en esta página")]
[property: Name("Mostrar en Esta Página")]
[property: Category("Layout:")]
public bool Show_On_This_Page
{
get
@ -972,15 +958,13 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Creado automáticamente y clonado con plantillas de búsqueda")]
[property: Name("Clonado")]
[property: Description("Autocreated and cloned with Search Templates")]
[property: Category("Tag Extraction:")]
bool cloned;
[ObservableProperty]
[property: Category("Datos")]
[property: Description("ID del objeto del cual fue clonado")]
[property: Name("Clonado Desde")]
[property: Description("Autocreated and cloned with Search Templates")]
[property: Category("Tag Extraction:")]
[property: Hidden]
UniqueId cloned_from;
@ -1169,27 +1153,6 @@ namespace CtrEditor.ObjetosSim
return storyboard;
}
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporteCircular(System.Windows.Shapes.Path transporte, bool invertirDireccion)
{
if (_visualRepresentation == null) return null;
if (transporte == null) return null;
Storyboard storyboard = new Storyboard();
var animation = new DoubleAnimation
{
From = invertirDireccion ? 20 : 0,
To = invertirDireccion ? 0 : 20, // Total Pixels Brush
Duration = TimeSpan.FromSeconds(PixelToMeter.Instance.calc.PixelsToMeters(20) * 60),
RepeatBehavior = RepeatBehavior.Forever
};
Storyboard.SetTarget(animation, transporte);
Storyboard.SetTargetProperty(animation, new PropertyPath("(Path.Fill).(VisualBrush.Transform).(TransformGroup.Children)[0].(TranslateTransform.Y)"));
storyboard.Children.Add(animation);
storyboard.Begin();
storyboard.SetSpeedRatio(0);
return storyboard;
}
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporte(Storyboard storyboard, Rectangle transporte, bool invertirDireccion)
{
// Detener y eliminar el storyboard existente si hay uno
@ -1202,18 +1165,6 @@ namespace CtrEditor.ObjetosSim
return CrearAnimacionMultiStoryBoardTrasnporte(transporte, invertirDireccion);
}
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporteCircular(Storyboard storyboard, System.Windows.Shapes.Path transporte, bool invertirDireccion)
{
// Detener y eliminar el storyboard existente si hay uno
if (storyboard != null)
{
storyboard.Stop();
storyboard.Children.Clear();
}
return CrearAnimacionMultiStoryBoardTrasnporteCircular(transporte, invertirDireccion);
}
protected void ActualizarAnimacionMultiStoryBoardTransporte(Storyboard storyboard, float velocidadActual)
{
if (_visualRepresentation == null) return;
@ -1230,14 +1181,6 @@ namespace CtrEditor.ObjetosSim
_storyboard = CrearAnimacionMultiStoryBoardTrasnporte(_storyboard, transporte, invertirDireccion);
}
protected void CrearAnimacionStoryBoardTrasnporteCircular(System.Windows.Shapes.Path transporte, bool invertirDireccion, float angulo)
{
if (angulo > 45 && angulo < 225)
_storyboard = CrearAnimacionMultiStoryBoardTrasnporteCircular(_storyboard, transporte, !invertirDireccion);
else
_storyboard = CrearAnimacionMultiStoryBoardTrasnporteCircular(_storyboard, transporte, invertirDireccion);
}
protected void ActualizarAnimacionStoryBoardTransporte(float velocidadActual)
{
ActualizarAnimacionMultiStoryBoardTransporte(_storyboard, velocidadActual);
@ -1658,31 +1601,7 @@ namespace CtrEditor.ObjetosSim
{
if (value is string stringValue)
{
try
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri(stringValue, UriKind.RelativeOrAbsolute);
bitmapImage.EndInit();
return bitmapImage;
}
catch
{
// Si falla la carga de la imagen, usar imagen por defecto como fallback
try
{
var defaultImage = new BitmapImage();
defaultImage.BeginInit();
defaultImage.UriSource = new Uri("/Icons/unselect.png", UriKind.RelativeOrAbsolute);
defaultImage.EndInit();
return defaultImage;
}
catch
{
// Si incluso la imagen por defecto falla, devolver null
return null;
}
}
return new BitmapImage(new Uri(stringValue, UriKind.RelativeOrAbsolute));
}
return null;
}

View File

@ -23,47 +23,40 @@ namespace CtrEditor.ObjetosSim
// Tamaño del área de simulación
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del área de simulación en metros")]
[property: Name("Ancho Simulación")]
[property: Category("Simulación:")]
private float anchoSimulacion = 10.0f;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del área de simulación en metros")]
[property: Name("Alto Simulación")]
[property: Category("Simulación:")]
private float altoSimulacion = 10.0f;
// Propiedades del fluido
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual de las partículas")]
[property: Name("Tamaño Partícula")]
[property: Category("Visual:")]
private float tamañoParticula = 0.01f;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del fluido")]
[property: Name("Color Fluido")]
[property: Category("Visual:")]
private Color colorFluido = Colors.CornflowerBlue;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Opacidad de las partículas")]
[property: Name("Opacidad Partículas")]
[property: Category("Visual:")]
private double opacidadParticulas = 0.7;
// Propiedades de gravedad
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Gravedad en X (m/s²)")]
[property: Name("Gravedad X")]
[property: Category("Física:")]
private float gravedadX = 0.0f;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Gravedad en Y (m/s²)")]
[property: Name("Gravedad Y")]
[property: Category("Física:")]
private float gravedadY = 9.8f;
partial void OnGravedadXChanged(float value)
@ -78,15 +71,13 @@ namespace CtrEditor.ObjetosSim
// Estadísticas de la simulación
[ObservableProperty]
[property: Category("Información")]
[property: Description("Número de partículas")]
[property: Name("Número Partículas")]
[property: Category("Estadísticas:")]
private int numeroParticulas;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Rendimiento en FPS")]
[property: Name("FPS")]
[property: Category("Estadísticas:")]
private double fps;
// Referencia a componentes (solo para la función Add)
@ -95,14 +86,10 @@ namespace CtrEditor.ObjetosSim
// Nombre de la clase para identificación
public static string NombreClase()
{
return "Sistema de Fluidos";
return "SistemaFluidos";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;

View File

@ -7,7 +7,6 @@ using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using CtrEditor.Simulacion;
using System.Windows.Input;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
@ -25,13 +24,9 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Ejemplo Básico";
return "Example";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
private string nombre = "Transporte TTOP";
public override string Nombre
{
get => nombre;
@ -39,9 +34,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -50,9 +42,6 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -76,9 +65,6 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al transporte")]
[property: Name("Motor")]
public string motor;
partial void OnMotorChanged(string value)
@ -87,45 +73,18 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del transporte")]
[property: Name("Ancho")]
public float ancho;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del transporte")]
[property: Name("Alto")]
public float alto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ángulo de rotación")]
[property: Name("Ángulo")]
public float angulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;

View File

@ -57,9 +57,8 @@ namespace CtrEditor.ObjetosSim
// Propiedades visuales
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la tubería en metros")]
[property: Name("Diámetro")]
[property: Category("Dimensiones:")]
private float diametro = 0.05f;
partial void OnDiametroChanged(float value)
@ -73,33 +72,28 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Diámetro interno para visualización del fluido")]
[property: Name("Diámetro Interno")]
[property: Category("Visual:")]
private float diametroInterno;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la tubería")]
[property: Name("Color Tubería")]
[property: Category("Visual:")]
private System.Windows.Media.Color color = System.Windows.Media.Colors.Gray;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del fluido")]
[property: Name("Color Fluido")]
[property: Category("Visual:")]
private System.Windows.Media.Color colorFluido = System.Windows.Media.Colors.CornflowerBlue;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Datos del path para dibujar la tubería")]
[property: Name("Path Data")]
[property: Category("Interno:")]
private string pathData;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Densidad del fluido (0-1)")]
[property: Name("Densidad Fluido")]
[property: Category("Simulación:")]
private double densidadFluido = 0.7;
// Lista de puntos que forman la tubería
@ -108,14 +102,10 @@ namespace CtrEditor.ObjetosSim
// Nombre de la clase para identificación
public static string NombreClase()
{
return "Tubería de Fluido";
return "TuberiaFluido";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;

View File

@ -58,41 +58,35 @@ namespace CtrEditor.ObjetosSim
// Propiedades dimensionales
[ObservableProperty]
[property: Category("Configuración")]
[property: Category("Dimensiones:")]
[property: Description("Ancho de la válvula en metros")]
[property: Name("Ancho")]
private float ancho = 0.1f;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de la válvula en metros")]
[property: Name("Alto")]
[property: Category("Dimensiones:")]
private float alto = 0.06f;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la tubería conectada")]
[property: Name("Diámetro Tubería")]
[property: Category("Dimensiones:")]
private float diametroTuberia = 0.05f;
// Propiedades visuales
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la válvula")]
[property: Name("Color")]
[property: Category("Visual:")]
private Color color = Colors.Silver;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del indicador de apertura")]
[property: Name("Color Indicador")]
[property: Category("Visual:")]
private Color colorIndicador = Colors.CornflowerBlue;
// Propiedades de funcionamiento
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Apertura de la válvula (0-1)")]
[property: Name("Apertura")]
[property: Category("Operación:")]
private float apertura = 1.0f;
partial void OnAperturaChanged(float value)
@ -108,9 +102,8 @@ namespace CtrEditor.ObjetosSim
// Tag PLC para la válvula
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para lectura/escritura de apertura (0-100%)")]
[property: Name("Tag Apertura")]
[property: Description("Tag de lectura/escritura de la apertura (0-100%)")]
[property: Category("PLC:")]
private string tagApertura;
// Propiedades calculadas para visualización
@ -129,14 +122,10 @@ namespace CtrEditor.ObjetosSim
// Nombre de la clase para identificación
public static string NombreClase()
{
return "Válvula de Fluido";
return "ValvulaFluido";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;

View File

@ -1,138 +0,0 @@
# Script para estandarizar objetos derivados de osBase
# Ejecutar desde la raíz del proyecto CtrEditor
Write-Host "=== Estandarización de Objetos osBase ===" -ForegroundColor Green
# Mapeo de nombres de clase mejorados
$nombresClase = @{
# Transportes
"ucTransporteTTop" = "Transporte TTOP"
"ucTransporteTTopDualInverter" = "Transporte TTOP Dual Inverter"
"ucTransporteGuias" = "Transporte con Guías"
"ucTransporteGuiasUnion" = "Transporte con Guías Unión"
"ucTransporteCurva" = "Transporte Curva"
"ucTransporteCurvaGuias" = "Transporte Curva con Guías"
# Sensores
"ucPhotocell" = "Fotocélula"
"ucGearEncoder" = "Encoder de Engranaje"
"ucEncoderMotor" = "Encoder Motor"
"ucEncoderMotorLineal" = "Encoder Motor Lineal"
"ucSensTemperatura" = "Sensor de Temperatura"
"ucBoton" = "Botón"
# Actuadores
"ucVMmotorSim" = "Motor VetroMeccanica"
"ucValvulaFluido" = "Válvula de Fluido"
# Elementos Estáticos
"ucGuia" = "Guía"
"ucDescarte" = "Descarte"
# Emuladores
"ucBottGenerator" = "Generador de Botellas"
"ucFiller" = "Llenadora"
"ucTanque" = "Tanque"
# Señales
"ucAnalogTag" = "Tag Analógico"
"ucBoolTag" = "Tag Digital"
"ucConsensGeneric" = "Consenso Genérico"
# Datos
"ucExtraccionTag" = "Extracción de Tag"
"ucBuscarCoincidencias" = "Búsqueda de Coincidencias"
# Decorativos
"ucCustomImage" = "Imagen Personalizada"
"ucFramePlate" = "Marco"
"ucTextPlate" = "Placa de Texto"
# Fluidos
"ucTuberiaFluido" = "Tubería de Fluido"
"osSistemaFluidos" = "Sistema de Fluidos"
# Trazas
"ucTrace3" = "Traza 3 Puntos"
"ucTraceSimple" = "Traza Simple"
# Dinámicos
"ucBotella" = "Botella"
"ucBotellaCuello" = "Botella con Cuello"
# Ejemplo
"ucBasicExample" = "Ejemplo Básico"
}
# Mapeo de categorías estándar
$categoriasEstandar = @{
"Id:" = "Identificación"
"Layout:" = "Posición y Tamaño"
"Setup:" = "Configuración"
"Simulation:" = "Simulación"
"PLC link:" = "Enlace PLC"
"Debug:" = "Información"
"Encoder:" = "Encoder"
"General:" = "Identificación"
}
function Actualizar-NombreClase {
param(
[string]$archivo,
[string]$nuevoNombre
)
$contenido = Get-Content $archivo -Raw
$patron = 'return\s+"[^"]*";'
$reemplazo = "return `"$nuevoNombre`";"
if ($contenido -match $patron) {
$contenido = $contenido -replace $patron, $reemplazo
Set-Content $archivo $contenido -NoNewline
Write-Host "✓ Actualizado NombreClase en $archivo" -ForegroundColor Yellow
}
}
function Estandarizar-Categorias {
param([string]$archivo)
$contenido = Get-Content $archivo -Raw
$modificado = $false
foreach ($categoria in $categoriasEstandar.Keys) {
$patron = [regex]::Escape("Category(`"$categoria`")")
$reemplazo = "Category(`"$($categoriasEstandar[$categoria])`")"
if ($contenido -match $patron) {
$contenido = $contenido -replace $patron, $reemplazo
$modificado = $true
}
}
if ($modificado) {
Set-Content $archivo $contenido -NoNewline
Write-Host "✓ Estandarizadas categorías en $archivo" -ForegroundColor Cyan
}
}
# Buscar todos los archivos .cs en ObjetosSim
$archivos = Get-ChildItem -Path "ObjetosSim" -Filter "*.cs" -Recurse | Where-Object {
$_.Name -like "uc*.cs" -or $_.Name -like "os*.cs"
}
Write-Host "Encontrados $($archivos.Count) archivos para procesar" -ForegroundColor Blue
foreach ($archivo in $archivos) {
$nombreArchivo = [System.IO.Path]::GetFileNameWithoutExtension($archivo.Name)
# Actualizar nombre de clase si está en el mapeo
if ($nombresClase.ContainsKey($nombreArchivo)) {
Actualizar-NombreClase -archivo $archivo.FullName -nuevoNombre $nombresClase[$nombreArchivo]
}
# Estandarizar categorías
Estandarizar-Categorias -archivo $archivo.FullName
}
Write-Host "=== Proceso completado ===" -ForegroundColor Green
Write-Host "Revise los cambios y verifique que la compilación sea exitosa" -ForegroundColor Yellow

View File

@ -6,7 +6,6 @@ using System.Windows;
using CtrEditor.Simulacion;
using System.IO;
using System.Linq;
using System.Windows.Media;
namespace CtrEditor.Serialization
{
@ -255,94 +254,8 @@ namespace CtrEditor.Serialization
NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto,
ObjectCreationHandling = ObjectCreationHandling.Replace,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
Error = HandleDeserializationError,
Converters = { new SafeImageSourceConverter() },
// Configuración para respetar atributos JsonIgnore de Newtonsoft.Json
ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver
{
IgnoreSerializableAttribute = false
}
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
}
private void HandleDeserializationError(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e)
{
// Si es un error relacionado con ImagePath, ImageSource o osCustomImage, simplemente ignorarlo y continuar
if (e.ErrorContext.Error.Message.Contains("ImagePath") ||
e.ErrorContext.Error.Message.Contains("osCustomImage") ||
e.ErrorContext.Error.Message.Contains("ImageSource") ||
e.ErrorContext.Error.Message.Contains("lmageSource") || // posible typo en el mensaje de error
(e.ErrorContext.Path != null && e.ErrorContext.Path.Contains("ImageSource")) ||
(e.ErrorContext.Path != null && e.ErrorContext.Path.Contains("imagePath")) ||
(e.ErrorContext.Member != null && e.ErrorContext.Member.ToString().Contains("Image")))
{
e.ErrorContext.Handled = true;
// Si el contexto actual es un objeto osCustomImage y hay un error,
// intentar establecer valores por defecto
if (e.ErrorContext.OriginalObject is osCustomImage customImage)
{
try
{
// Establecer valores seguros por defecto
if (e.ErrorContext.Member?.ToString() == "ImagePath" ||
e.ErrorContext.Member?.ToString() == "imagePath")
{
customImage.ImagePath = ""; // Esto activará el fallback a imagen por defecto
}
}
catch
{
// Si incluso esto falla, simplemente ignorar
}
}
}
}
}
/// <summary>
/// Convertidor JSON seguro para ImageSource que nunca lanza excepciones
/// </summary>
public class SafeImageSourceConverter : JsonConverter<ImageSource>
{
public override ImageSource ReadJson(JsonReader reader, Type objectType, ImageSource existingValue, bool hasExistingValue, JsonSerializer serializer)
{
try
{
// Si el valor es null o string vacío, devolver null
if (reader.Value == null || reader.Value.ToString() == "")
return null;
// Intentar crear ImageSource desde el valor
string value = reader.Value.ToString();
// Limpiar caracteres problemáticos
value = value.Trim();
if (value.Contains("•"))
value = value.Replace("•", "");
if (value.StartsWith("filet///"))
value = value.Replace("filet///", "file:///");
// Si el valor limpio está vacío, devolver null
if (string.IsNullOrWhiteSpace(value))
return null;
// No intentar crear ImageSource aquí, simplemente devolver null
// La lógica de carga de imagen se manejará en el código de la aplicación
return null;
}
catch
{
// En caso de cualquier error, devolver null silenciosamente
return null;
}
}
public override void WriteJson(JsonWriter writer, ImageSource value, JsonSerializer serializer)
{
// Nunca serializar ImageSource, siempre escribir null
writer.WriteNull();
}
}
}