Rewrite property panel to adapt to ruleset config.

This commit is contained in:
2023-07-27 22:07:20 +08:00
parent 9b091a0084
commit bc51a45df8
39 changed files with 825 additions and 298 deletions

View File

@@ -0,0 +1,102 @@
using Cryville.Common.ComponentModel;
using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace Cryville.Crtr.Config {
public interface IPropertyAdapter {
string Category { get; }
string Name { get; }
PropertyType Type { get; }
object[] Range { get; }
object GetValue();
void SetValue(object value);
object MapValue(object value);
bool SetMapped { get; }
object MapValueInverse(object value);
}
public enum PropertyType {
Unknown,
Number,
SteppedNumber,
Boolean,
String,
}
public class DefaultPropertyAdapter : IPropertyAdapter {
readonly object _target;
readonly PropertyInfo _prop;
readonly string m_category;
public string Category { get { return m_category; } }
readonly string m_name;
public string Name { get { return m_name; } }
readonly PropertyType m_type = PropertyType.Unknown;
public PropertyType Type { get { return m_type; } }
readonly object[] m_range;
public object[] Range { get { return m_range; } }
public object GetValue() { return _prop.GetValue(_target, null); }
public void SetValue(object value) { _prop.SetValue(_target, value, null); }
double _precision;
double _step;
bool _logarithmic;
public object MapValue(object value) {
if (Type == PropertyType.Number || Type == PropertyType.SteppedNumber) {
var result = (double)value;
if (_step != 0) result *= _step;
if (_logarithmic) result = Math.Pow(Math.E, result);
if (_precision != 0) result = Math.Round(result / _precision) * _precision;
return Convert.ChangeType(result, _prop.PropertyType);
}
return value;
}
public bool SetMapped { get { return true; } }
public object MapValueInverse(object value) {
if (Type == PropertyType.Number || Type == PropertyType.SteppedNumber) {
var result = Convert.ToDouble(value);
if (_logarithmic) result = Math.Log(result);
if (_step != 0) result /= _step;
return result;
}
return value;
}
public DefaultPropertyAdapter(object target, PropertyInfo prop) {
_target = target;
_prop = prop;
var attrs = prop.GetCustomAttributes(typeof(CategoryAttribute), true);
if (attrs.Length > 0) m_category = ((CategoryAttribute)attrs.Single()).Category;
m_name = prop.Name;
if (prop.PropertyType == typeof(bool)) m_type = PropertyType.Boolean;
else if (prop.PropertyType == typeof(char)) throw new NotSupportedException();
else if (prop.PropertyType.IsPrimitive) {
m_type = prop.GetCustomAttributes(typeof(StepAttribute), true).Length > 0
? PropertyType.SteppedNumber
: PropertyType.Number;
var attr = prop.GetCustomAttributes(typeof(RangeAttribute), true);
if (attr.Length > 0) {
var u = (RangeAttribute)attr.Single();
m_range = new object[] { u.Min, u.Max };
}
attr = prop.GetCustomAttributes(typeof(PrecisionAttribute), true);
if (attr.Length > 0) {
var u = (PrecisionAttribute)attr.Single();
_precision = u.Precision;
}
attr = prop.GetCustomAttributes(typeof(StepAttribute), true);
if (attr.Length > 0) {
var u = (StepAttribute)attr.Single();
_step = u.Step;
}
attr = prop.GetCustomAttributes(typeof(LogarithmicScaleAttribute), true);
if (attr.Length > 0) {
_logarithmic = true;
}
}
else if (prop.PropertyType == typeof(string)) m_type = PropertyType.String;
else return;
}
}
}