This commit is contained in:
2026-05-02 21:08:13 +08:00
parent e02c7f5e89
commit 91bc3a269b
27 changed files with 212553 additions and 18619 deletions

View File

@@ -59,6 +59,27 @@ namespace Ichni.Editor
}
}
/// <summary>
/// 滑块控制属性,适用于 float/int 类型字段,自动生成带范围限制的 Slider 替代 InputField。
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class DynamicUISliderAttribute : DynamicUIAttribute
{
public float Min { get; set; }
public float Max { get; set; }
public bool WholeNumbers { get; set; }
public DynamicUISliderAttribute(string name = "", string group = "Default",
float min = 0f, float max = 1f, bool wholeNumbers = false,
int span = 0, float height = 0f, bool autoUpdate = false, bool readOnly = false)
: base(name, group, span, height, autoUpdate, readOnly)
{
Min = min;
Max = max;
WholeNumbers = wholeNumbers;
}
}
/// <summary>
/// 操作按钮卡片,挂载在没有任何参数的 Method() 方法上
/// </summary>

View File

@@ -73,7 +73,7 @@ namespace Ichni.Editor
// 先排变量
foreach (var field in fieldsInGroup)
{
int span = field.Attr.Span > 0 ? field.Attr.Span : SmartInferSpan(field.ValueType);
int span = GetEffectiveSpan(field);
span = Mathf.Clamp(span, 1, 3);
// 如果该行的槽被塞满了或者装不下了
@@ -83,12 +83,12 @@ namespace Ichni.Editor
currentLineBuffer.Clear();
currentSpanCount = 0;
}
// 特殊兼容:由于 GridLayoutGroup 的强制统一 cellSize, 我们如果在同一行混搭不同 Span 宽度的,反而会让它变形。
// 因此若当前这行的空间要求和前一个需求跨度不一致,也必须强行断点分层!
if (currentLineBuffer.Count > 0)
{
var lastSpan = currentLineBuffer[0].Attr.Span > 0 ? currentLineBuffer[0].Attr.Span : SmartInferSpan(currentLineBuffer[0].ValueType);
var lastSpan = GetEffectiveSpan(currentLineBuffer[0]);
if (span != lastSpan)
{
FlushLine(element, inspector, container, currentLineBuffer, GetHighestSpanRequirement(currentLineBuffer));
@@ -124,8 +124,7 @@ namespace Ichni.Editor
// 如果一行要放 3 份Span 都是 1 拼成的),那格子数量也是 3600/3=200一个
// 但是如果是独占的Span 都是 3格子数量反而应该是 1600/1=600一个
// 为了防止排版错开变形,我们通过 3 / span 来决定 Subcontainer 内部允许的等分元素数量。
int subcontainerDivision = 3 / lineSpanCapacity;
if (subcontainerDivision < 1) subcontainerDivision = 1;
int subcontainerDivision = Mathf.Max(1, Mathf.RoundToInt(3f / lineSpanCapacity));
float rowHeight = GetHighestHeightRequirement(fields);
var sub = container.GenerateSubcontainer(subcontainerDivision, rowHeight);
@@ -169,6 +168,10 @@ namespace Ichni.Editor
{
inspector.GenerateDropdown(element, sub, title, fd.ValueType, pName);
}
else if (fd.Attr is DynamicUISliderAttribute sliderAttr)
{
inspector.GenerateSlider(element, sub, title, pName, sliderAttr.Min, sliderAttr.Max, sliderAttr.WholeNumbers);
}
else // 容错给普通的 InputField
{
inspector.GenerateInputField(element, sub, title, pName, fd.Attr.AutoUpdate);
@@ -191,12 +194,17 @@ namespace Ichni.Editor
int highest = 1;
foreach (var f in fields)
{
int span = f.Attr.Span > 0 ? f.Attr.Span : SmartInferSpan(f.ValueType);
int span = GetEffectiveSpan(f);
if (span > highest) highest = span;
}
return highest;
}
private static int GetEffectiveSpan(FieldDef fd)
{
return fd.Attr.Span > 0 ? fd.Attr.Span : SmartInferSpan(fd.ValueType);
}
private static float SmartInferHeight(FieldDef fd)
{
// EmissionColorPicker 有 Toggle/RGB滑块/Intensity输入框高度明显大于 BaseColorPicker