UI/ContextMenu/ContextMenuHost.razor
@using Sandbox;
@using Sandbox.UI;
@inherits Panel
@namespace Sandbox
@attribute [SpawnMenuHost.SpawnMenuMode]
@attribute [Icon("🔍")]
@attribute [Title("#spawnmenu.mode.inspect")]
@attribute [Order( 500 )]

<root>
	
    <div class="container">

        <Inspector @ref=Inspector></Inspector>

    </div>

</root>

@code
{
    Inspector Inspector = default;

    public HighlightOutline SelectedOutline;
    public HighlightOutline HoveredOutline;

    protected override void OnAfterTreeRender(bool firstTime)
    {
        base.OnAfterTreeRender(firstTime);

        //if (firstTime)
        {
            SelectedOutline ??= GameObject.AddComponent<HighlightOutline>();
            HoveredOutline ??= GameObject.AddComponent<HighlightOutline>();

            SelectedOutline.OverrideTargets = true;
            HoveredOutline.OverrideTargets = true;
        }
    }

    public override void Tick()
    {
        base.Tick();

        UpdateCursor();
        DrawHandles();
    }

    void UpdateCursor()
    {
        Style.Cursor = (Inspector?.Hovered.IsValid() ?? false) ? "pointer" : null;
    }

    protected override void OnMouseDown(MousePanelEvent e)
    {
        Sandbox.UI.InputFocus.Clear();

        if ( e.MouseButton == MouseButtons.Right )
        {
            Inspector?.WorldMouseRightDown( e );
            return;
        }

        Inspector?.WorldMouseDown( e );
    }

    protected override void OnMouseUp(MousePanelEvent e)
    {

        Inspector?.WorldMouseUp( e );
    }

    Dictionary<Component, Panel> _handles = [];

    void DrawHandles()
    {
		if ( Scene?.Camera is not { IsValid: true } )
			return;

        var objects = Scene.FindInPhysics(new Sphere( Scene.Camera.WorldPosition, 1000 ));
        var rootObjects = objects.Select( x => x.Network?.RootGameObject ).Where( x => x.IsValid() ).Distinct();

        foreach ( var o in rootObjects )
        {
            // find handles in this object
            foreach (var component in o.GetComponentsInChildren<Component>())
            {
                if (!ShouldCreateHandle(component))
                    continue;

                if ( _handles.TryGetValue(component, out var existingHandle) )
                {
                    if (existingHandle.IsValid())
                        continue;
                }

                var panel = new ComponentHandle( this, component, Inspector );
                _handles[component] = panel;
            }
        }
    }

    bool ShouldCreateHandle(Component component)
    {
        // TODO - needs a handle

        return false;
    }

}