Skip to main content

Drag And Drop

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);

// Drag target.
// Any interactive widget, like a Button, will work.
Gui.InteractiveItem();

//Mark the last widget as a drop target.
Ctx.MarkLastDropTarget("Key");

// Try dragging the last widget.
var isDraggedItem = Ctx.TryDragLast("Key", i);

Gui.NextRect(Ctx.GetLastWidgetRect()).Text($"{names[i]}");

if (isDraggedItem)
{
if (Gui.BeginAutoSizeSubWindow("DragInfo"))
{
Gui.FixedWidthText(names[i]);
Gui.EndAutoSizeSubWindow();
}
}

/// By marking the drop target with<see cref= "Context.MarkLastDropTarget(string)" />,
/// you can drop it with <see cref="Context.TryDrop(string, out object)"/>().
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}");

var widget = Gui.NextHeight(20f).Custom<InsertAreaWidget>(true);

/// Attempt to mark the drop target to the rect of <see cref="InsertAreaWidget"/>.
Ctx.MarkDropTarget("Key", Ctx.GetLastWidgetRect());

widget.Color = Ctx.CanDrop("Key") ? Color32.Green : Color32.Gray;

/// Try insertion.
if (Ctx.TryDrop("Key", out var payload))
{
var insertArrayI = (int)payload < insertI ? insertI - 1 : insertI;
Logger.Debug($"{payload} was dropped and inserted into {insertArrayI}.");
names.Move((int)payload, insertArrayI);
}
}

class InsertAreaWidget : PrimitiveWidget
{
public Color32 Color { get; set; } = Color32.Green;

public override void Build(Shaper shaper)
{
shaper.AddInnerFrameRect(Rect, 1f, Color);
}
}
}
}