Move List elements via Drag and Drop

This commit is contained in:
Simon Lübeß
2023-11-22 19:28:02 +01:00
parent 872a400966
commit 0257b93c7b
2 changed files with 113 additions and 46 deletions
+83 -9
View File
@@ -36,6 +36,8 @@ internal class EntityEditor
public static void ShowDefaultEntityEditor(UUID entityId, Type entityType)
{
// TODO: Call custom editors here!
ScriptGlue.Entity_GetScriptInstance(entityId, out object instance);
ShowEditor(entityType, instance);
@@ -69,16 +71,17 @@ internal class EntityEditor
RangeAttribute range = GetAttribute<RangeAttribute>(attributes);
// Get Min and Max Values from Type T
T min = ReadStaticField<T>("MinValue");
T max = ReadStaticField<T>("MaxValue");
float speed = 1.0f;
float dragSpeed = 1.0f;
// RangeAttribute takes precedence over Minimum- and Maximum-Attribute
if (range != null)
{
min = ChangeTypeSafe(range.Min);
max = ChangeTypeSafe(range.Max);
speed = range.Speed;
dragSpeed = range.Speed;
}
else
{
@@ -112,7 +115,7 @@ internal class EntityEditor
}
else
{
if (ImGui.DragScalar(fieldName, dataType, (IntPtr)(&value), speed, (IntPtr)(&min), (IntPtr)(&max)))
if (ImGui.DragScalar(fieldName, dataType, (IntPtr)(&value), dragSpeed, (IntPtr)(&min), (IntPtr)(&max)))
{
newValue = value;
}
@@ -134,6 +137,7 @@ internal class EntityEditor
{
char value = (char)reference;
// TODO: Allow entering chars like '\0', '\n', etc...
if (ImGui.InputText(fieldName, (IntPtr)(&value), 2))
newValue = value;
}
@@ -359,6 +363,12 @@ internal class EntityEditor
}
}
struct ListPayload
{
public IList List;
public int Element;
}
private static object ShowListEditor(Type fieldType, object list, string fieldName)
{
object newList = DidNotChange;
@@ -389,33 +399,97 @@ internal class EntityEditor
myList.Add(newElement);
}
ImGui.SetTooltip("Add a new Element at the end of the list.");
ImGuiExtension.AttachTooltip("Add a new Element at the end of the list.");
ImGui.SameLine(ImGui.GetWindowContentRegionMax().X - removeButtonWidth);
ImGui.BeginDisabled(myList == null);
ImGui.BeginDisabled(myList == null || myList.Count == 0);
if (ImGui.SmallButton("-"))
{
myList!.RemoveAt(myList.Count - 1);
}
ImGuiExtension.AttachTooltip("Remove the last Element from the list.");
ImGui.EndDisabled();
ImGui.SetTooltip("Remove the last Element from the list.");
if (listOpen)
if (listOpen && myList != null)
{
for (int i = 0; i < myList?.Count; i++)
void DropTarget(int insertIndex, string tooltip)
{
if (ImGui.BeginDragDropTarget())
{
ImGui.SetTooltip(tooltip);
var payloadPtr = ImGui.AcceptDragDropPayload("SCRIPT_EDITOR_LIST_ELEMENT");
unsafe
{
if (payloadPtr.NativePtr != null)
{
ListPayload payload = *(ListPayload*)(payloadPtr.Data);
// Make sure the index is still correct
if (payload.Element < myList.Count)
{
object item = myList[payload.Element];
myList.RemoveAt(payload.Element);
if (payload.Element >= insertIndex)
myList.Insert(insertIndex, item);
else
// If the original index is before the insert index, the insert index will be moved after removing the element
// thus we have to subtract one.
myList.Insert(insertIndex - 1, item);
}
}
}
ImGui.EndDragDropTarget();
}
}
// Drop at index 0
ImGui.Separator();
DropTarget(0, "Drop before Element 0.");
for (int i = 0; i < myList.Count; i++)
{
object element = myList[i];
object newValue = ShowFieldEditor(element, element.GetType(), $"Element {i}");
// A Bullet point to grab the element
ImGui.Bullet();
if (ImGui.BeginDragDropSource(ImGuiDragDropFlags.SourceAllowNullID))
{
unsafe
{
ListPayload payload = new() { List = myList, Element = i };
ImGui.SetDragDropPayload("SCRIPT_EDITOR_LIST_ELEMENT", (IntPtr)(&payload), (uint)sizeof(ListPayload));
}
ImGui.SetTooltip($"Move Element {i}");
ImGui.EndDragDropSource();
}
DropTarget(i, $"Drop before Element {i}.");
ImGui.SameLine();
object newValue = ShowFieldEditor(element, element.GetType(), $"Element {i}");
if (newValue != DidNotChange)
{
myList[i] = newValue;
}
// Drop after current element
ImGui.Separator();
DropTarget(i + 1, $"Drop after Element {i}.");
}
ImGui.TreePop();
+30 -37
View File
@@ -34,43 +34,36 @@ public static class ImGuiDataTypeExtension
}
}
//namespace ImGuiNET;
public static class ImGuiExtension
{
/// <summary>
/// A helper function to attach a tooltip to the previous item. It automatically checks IsItemHovered before showing a tooltip with the given text.
/// </summary>
/// <param name="tooltip">The text to be displayed in the tooltip.</param>
public static void AttachTooltip(string tooltip)
{
if (!ImGui.IsItemHovered())
return;
//public static unsafe partial class ImGui
//{
// [DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
// private static extern unsafe bool ImGui_EditFloat2(byte* label, ref float2 value, float2 resetValues, float dragSpeed, float columnWidth, float2 minValue, float2 maxValue, bool2 componentEnabled);
ImGui.BeginTooltip();
ImGui.TextUnformatted(tooltip);
ImGui.EndTooltip();
}
/// <summary>
/// A helper function to attach a tooltip to the previous item. It automatically checks IsItemHovered before showing a tooltip with the given content.
/// </summary>
/// <param name="tooltipContent">A method that will be called to show the content of the tooltip.</param>
public static void AttachTooltip(Action tooltipContent)
{
if (!ImGui.IsItemHovered())
return;
// public static bool EditFloat2(string label, ref float2 value, float2 resetValues = default, float dragSpeed = 0.1f,
// float columnWidth = 100f, float2 minValue = default, float2 maxValue = default)
// {
// byte* native_label;
// int label_byteCount = 0;
// if (label != null)
// {
// label_byteCount = Encoding.UTF8.GetByteCount(label);
// if (label_byteCount > Util.StackAllocationSizeLimit)
// {
// native_label = Util.Allocate(label_byteCount + 1);
// }
// else
// {
// byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
// native_label = native_label_stackBytes;
// }
// int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount);
// native_label[native_label_offset] = 0;
// }
// else { native_label = null; }
ImGui.BeginTooltip();
// return ImGui_EditFloat2(native_label, ref value, resetValues, dragSpeed, columnWidth, minValue, maxValue, true);
// }
// public static bool EditFloat2(string label, ref float2 value, float2 resetValues, float dragSpeed,
// float columnWidth, float2 minValue, float2 maxValue, bool2 componentEnabled)
// {
// return ImGui_EditFloat2(label, ref value, resetValues, dragSpeed, columnWidth, minValue, maxValue, true);
// }
// //ImGui_EditFloat2(char8* label, ref float2 value, float2 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float2 minValue = .Zero, float2 maxValue = .Zero, bool2 componentEnabled = true)
//}
tooltipContent();
ImGui.EndTooltip();
}
}