# CommonUI Framework

> **API names below are illustrative.** Use `query_ue_api` and `dir()` to discover exact names before calling.

CommonUI is Epic's production UI framework (used in Lyra, Fortnite) providing platform-agnostic input routing, widget activation/deactivation stack, and gamepad/keyboard/mouse support.

## Enable CommonUI plugin
CommonUI must be enabled in the .uproject and referenced in Build.cs:
```csharp
PublicDependencyModuleNames.AddRange(new string[] {
    "CommonUI",
    "CommonInput"
});
```

## Core CommonUI concepts
- **CommonActivatableWidget**: Base widget class with Activate/Deactivate lifecycle
- **CommonActivatableWidgetStack**: LIFO stack managing widget focus and input routing
- **CommonButtonBase**: Unified button supporting gamepad, keyboard, mouse, touch
- **CommonUIActionRouter**: Routes input to the topmost active widget
- **Input routing**: Only the top widget in the stack receives input

## CommonActivatableWidget lifecycle
```cpp
// Header:
#pragma once
#include "CommonActivatableWidget.h"
#include "MyMenuWidget.generated.h"

UCLASS()
class UMyMenuWidget : public UCommonActivatableWidget
{
    GENERATED_BODY()

protected:
    virtual void NativeOnActivated() override;
    virtual void NativeOnDeactivated() override;
    virtual UWidget* NativeGetDesiredFocusTarget() const override;
};

// Source:
void UMyMenuWidget::NativeOnActivated()
{
    Super::NativeOnActivated();
    // Widget is now visible and receiving input
    // Set up bindings, play animations, etc.
}

void UMyMenuWidget::NativeOnDeactivated()
{
    Super::NativeOnDeactivated();
    // Widget is hidden and no longer receiving input
    // Clean up bindings, stop animations
}

UWidget* UMyMenuWidget::NativeGetDesiredFocusTarget() const
{
    // Return the button/widget that should be focused when this widget activates
    return StartButton;  // For gamepad navigation
}
```

## Activatable Widget Stack (managing UI layers)
```cpp
// In your HUD or GameLayout widget:
UPROPERTY(meta = (BindWidget))
UCommonActivatableWidgetStack* MenuStack;

UPROPERTY(meta = (BindWidget))
UCommonActivatableWidgetStack* ModalStack;  // For popups/dialogs

// Push widget onto stack:
UMyMenuWidget* Menu = MenuStack->AddWidget<UMyMenuWidget>();

// Pop / Deactivate:
Menu->DeactivateWidget();  // Removes from stack, returns input to previous widget
```

## CommonButtonBase (unified input button)
```cpp
UCLASS()
class UMyButton : public UCommonButtonBase
{
    GENERATED_BODY()

protected:
    virtual void NativeOnClicked() override;
    virtual void NativeOnHovered() override;
    virtual void NativeOnUnhovered() override;
};

void UMyButton::NativeOnClicked()
{
    Super::NativeOnClicked();
    // Handle click — works for mouse, gamepad A button, Enter key, touch
}
```

## Lyra UI architecture pattern
Lyra uses a layered UI system:
1. **Game Layout** (UPrimaryGameLayout): Root widget containing widget stacks
2. **UI Layers**: Game (HUD) → GameMenu (pause/inventory) → Menu (main menu) → Modal (popups)
3. **Each layer is a UCommonActivatableWidgetStack**
4. **Only the top widget in the highest-priority stack receives input**

```cpp
// Lyra-style game layout:
UCLASS()
class UMyGameLayout : public UCommonUserWidget
{
    GENERATED_BODY()
public:
    UPROPERTY(meta = (BindWidget))
    UCommonActivatableWidgetStack* GameLayer;     // HUD, crosshair

    UPROPERTY(meta = (BindWidget))
    UCommonActivatableWidgetStack* GameMenuLayer;  // Pause, inventory

    UPROPERTY(meta = (BindWidget))
    UCommonActivatableWidgetStack* MenuLayer;      // Main menu, settings

    UPROPERTY(meta = (BindWidget))
    UCommonActivatableWidgetStack* ModalLayer;     // Confirm dialogs
};
```

## Input Action binding in CommonUI
```cpp
// Bind Enhanced Input actions to UI buttons/widgets:
// In widget setup:
FBindUIActionArgs BindArgs(InputActionAsset, false,
    FSimpleDelegate::CreateUObject(this, &UMyWidget::OnActionTriggered));
BindArgs.bDisplayInActionBar = true;  // Show in action bar (console/gamepad)
RegisterUIActionBinding(BindArgs);
```

## Creating CommonUI widgets via Python
CommonUI widgets are Widget Blueprints with CommonActivatableWidget (or subclass) as the parent class. To create one programmatically:
1. Discover the widget blueprint factory and asset creation API via `query_ue_api`
2. Create factory, set parent_class to CommonActivatableWidget (or your C++ subclass)
3. Create asset, compile, save
4. Use `dir()` on the created asset to explore available properties at runtime

## Common patterns
- **Pause menu**: Push to GameMenuLayer, set ActivationPolicy to WhenAdded, handle back button to deactivate
- **Settings menu**: Nested stacks for tabs (Graphics, Audio, Controls)
- **Confirmation dialog**: Push to ModalLayer with OK/Cancel buttons
- **Action bar**: Auto-populated from registered UI action bindings (shows gamepad prompts)
- **Platform-specific input icons**: CommonUI handles icon swapping (gamepad ↔ keyboard) automatically

## Naming conventions
- WBP_ prefix for widget Blueprints: WBP_PauseMenu, WBP_HUD, WBP_Inventory
- U prefix for C++ widgets: UMyMenuWidget, UMyButton

## Critical rules
- Add "CommonUI" and "CommonInput" to Build.cs
- Set DefaultInputType in CommonInputSettings (Gamepad/Mouse/Touch)
- Override NativeGetDesiredFocusTarget() for gamepad navigation — without it, nothing is focused
- Use DeactivateWidget() to pop from stack (not RemoveFromParent)
- CommonUI requires ActivatableWidget as base — regular UUserWidget won't route input correctly
- Use `query_ue_api` to discover CommonUI class APIs; use `dir()` in `execute_python` to inspect objects at runtime
