Drag And Drop
See the DragDropDemo class.
public void Draw()
{
using var spaceScope = Style.SpacingYs.Begin(0f);
for (int i = 0; i < names.Length; i++)
{
using var s = Ctx.PushId(i);
DrawInsertArea(i);
Gui.Text($"{names[i]}");
// By placing the InteractiveArea in the same position as Text,
// we can make the Text itself interactive.
Gui.NextRect(Ctx.GetLastWidgetRect()).InteractiveArea();
// Drag and drop into the InteractiveArea(Text)
if (Ctx.TryDragDropLast("Key", i))
{
if (Gui.BeginAutoSizeSubWindow())
{
Gui.FixedWidthText(names[i]);
Gui.EndAutoSizeSubWindow();
}
}
/// By executing this after <see cref="Context.TryDragDropLast(string, object)"/>,
/// we enable the item being dragged to be dropped.
if (Ctx.TryDrop("Key", out var payload))
{
var tmp = names[i];
names[i] = names[(int)payload];
names[(int)payload] = tmp;
Logger.Debug($"Dropped:{i},{payload}");
}
}
DrawInsertArea(names.Length);
}
void DrawInsertArea(int insertI)
{
if (names.Length < insertI)
throw new ArgumentOutOfRangeException($"{insertI}");
Gui.NextHeight(20f).Custom<InsertAreaWidget>(true);
/// Attempt to set the drop target to the rect of <see cref="InsertAreaWidget"/> and perform the insertion.
///
/// <see cref="Context.TrySetDropTarget(string, Rect)"/> does not return true
/// unless an item is currently being dragged.
if (Ctx.TrySetDropTarget("Key", Ctx.GetLastWidgetRect()) && Ctx.TryDrop("Key", out var payload))
{
var insertArrayI = (int)payload < insertI ? insertI - 1 : insertI;
Logger.Debug($"{payload} was dropped and inserted into {insertArrayI}.");
names.MoveElement((int)payload, insertArrayI);
}
}
class InsertAreaWidget : PrimitiveWidget
{
public override void Build(Shaper shaper)
{
shaper.AddInnerFrameRect(Rect, 1f, Color32.Green);
}
}