项目文件夹

文件
2026-07-13 13:13:17 +08:00

268 行
8.2 KiB
C#

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
using ImGuiNET;
using T3.Core.Operator;
using T3.Editor.Gui.InputUi.VectorInputs;
using T3.Editor.Gui.Interaction;
using T3.Editor.UiModel.InputsAndTypes;
namespace T3.Editor.Gui.InputUi.ListInputs;
/// <summary>
/// Provides a generic UI for editing lists of base value types like int, float and string.
/// </summary>
internal abstract class ListInputValueUi<T> : InputValueUi<T>
{
protected override void DrawReadOnlyControl(string name, ref T list)
{
string outputString;
if (list == null)
{
outputString = "NULL";
}
else
{
lock (list)
{
outputString = string.Join(", ", list);
}
}
ImGui.TextUnformatted($"{outputString}");
}
protected InputEditStateFlags DrawListInputControl<TT>(Symbol.Child.Input input, ref List<TT> list)
{
// Handle missing or empty list
if (list == null)
{
if (ImGui.Button("Create"))
{
list = [];
return InputEditStateFlags.Modified | InputEditStateFlags.Finished;
}
return InputEditStateFlags.Nothing;
}
if (list.Count == 0)
{
if (ImGui.Button("+"))
{
if (input.IsDefault)
{
list = [];
input.IsDefault = false;
}
if (typeof(TT) == typeof(string))
{
list.Add((TT)(object)string.Empty); // ensures it's a valid string
}
else
{
list.Add(default);
}
return InputEditStateFlags.ModifiedAndFinished;
}
return InputEditStateFlags.Nothing;
}
if (ImGui.Button("Clear all"))
{
if (input.IsDefault)
{
list = [];
input.IsDefault = false;
}
else
{
list.Clear();
}
return InputEditStateFlags.ModifiedAndFinished;
}
// List...
if (!_isDragging && _listOrderWhileDragging.Count != list.Count)
{
_listOrderWhileDragging.Clear();
for (var index = 0; index < list.Count; index++)
{
_listOrderWhileDragging.Add(index);
}
}
var cloneIfModified = input.IsDefault;
var modified = InputEditStateFlags.Nothing;
var completedDragging = false;
for (var index = 0; index < list.Count; index++)
{
var dragIndex = _isDragging
? _listOrderWhileDragging[index]
: index;
ImGui.PushID(dragIndex);
ImGui.AlignTextToFramePadding();
ImGui.Button($"{dragIndex}.");
if (ImGui.IsItemActive())
{
_isDragging = true;
var itemMin = ImGui.GetItemRectMin();
var itemMax = ImGui.GetItemRectMax();
var mouseY = ImGui.GetMousePos().Y;
var halfHeight = ImGui.GetItemRectSize().Y / 2;
var indexDelta = 0;
if (mouseY < itemMin.Y - halfHeight && index > 0)
{
indexDelta = -1;
}
else if (mouseY > itemMax.Y + halfHeight && index < list.Count - 1)
{
indexDelta = 1;
}
if (indexDelta != 0)
{
if (cloneIfModified)
{
list = [..list];
cloneIfModified = false;
input.IsDefault = false;
}
var newIndex = index + indexDelta;
if (newIndex >= 0 && index < list.Count && newIndex < list.Count)
{
(list[newIndex], list[index]) = (list[index], list[newIndex]);
(_listOrderWhileDragging[newIndex], _listOrderWhileDragging[index]) =
(_listOrderWhileDragging[index], _listOrderWhileDragging[newIndex]);
}
}
}
if (ImGui.IsItemDeactivated())
{
completedDragging = true;
}
ImGui.SameLine(30 * T3Ui.UiScaleFactor);
var f = list[index];
var ff = f;
var paddingForEditAndInsert = ImGui.GetFrameHeight() * 2;
var additionalPadding = 10;
var width = ImGui.GetContentRegionAvail().X - ImGui.GetCursorPosX() - paddingForEditAndInsert - additionalPadding;
var size = new Vector2(width, 0);
var r = InputEditStateFlags.Nothing;
//var r = SingleValueEdit.Draw(ref ff, new Vector2(300 * T3Ui.UiScaleFactor,0));
switch (ff)
{
case float floatValue:
{
r = SingleValueEdit.Draw(ref floatValue, size);
if (r != InputEditStateFlags.Nothing)
{
ff = (TT)(object)floatValue;
}
break;
}
case int intValue:
{
r = SingleValueEdit.Draw(ref intValue, size);
if (r != InputEditStateFlags.Nothing)
ff = (TT)(object)intValue;
break;
}
case Vector4 colorValue:
{
var rightPadding = ImGui.GetFrameHeight() * 3;
r = Vector4InputUi.DrawColorInput(ref colorValue, false, rightPadding);
if (r != InputEditStateFlags.Nothing)
ff = (TT)(object)colorValue;
break;
}
case string stringValue:
{
if (ImGui.InputText("##textEdit", ref stringValue, 1024))
{
r |= InputEditStateFlags.Modified;
ff = (TT)(object)stringValue;
}
break;
}
}
ImGui.SameLine();
var didChangeOrder = false;
if (ImGui.Button("×"))
{
r |= InputEditStateFlags.ModifiedAndFinished;
if (cloneIfModified)
{
list = [..list];
cloneIfModified = false;
input.IsDefault = false;
}
list.RemoveAt(index);
didChangeOrder = true;
}
ImGui.SameLine();
if (ImGui.Button("+"))
{
r |= InputEditStateFlags.ModifiedAndFinished;
if (cloneIfModified)
{
list = [..list];
cloneIfModified = false;
input.IsDefault = false;
}
list.Insert(index, ff);
didChangeOrder = true;
}
if (r != InputEditStateFlags.Nothing)
{
if (!didChangeOrder)
{
if (cloneIfModified)
{
list = [..list];
cloneIfModified = false;
input.IsDefault = false;
}
list[index] = ff;
}
modified |= r;
}
ImGui.PopID();
}
if (completedDragging)
{
_isDragging = false;
_listOrderWhileDragging.Clear();
modified |= InputEditStateFlags.Modified;
}
return modified;
}
private readonly List<int> _listOrderWhileDragging = [];
private bool _isDragging;
}