feat(ui): D.5.3/B.1 — UiRoot payload injection + cursor drag ghost (AP-47)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1672eaa620
commit
595c4bdac4
3 changed files with 97 additions and 3 deletions
|
|
@ -141,9 +141,25 @@ public sealed class UiRoot : UiElement
|
|||
// beats even rect backgrounds. Faithful to retail's root-level MakePopup.
|
||||
ctx.BeginOverlayLayer();
|
||||
DrawOverlays(ctx);
|
||||
DrawDragGhost(ctx);
|
||||
ctx.EndOverlayLayer();
|
||||
}
|
||||
|
||||
/// <summary>Translucency of the cursor-following drag ghost. AP-47: we reuse the
|
||||
/// item's full composited icon at this alpha rather than retail's dedicated
|
||||
/// underlay-less m_pDragIcon.</summary>
|
||||
private const float GhostAlpha = 0.6f;
|
||||
|
||||
/// <summary>Paint the drag ghost at the cursor. The texture comes from the source
|
||||
/// element's <see cref="UiElement.GetDragGhost"/> so UiRoot stays item-agnostic; the
|
||||
/// ghost is NOT a tree element, so it never intercepts hit-tests.</summary>
|
||||
private void DrawDragGhost(UiRenderContext ctx)
|
||||
{
|
||||
if (DragSource?.GetDragGhost() is not { } g || g.tex == 0) return;
|
||||
ctx.DrawSprite(g.tex, MouseX - g.w / 2f, MouseY - g.h / 2f, g.w, g.h,
|
||||
0f, 0f, 1f, 1f, new Vector4(1f, 1f, 1f, GhostAlpha));
|
||||
}
|
||||
|
||||
// ── Input entry points (called from GameWindow's Silk.NET handlers) ──
|
||||
|
||||
public void OnMouseMove(int x, int y)
|
||||
|
|
@ -185,7 +201,7 @@ public sealed class UiRoot : UiElement
|
|||
if (Math.Abs(x - _pressX) > DragDistanceThreshold
|
||||
|| Math.Abs(y - _pressY) > DragDistanceThreshold)
|
||||
{
|
||||
BeginDrag(Captured, payload: null);
|
||||
BeginDrag(Captured);
|
||||
}
|
||||
}
|
||||
if (DragSource is not null)
|
||||
|
|
@ -447,8 +463,13 @@ public sealed class UiRoot : UiElement
|
|||
|
||||
// ── Drag-drop (retail event chain 0x15 → 0x21 → 0x1C → 0x3E) ────────
|
||||
|
||||
private void BeginDrag(UiElement source, object? payload)
|
||||
private void BeginDrag(UiElement source)
|
||||
{
|
||||
// Pull the payload from the source; a null payload (e.g. an empty item cell)
|
||||
// CANCELS the drag — retail's ItemList_BeginDrag only arms an occupied cell.
|
||||
var payload = source.GetDragPayload();
|
||||
if (payload is null) { _dragCandidate = false; return; }
|
||||
|
||||
DragSource = source;
|
||||
DragPayload = payload;
|
||||
var e = new UiEvent(source.EventId, source, UiEventType.DragBegin, Payload: payload);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue