616 lines
20 KiB
C#
616 lines
20 KiB
C#
using System.Globalization;
|
|
using System.Windows.Data;
|
|
using System.Windows.Media;
|
|
using System.Windows;
|
|
using System.ComponentModel;
|
|
using System.Reflection;
|
|
using Xceed.Wpf.Toolkit.PropertyGrid.Editors;
|
|
using Xceed.Wpf.Toolkit;
|
|
using Xceed.Wpf.Toolkit.PropertyGrid;
|
|
using CtrEditor.ObjetosSim.Extraccion_Datos;
|
|
using CtrEditor.ObjetosSim;
|
|
using System.Collections.ObjectModel;
|
|
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
|
using System.Collections;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
namespace CtrEditor
|
|
{
|
|
|
|
public partial class ObjetosSimulablesFilterTypes : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
public bool cloned;
|
|
[ObservableProperty]
|
|
public bool enable_On_All_Pages;
|
|
[ObservableProperty]
|
|
public bool show_On_This_Page;
|
|
[ObservableProperty]
|
|
public bool all;
|
|
|
|
}
|
|
|
|
public class ListItemPropertyDescriptor<T> : PropertyDescriptor
|
|
{
|
|
private readonly IList<T> owner;
|
|
private readonly int index;
|
|
|
|
public ListItemPropertyDescriptor(IList<T> owner, int index) : base($"[{index}]", null)
|
|
{
|
|
this.owner = owner;
|
|
this.index = index;
|
|
|
|
}
|
|
|
|
public override AttributeCollection Attributes
|
|
{
|
|
get
|
|
{
|
|
var attributes = TypeDescriptor.GetAttributes(GetValue(null), false);
|
|
//If the Xceed expandable object attribute is not applied then apply it
|
|
if (!attributes.OfType<ExpandableObjectAttribute>().Any())
|
|
{
|
|
attributes = AddAttribute(new ExpandableObjectAttribute(), attributes);
|
|
}
|
|
|
|
//set the xceed order attribute
|
|
attributes = AddAttribute(new PropertyOrderAttribute(index), attributes);
|
|
|
|
return attributes;
|
|
}
|
|
}
|
|
private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes)
|
|
{
|
|
Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1];
|
|
oldAttributes.CopyTo(newAttributes, 1);
|
|
newAttributes[0] = newAttribute;
|
|
|
|
return new AttributeCollection(newAttributes);
|
|
}
|
|
|
|
public override bool CanResetValue(object component)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public override object GetValue(object component)
|
|
{
|
|
return Value;
|
|
}
|
|
|
|
private T Value
|
|
=> owner[index];
|
|
|
|
public override void ResetValue(object component)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override void SetValue(object component, object value)
|
|
{
|
|
owner[index] = (T)value;
|
|
}
|
|
|
|
public override bool ShouldSerializeValue(object component)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public override Type ComponentType
|
|
=> owner.GetType();
|
|
|
|
public override bool IsReadOnly
|
|
=> false;
|
|
|
|
public override Type PropertyType
|
|
=> Value?.GetType();
|
|
|
|
}
|
|
public class MyExpandableIListConverter<T> : ExpandableObjectConverter
|
|
{
|
|
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
|
|
{
|
|
if (value is IList<T> list)
|
|
{
|
|
PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null);
|
|
IEnumerator enumerator = list.GetEnumerator();
|
|
int counter = -1;
|
|
while (enumerator.MoveNext())
|
|
{
|
|
counter++;
|
|
propDescriptions.Add(new ListItemPropertyDescriptor<T>(list, counter));
|
|
|
|
}
|
|
return propDescriptions;
|
|
}
|
|
else
|
|
{
|
|
return base.GetProperties(context, value, attributes);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class TypeDecorationManager
|
|
{
|
|
public static void AddExpandableObjectConverter(Type T)
|
|
{
|
|
TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(ExpandableObjectConverter)));
|
|
TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute());
|
|
}
|
|
|
|
public static void AddExpandableIListConverter<I>(Type T)
|
|
{
|
|
TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(MyExpandableIListConverter<I>)));
|
|
TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute());
|
|
}
|
|
}
|
|
|
|
public class SubclassFilterConverter : IValueConverter
|
|
{
|
|
public Type TargetType { get; set; }
|
|
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is ObservableCollection<osBase> collection && TargetType != null)
|
|
{
|
|
var filteredCollection = new ObservableCollection<osBase>(collection.Where(x => x.GetType() == TargetType));
|
|
return filteredCollection;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
|
|
public class BoolToVisibilityConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is bool boolValue)
|
|
{
|
|
return boolValue ? Visibility.Visible : Visibility.Collapsed;
|
|
}
|
|
return Visibility.Collapsed;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is Visibility visibility)
|
|
{
|
|
return visibility == Visibility.Visible;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public class DecimalEditor : ITypeEditor
|
|
{
|
|
public FrameworkElement ResolveEditor(PropertyItem propertyItem)
|
|
{
|
|
var doubleUpDown = new DoubleUpDown
|
|
{
|
|
FormatString = "F3",
|
|
Increment = 0.001,
|
|
Maximum = 200000.599,
|
|
MinWidth = 100
|
|
};
|
|
|
|
var binding = new Binding("Value")
|
|
{
|
|
Source = propertyItem,
|
|
Converter = new DecimalConverter(),
|
|
Mode = BindingMode.TwoWay,
|
|
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
|
|
};
|
|
BindingOperations.SetBinding(doubleUpDown, DoubleUpDown.ValueProperty, binding);
|
|
|
|
return doubleUpDown;
|
|
}
|
|
}
|
|
|
|
public class DecimalConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is double doubleValue)
|
|
{
|
|
return doubleValue.ToString("0.00", culture); // Formatear a dos decimales
|
|
}
|
|
if (value is float floatValue)
|
|
{
|
|
return floatValue.ToString("0.00", culture); // Formatear a dos decimales
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (double.TryParse(value as string, NumberStyles.Any, CultureInfo.InvariantCulture, out double doubleValue))
|
|
{
|
|
return doubleValue;
|
|
}
|
|
if (float.TryParse(value as string, NumberStyles.Any, CultureInfo.InvariantCulture, out float floatValue))
|
|
{
|
|
return floatValue;
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
|
|
public class ColorToBrushConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is Color color)
|
|
{
|
|
return new SolidColorBrush(color);
|
|
}
|
|
return Binding.DoNothing;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is SolidColorBrush brush)
|
|
{
|
|
return brush.Color;
|
|
}
|
|
return Binding.DoNothing;
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Property)]
|
|
public class HiddenAttribute : Attribute
|
|
{
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Property)]
|
|
public class DisplayNameAttribute : Attribute
|
|
{
|
|
public string DisplayName { get; }
|
|
|
|
public DisplayNameAttribute(string displayName)
|
|
{
|
|
DisplayName = displayName;
|
|
}
|
|
}
|
|
|
|
public class StringToBrushConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is string colorString)
|
|
{
|
|
return (Brush)new BrushConverter().ConvertFromString(colorString);
|
|
}
|
|
return Brushes.Transparent;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
public class SumConverter : IMultiValueConverter
|
|
{
|
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (values.Length == 2 && values[0] is float value1 && values[1] is float value2)
|
|
{
|
|
return (double) (value1 + value2);
|
|
}
|
|
return DependencyProperty.UnsetValue;
|
|
}
|
|
|
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
public class VerticalPositionConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is double altura && double.TryParse(parameter?.ToString(), out double factor))
|
|
{
|
|
return altura * factor;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
public class HalfWidthConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is double width)
|
|
{
|
|
return (width / 2.0) - (double.Parse(parameter.ToString()) / 2.0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
public class WidthPercentageConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is double width)
|
|
{
|
|
return width * 0.25;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
public class LevelToHeightMultiConverter : IMultiValueConverter
|
|
{
|
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (values[0] is float level && values[1] is double containerHeight)
|
|
{
|
|
return containerHeight * (level / 100);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
|
|
public class BrushToColorNameConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
|
{
|
|
if (value is SolidColorBrush brush)
|
|
{
|
|
if (brush == Brushes.Red) return "Rojo";
|
|
if (brush == Brushes.Blue) return "Azul";
|
|
if (brush == Brushes.Black) return "Negro";
|
|
if (brush == Brushes.Green) return "Verde";
|
|
if (brush == Brushes.Gray) return "Gris";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
|
{
|
|
if (value is string colorName)
|
|
{
|
|
switch (colorName)
|
|
{
|
|
case "Rojo":
|
|
return Brushes.Red;
|
|
case "Azul":
|
|
return Brushes.Blue;
|
|
case "Negro":
|
|
return Brushes.Black;
|
|
case "Verde":
|
|
return Brushes.Green;
|
|
case "Gris":
|
|
return Brushes.Gray;
|
|
}
|
|
}
|
|
return Brushes.Transparent;
|
|
}
|
|
}
|
|
|
|
public class PixelToMeter
|
|
{
|
|
// Instancia privada estática, parte del patrón Singleton
|
|
private static PixelToMeter? _instance;
|
|
public UnitConverter calc = new UnitConverter(0.01f);
|
|
|
|
// Propiedad pública estática para acceder a la instancia
|
|
public static PixelToMeter Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
_instance = new PixelToMeter();
|
|
}
|
|
return _instance;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class MeterToPixelConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value == null) return 0; // Aseguramos que el valor no sea nulo
|
|
|
|
// Convertimos el valor de entrada en un número flotante
|
|
float meters = System.Convert.ToSingle(value);
|
|
|
|
float factor = 1; // Valor por defecto del factor
|
|
|
|
// Si el parámetro no es nulo, intentamos convertirlo a float
|
|
if (parameter != null)
|
|
{
|
|
string paramStr = parameter.ToString();
|
|
|
|
// Normalizamos el parámetro para asegurar que el punto sea el separador decimal
|
|
paramStr = paramStr.Replace(',', '.');
|
|
|
|
// Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal
|
|
if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor))
|
|
{
|
|
factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa
|
|
}
|
|
}
|
|
|
|
// Calculamos los píxeles llamando a la instancia de PixelToMeter y multiplicamos por el factor
|
|
return PixelToMeter.Instance.calc.MetersToPixels(meters) * factor;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value == null) return 0; // Aseguramos que el valor no sea nulo
|
|
|
|
// Convertimos el valor de entrada en un número flotante
|
|
float pixels = System.Convert.ToSingle(value);
|
|
|
|
float factor = 1; // Valor por defecto del factor
|
|
|
|
// Si el parámetro no es nulo, intentamos convertirlo a float
|
|
if (parameter != null)
|
|
{
|
|
string paramStr = parameter.ToString();
|
|
|
|
// Normalizamos el parámetro para asegurar que el punto sea el separador decimal
|
|
paramStr = paramStr.Replace(',', '.');
|
|
|
|
// Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal
|
|
if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor))
|
|
{
|
|
factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa
|
|
}
|
|
}
|
|
|
|
return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor;
|
|
}
|
|
}
|
|
|
|
public class MarginConverter : IMultiValueConverter
|
|
{
|
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (values.Length == 4 &&
|
|
values[0] is double left &&
|
|
values[1] is double top &&
|
|
values[2] is double right &&
|
|
values[3] is double bottom)
|
|
{
|
|
return new Thickness(PixelToMeter.Instance.calc.MetersToPixels((float)left), PixelToMeter.Instance.calc.MetersToPixels((float)top), PixelToMeter.Instance.calc.MetersToPixels((float)right), PixelToMeter.Instance.calc.MetersToPixels((float)bottom));
|
|
}
|
|
return new Thickness();
|
|
}
|
|
|
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotSupportedException("ConvertBack is not supported.");
|
|
}
|
|
}
|
|
|
|
public class DistanceToMarginConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is double distance)
|
|
{
|
|
return new Thickness(0, 0, 0, PixelToMeter.Instance.calc.MetersToPixels((float)distance)); // Ajustar Bottom a 'distance'
|
|
}
|
|
return new Thickness();
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotSupportedException("ConvertBack is not supported.");
|
|
}
|
|
}
|
|
|
|
public class FloatToFormattedStringConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is float floatValue)
|
|
{
|
|
var r = floatValue.ToString("0.00", culture).Replace('.', ','); // Formatear a dos decimales
|
|
return r;
|
|
}
|
|
return value; // Devolver el valor original si no es un float
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is string stringValue && float.TryParse(stringValue.Replace(',', '.'), NumberStyles.Float, culture, out float result))
|
|
{
|
|
return result;
|
|
}
|
|
return value; // Devolver el valor original si no se puede convertir
|
|
}
|
|
}
|
|
|
|
public class DoubleToFormattedStringConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is double floatValue)
|
|
{
|
|
return floatValue.ToString("0.00", culture).Replace('.', ','); // Formatear a dos decimales
|
|
}
|
|
return value; // Devolver el valor original si no es un float
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (value is string stringValue && double.TryParse(stringValue.Replace(',', '.'), NumberStyles.Float, culture, out double result))
|
|
{
|
|
return result;
|
|
}
|
|
return value; // Devolver el valor original si no se puede convertir
|
|
}
|
|
}
|
|
|
|
|
|
public class UnitConverter
|
|
{
|
|
// La escala representa cuántos metros hay en un píxel
|
|
public float Scale { get; private set; }
|
|
|
|
|
|
public UnitConverter(float scale)
|
|
{
|
|
if (scale <= 0)
|
|
throw new ArgumentException("Scale must be greater than zero.");
|
|
|
|
Scale = scale;
|
|
}
|
|
|
|
// Convierte una distancia en metros a píxeles
|
|
public float MetersToPixels(float meters)
|
|
{
|
|
return meters / Scale;
|
|
}
|
|
|
|
// Convierte una distancia en píxeles a metros
|
|
public float PixelsToMeters(float pixels)
|
|
{
|
|
return pixels * Scale;
|
|
}
|
|
|
|
// Configurar o ajustar la escala
|
|
public void SetScale(float newScale)
|
|
{
|
|
if (newScale <= 0)
|
|
throw new ArgumentException("Scale must be greater than zero.");
|
|
|
|
Scale = newScale;
|
|
}
|
|
}
|
|
}
|