mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Move List elements via Drag and Drop
This commit is contained in:
@@ -36,6 +36,8 @@ internal class EntityEditor
|
|||||||
|
|
||||||
public static void ShowDefaultEntityEditor(UUID entityId, Type entityType)
|
public static void ShowDefaultEntityEditor(UUID entityId, Type entityType)
|
||||||
{
|
{
|
||||||
|
// TODO: Call custom editors here!
|
||||||
|
|
||||||
ScriptGlue.Entity_GetScriptInstance(entityId, out object instance);
|
ScriptGlue.Entity_GetScriptInstance(entityId, out object instance);
|
||||||
|
|
||||||
ShowEditor(entityType, instance);
|
ShowEditor(entityType, instance);
|
||||||
@@ -69,16 +71,17 @@ internal class EntityEditor
|
|||||||
|
|
||||||
RangeAttribute range = GetAttribute<RangeAttribute>(attributes);
|
RangeAttribute range = GetAttribute<RangeAttribute>(attributes);
|
||||||
|
|
||||||
|
// Get Min and Max Values from Type T
|
||||||
T min = ReadStaticField<T>("MinValue");
|
T min = ReadStaticField<T>("MinValue");
|
||||||
T max = ReadStaticField<T>("MaxValue");
|
T max = ReadStaticField<T>("MaxValue");
|
||||||
float speed = 1.0f;
|
float dragSpeed = 1.0f;
|
||||||
|
|
||||||
// RangeAttribute takes precedence over Minimum- and Maximum-Attribute
|
// RangeAttribute takes precedence over Minimum- and Maximum-Attribute
|
||||||
if (range != null)
|
if (range != null)
|
||||||
{
|
{
|
||||||
min = ChangeTypeSafe(range.Min);
|
min = ChangeTypeSafe(range.Min);
|
||||||
max = ChangeTypeSafe(range.Max);
|
max = ChangeTypeSafe(range.Max);
|
||||||
speed = range.Speed;
|
dragSpeed = range.Speed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -112,7 +115,7 @@ internal class EntityEditor
|
|||||||
}
|
}
|
||||||
else
|
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;
|
newValue = value;
|
||||||
}
|
}
|
||||||
@@ -134,6 +137,7 @@ internal class EntityEditor
|
|||||||
{
|
{
|
||||||
char value = (char)reference;
|
char value = (char)reference;
|
||||||
|
|
||||||
|
// TODO: Allow entering chars like '\0', '\n', etc...
|
||||||
if (ImGui.InputText(fieldName, (IntPtr)(&value), 2))
|
if (ImGui.InputText(fieldName, (IntPtr)(&value), 2))
|
||||||
newValue = value;
|
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)
|
private static object ShowListEditor(Type fieldType, object list, string fieldName)
|
||||||
{
|
{
|
||||||
object newList = DidNotChange;
|
object newList = DidNotChange;
|
||||||
@@ -389,33 +399,97 @@ internal class EntityEditor
|
|||||||
myList.Add(newElement);
|
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.SameLine(ImGui.GetWindowContentRegionMax().X - removeButtonWidth);
|
||||||
|
|
||||||
ImGui.BeginDisabled(myList == null);
|
ImGui.BeginDisabled(myList == null || myList.Count == 0);
|
||||||
|
|
||||||
if (ImGui.SmallButton("-"))
|
if (ImGui.SmallButton("-"))
|
||||||
{
|
{
|
||||||
myList!.RemoveAt(myList.Count - 1);
|
myList!.RemoveAt(myList.Count - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGuiExtension.AttachTooltip("Remove the last Element from the list.");
|
||||||
|
|
||||||
ImGui.EndDisabled();
|
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 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)
|
if (newValue != DidNotChange)
|
||||||
{
|
{
|
||||||
myList[i] = newValue;
|
myList[i] = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop after current element
|
||||||
|
ImGui.Separator();
|
||||||
|
DropTarget(i + 1, $"Drop after Element {i}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
|
|||||||
@@ -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
|
ImGui.BeginTooltip();
|
||||||
//{
|
|
||||||
// [DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
|
ImGui.TextUnformatted(tooltip);
|
||||||
// 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.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,
|
ImGui.BeginTooltip();
|
||||||
// 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; }
|
|
||||||
|
|
||||||
// return ImGui_EditFloat2(native_label, ref value, resetValues, dragSpeed, columnWidth, minValue, maxValue, true);
|
tooltipContent();
|
||||||
// }
|
|
||||||
|
ImGui.EndTooltip();
|
||||||
// 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)
|
|
||||||
//}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user