Drag And Drop
See the DragAndDropDemo.cs.
using Gridrand.Contracts;
using System;
namespace Gridrand.RimGui.Manual
{
/// <summary>
/// Drag and drop demo.
/// </summary>
class DragDropDemo : ManualBase, IManual
{
string[] names = new string[3] { "A", "B", "C", };
public DragDropDemo(ManualBaseResource p) : base(p)
{
}
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("DragInfo"))
{
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);
}
}
}
}