Context Menus

The context menu system lets actors provide right-click menus that are rendered as web overlays. Any actor implementing IContextMenuProvider can supply menu items.

Architecture

Alt + Right-Click
      │
      ▼
  Line Trace (from cursor position)
      │
      ▼
  Hit Actor → implements IContextMenuProvider?
      │
      ▼ Yes
  UContextMenuManager::TryOpenContextMenu()
      │
      ▼
  Open "context-menu" overlay
  Send "context-menu:open" event with items
      │
      ▼
  User selects item → "context-menu:select" sent back
      │
      ▼
  IContextMenuProvider::OnContextMenuAction(ActionId)

C++ Interface — IContextMenuProvider

UINTERFACE(MinimalAPI, Blueprintable)
class UContextMenuProvider : public UInterface
{
    GENERATED_BODY()
};

class IContextMenuProvider
{
    GENERATED_BODY()
public:
    virtual FString GetContextMenuDisplayName() const = 0;
    virtual TArray<FContextMenuItem> GetContextMenuItems() const = 0;
    virtual void OnContextMenuAction(const FString& ActionId) = 0;
};

FContextMenuItem

USTRUCT(BlueprintType)
struct FContextMenuItem
{
    GENERATED_BODY()

    UPROPERTY() FString ActionId;
    UPROPERTY() FString Label;
    UPROPERTY() FString Icon;     // Key into icon map (search, trash, edit, etc.)
    UPROPERTY() bool bEnabled;
    UPROPERTY() bool bDestructive;
};

Example — ADynamicBlock

ADynamicBlock implements IContextMenuProvider to provide block-specific actions:

FString ADynamicBlock::GetContextMenuDisplayName() const
{
    return FString::Printf(TEXT("Block (%s)"), *BlockId);
}

TArray<FContextMenuItem> ADynamicBlock::GetContextMenuItems() const
{
    return {
        { "inspect", "Inspect Block", "search", true, false },
        { "copy",    "Copy Block",    "copy",   true, false },
        { "delete",  "Delete Block",  "trash",  true, true  },
    };
}

void ADynamicBlock::OnContextMenuAction(const FString& ActionId)
{
    if (ActionId == "delete") { Destroy(); }
    // Handle other actions...
}

Overlay Side

The context menu overlay (overlays/core/context-menu/) renders the ContextMenu component from @grids/ui:

grids.on('context-menu:open', (data) => {
  // data: { displayName, screenX, screenY, items }
  setMenu(data);
});

// When user selects an item:
grids.send('context-menu:select', { actionId });

Available Icons

The ContextMenu component maps icon keys to emoji:

KeyIconKeyIcon
search🔍edit✏️
handsettings⚙️
copy📋infoℹ️
trash🗑️star
lock🔒download📥