Initial commit

This commit is contained in:
Bl4DiEDiEBL4
2026-02-08 21:30:32 +01:00
commit bea78417df
17 changed files with 18249 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
using System.ComponentModel;
namespace UnshackleGUI
{
/// <summary>
/// This is the object assigned to PropertyGrid.SelectedObject
/// It correctly implements ICustomTypeDescriptor.
/// </summary>
public class DynamicObject : ICustomTypeDescriptor
{
private readonly Dictionary<string, object> _values;
private readonly List<UnshackleParameter> _defs;
public DynamicObject(Dictionary<string, object> values, List<UnshackleParameter> defs)
{
_values = values;
_defs = defs;
}
public PropertyDescriptorCollection GetProperties()
{
return new DynamicCustomTypeDescriptor(_values, _defs).GetProperties();
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return GetProperties();
}
public object GetPropertyOwner(PropertyDescriptor pd) => this;
public AttributeCollection GetAttributes() => AttributeCollection.Empty;
public string GetClassName() => nameof(DynamicObject);
public string GetComponentName() => null;
public TypeConverter GetConverter() => null;
public EventDescriptor GetDefaultEvent() => null;
public PropertyDescriptor GetDefaultProperty() => null;
public object GetEditor(Type editorBaseType) => null;
public EventDescriptorCollection GetEvents() => EventDescriptorCollection.Empty;
public EventDescriptorCollection GetEvents(Attribute[] attributes) => EventDescriptorCollection.Empty;
}
internal class DynamicCustomTypeDescriptor : CustomTypeDescriptor
{
private readonly Dictionary<string, object> _values;
private readonly List<UnshackleParameter> _defs;
private PropertyDescriptorCollection _cache;
public DynamicCustomTypeDescriptor(Dictionary<string, object> values, List<UnshackleParameter> defs)
{
_values = values;
_defs = defs;
}
public override PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
if (_cache == null)
{
var props = new List<PropertyDescriptor>();
foreach (var def in _defs)
{
props.Add(new DynamicPropertyDescriptor(def, _values));
}
_cache = new PropertyDescriptorCollection(props.ToArray());
}
return _cache;
}
}
internal class DynamicPropertyDescriptor : PropertyDescriptor
{
private readonly UnshackleParameter _parameter;
private readonly Dictionary<string, object> _values;
public DynamicPropertyDescriptor(UnshackleParameter parameter, Dictionary<string, object> values)
: base(parameter.Name, null)
{
_parameter = parameter;
_values = values;
}
public override string Category => _parameter.Category;
// IMPORTANT FIX
public override Type ComponentType => typeof(object);
public override bool IsReadOnly => false;
public override Type PropertyType =>
_parameter.Type switch
{
"Bool" => typeof(bool),
"Number" => typeof(int),
_ => typeof(string)
};
public override TypeConverter Converter =>
(_parameter.Type == "Selection" && _parameter.Options != null)
? new StandardValuesConverter(_parameter.Options)
: base.Converter;
public override object GetValue(object component)
{
return _values.ContainsKey(_parameter.Name)
? _values[_parameter.Name]
: _parameter.Default;
}
public override void SetValue(object component, object value)
{
_values[_parameter.Name] = value;
OnValueChanged(component, EventArgs.Empty);
// Force grid refresh
TypeDescriptor.Refresh(component);
}
public override bool CanResetValue(object component) => true;
public override void ResetValue(object component)
{
_values[_parameter.Name] = _parameter.Default;
}
public override bool ShouldSerializeValue(object component) => true;
}
internal class StandardValuesConverter : TypeConverter
{
private readonly List<string> _values;
public StandardValuesConverter(List<string> values)
{
_values = values;
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true;
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) => true;
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(_values);
}
}
}