增加颜色预设

This commit is contained in:
ww-rm
2025-04-20 16:55:14 +08:00
parent 7134aebb7f
commit 914c9d0ea3

View File

@@ -104,21 +104,21 @@ namespace SpineViewer.Utils
} }
} }
public class ResolutionConverter : SizeConverter public class ResolutionConverter : SizeConverter
{ {
private static readonly StandardValuesCollection standardValues = new(new string[] { private static readonly StandardValuesCollection standardValues = new(new Size[] {
"4096, 4096", new(4096, 4096),
"2048, 2048", new(2048, 2048),
"1024, 1024", new(1024, 1024),
"512, 512", new(512, 512),
"3840, 2160", new(3840, 2160),
"2560, 1440", new(2560, 1440),
"1920, 1080", new(1920, 1080),
"1280, 720", new(1280, 720),
"2160, 3840", new(2160, 3840),
"1440, 2560", new(1440, 2560),
"1080, 1920", new(1080, 1920),
"720, 1280", new(720, 1280),
}); });
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true; public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true;
@@ -128,16 +128,40 @@ namespace SpineViewer.Utils
public class SFMLColorConverter : ExpandableObjectConverter public class SFMLColorConverter : ExpandableObjectConverter
{ {
private class SFMLColorPropertyDescriptor : SimplePropertyDescriptor private static SFML.Graphics.Color ParseHexColor(string hex, bool includeAlpha)
{ {
public SFMLColorPropertyDescriptor(Type componentType, string name, Type propertyType) : base(componentType, name, propertyType) { } byte r = byte.Parse(hex.Substring(1, 2), NumberStyles.HexNumber);
byte g = byte.Parse(hex.Substring(3, 2), NumberStyles.HexNumber);
public override object? GetValue(object? component) => component?.GetType().GetField(Name)?.GetValue(component) ?? default; byte b = byte.Parse(hex.Substring(5, 2), NumberStyles.HexNumber);
byte a = includeAlpha ? byte.Parse(hex.Substring(7, 2), NumberStyles.HexNumber) : (byte)255;
public override void SetValue(object? component, object? value) => component?.GetType().GetField(Name)?.SetValue(component, value); return new SFML.Graphics.Color(r, g, b, a);
} }
private static PropertyDescriptorCollection pdCollection = null; private static SFML.Graphics.Color ParseShortHexColor(string hex, bool includeAlpha)
{
byte r = Convert.ToByte($"{hex[1]}{hex[1]}", 16);
byte g = Convert.ToByte($"{hex[2]}{hex[2]}", 16);
byte b = Convert.ToByte($"{hex[3]}{hex[3]}", 16);
byte a = includeAlpha ? Convert.ToByte($"{hex[4]}{hex[4]}", 16) : (byte)255;
return new SFML.Graphics.Color(r, g, b, a);
}
private static readonly StandardValuesCollection standardValues;
static SFMLColorConverter()
{
// 初始化所有 KnownColor
var knownColors = Enum.GetValues(typeof(KnownColor))
.Cast<KnownColor>()
.Select(knownColor =>
{
var color = Color.FromKnownColor(knownColor);
return new SFML.Graphics.Color(color.R, color.G, color.B, color.A);
})
.ToArray();
standardValues = new StandardValuesCollection(knownColors);
}
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{ {
@@ -149,24 +173,48 @@ namespace SpineViewer.Utils
if (value is string s) if (value is string s)
{ {
s = s.Trim(); s = s.Trim();
if (s.StartsWith("#") && s.Length == 9)
try
{ {
try // 处理 #RRGGBBAA 和 #RRGGBB 格式
if (s.StartsWith("#"))
{ {
// 解析 R, G, B, A 分量注意16进制解析 if (s.Length == 9) // #RRGGBBAA
byte r = byte.Parse(s.Substring(1, 2), NumberStyles.HexNumber); return ParseHexColor(s, includeAlpha: true);
byte g = byte.Parse(s.Substring(3, 2), NumberStyles.HexNumber); if (s.Length == 7) // #RRGGBB
byte b = byte.Parse(s.Substring(5, 2), NumberStyles.HexNumber); return ParseHexColor(s, includeAlpha: false);
byte a = byte.Parse(s.Substring(7, 2), NumberStyles.HexNumber); if (s.Length == 5) // #RGBA
return ParseShortHexColor(s, includeAlpha: true);
if (s.Length == 4) // #RGB
return ParseShortHexColor(s, includeAlpha: false);
throw new FormatException("无法解析颜色,请使用 #RRGGBBAA、#RRGGBB、#RGBA 或 #RGB 格式");
}
// 处理 R,G,B,A 和 R,G,B 格式
var parts = s.Split(',');
if (parts.Length == 3 || parts.Length == 4)
{
byte r = byte.Parse(parts[0].Trim());
byte g = byte.Parse(parts[1].Trim());
byte b = byte.Parse(parts[2].Trim());
byte a = parts.Length == 4 ? byte.Parse(parts[3].Trim()) : (byte)255;
return new SFML.Graphics.Color(r, g, b, a); return new SFML.Graphics.Color(r, g, b, a);
} }
catch (Exception ex)
{ // 尝试解析为 KnownColor
throw new FormatException("无法解析颜色,确保格式为 #RRGGBBAA", ex); var color = Color.FromName(s);
} if (color.IsKnownColor || color.IsNamedColor)
return new SFML.Graphics.Color(color.R, color.G, color.B, color.A);
throw new FormatException("无法解析颜色,请使用已知的颜色名称");
}
catch (Exception ex)
{
throw new FormatException("无法解析颜色,请检查格式", ex);
} }
throw new FormatException("格式错误,正确格式为 #RRGGBBAA");
} }
return base.ConvertFrom(context, culture, value); return base.ConvertFrom(context, culture, value);
} }
@@ -182,6 +230,21 @@ namespace SpineViewer.Utils
return base.ConvertTo(context, culture, value, destinationType); return base.ConvertTo(context, culture, value, destinationType);
} }
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true;
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) => false;
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context) => standardValues;
private class SFMLColorPropertyDescriptor : SimplePropertyDescriptor
{
public SFMLColorPropertyDescriptor(Type componentType, string name, Type propertyType) : base(componentType, name, propertyType) { }
public override object? GetValue(object? component) => component?.GetType().GetField(Name)?.GetValue(component) ?? default;
public override void SetValue(object? component, object? value) => component?.GetType().GetField(Name)?.SetValue(component, value);
}
private static PropertyDescriptorCollection pdCollection = null;
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext? context, object value, Attribute[]? attributes) public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext? context, object value, Attribute[]? attributes)
{ {
pdCollection ??= new( pdCollection ??= new(