<!-- SUMMARY -->
# UMG Widgets — Quick Reference
- **Create WBP**: `query_ue_api('WidgetBlueprintFactory')` to find the factory, set parent class to UserWidget
- **WidgetTree (PREFERRED)**: `helpers.build_widget_tree_from_spec(wbp, json_spec)` — declarative JSON → full widget hierarchy in one call
- **WidgetTree (manual)**: access via widget blueprint's `widget_tree` property → `construct_widget(Class, Name)` → set `root_widget` → `add_child(child)`
- **Widget-type variables**: `query_ue_api('BlueprintEditorLibrary type')` for type helpers — never construct EdGraphPinType manually
- **Slots**: `add_child()` returns a Slot with anchors, position, size, alignment, padding — slot type depends on parent panel
- **Button events**: `component_event` node type — `{"type":"component_event", "component":"Btn_Play", "delegate":"OnClicked"}`
- **Widget events**: `PreConstruct` (editor+runtime), `Construct` (runtime), `OnInitialized` (runtime), `Destruct`
- **WidgetSwitcher**: shows one child panel at a time, selected by index
- **Discover widgets**: `query_ue_api('UWidget')` and `query_ue_api('UPanelWidget')` to find subclasses
- **NEVER** `open_editor_for_asset()` — crashes editor
- For detailed slot/anchor/positioning reference → see **widget_layout** knowledge module
<!-- END SUMMARY -->

# UMG Widget Blueprints — Workflow & Concepts

All widget operations use `execute_python` with `import unreal`.
**NEVER call `open_editor_for_asset()`** — crashes the editor.

## Step 1: Create Widget Blueprint

Widget Blueprints require a dedicated factory class. `query_ue_api('WidgetBlueprintFactory')` to find it, then instantiate it.

**Workflow:**
1. `query_ue_api('WidgetBlueprintFactory')` to find the factory class
2. Set the factory's `parent_class` to UserWidget
3. Use the asset tools subsystem to create the asset with the factory
4. If the asset already exists, load it instead of creating a new one

**Naming convention**: prefix widget blueprints with `WBP_` (e.g. `WBP_MainMenu`).

**Discovery approach**: `query_ue_api('WidgetBlueprintFactory')`, then use `dir()` on the factory instance to inspect its properties.

## Step 2: Build WidgetTree (Visual Layout)

### PREFERRED: BuildWidgetTreeFromSpec (Declarative JSON)

Use `UNDBlueprintHelpers.build_widget_tree_from_spec(widget_bp, json_spec)` for the fastest, most reliable widget tree construction. This builds the entire widget hierarchy from a single JSON spec — no manual construct_widget/add_child/slot calls needed.

```python
import unreal, json
helpers = unreal.UNDBlueprintHelpers

spec = json.dumps({"widgets": [
    {"class": "CanvasPanel", "name": "RootCanvas", "is_root": True, "children": [
        {"class": "VerticalBox", "name": "MainLayout", "slot": {"anchors": {"minimum": [0.5,0.5], "maximum": [0.5,0.5]}, "alignment": [0.5,0.5], "position": [0,0], "size": [400,300]}, "children": [
            {"class": "TextBlock", "name": "TitleText", "properties": {"text": "Game Title"}, "slot": {"padding": [0,0,0,20]}},
            {"class": "Button", "name": "Btn_Play", "children": [
                {"class": "TextBlock", "name": "Btn_Play_Label", "properties": {"text": "Play"}}
            ]},
            {"class": "Button", "name": "Btn_Quit", "children": [
                {"class": "TextBlock", "name": "Btn_Quit_Label", "properties": {"text": "Quit"}}
            ]}
        ]}
    ]}
]})

result = helpers.build_widget_tree_from_spec(widget_bp, spec)
print(result)  # JSON with success, widgets_created, errors, warnings
```

**Spec format:**
- `class` — widget class name (CanvasPanel, VerticalBox, TextBlock, Button, Image, ProgressBar, etc.)
- `name` — unique name within the tree
- `is_root` — set True on the root widget (exactly one)
- `properties` — dict of property_name → value (set via reflection)
- `slot` — slot properties (anchors, position, size, alignment, padding — depends on parent panel)
- `children` — nested widget specs

Class names support fuzzy matching — "TextBlock", "UTextBlock", "text_block" all resolve correctly.

### Manual Approach (for complex cases)

The **WidgetTree** is the design-time visual hierarchy of a Widget Blueprint. Access it via the widget blueprint's `widget_tree` property.

**Core concepts:**
- `construct_widget(WidgetClass, Name)` — creates a widget inside the tree. Use this for ALL widgets — never regular constructors.
- `root_widget` — must be set before adding children. Root is typically a panel (CanvasPanel for absolute positioning, VerticalBox/HorizontalBox for auto-layout).
- `add_child(child)` — adds a child widget to a panel and **returns a Slot object** for positioning.

**Discovery approach**: use `dir()` on the WidgetTree object to see all available methods. `query_ue_api('WidgetTree construct_widget')` to find WidgetTree API, `query_ue_api('UPanelWidget')` to find panel classes.

### Slots — Positioning Children

Every `add_child()` call returns a **Slot** object. The slot type depends on the parent panel:
- **CanvasPanel slots** — absolute positioning: anchors, position, size, alignment, offsets
- **VerticalBox/HorizontalBox slots** — auto-layout: horizontal/vertical alignment, padding, size rules (auto/fill)

**Key slot concepts:**
- **Anchors** — define which point of the parent the widget is relative to (0,0 = top-left, 1,1 = bottom-right, 0.5,0.5 = center). Minimum and maximum anchors can differ for stretch behavior.
- **Alignment** — pivot point within the widget itself (0.5, 0.5 = centered)
- **Position/Offsets** — pixel offset from the anchor point
- **Size** — desired size in pixels (CanvasPanel) or fill/auto rules (Box layouts)
- **Padding** — spacing around the widget (left, top, right, bottom)

**Discovery approach**: use `dir()` on the slot object returned by `add_child()` to see available positioning methods. `query_ue_api('CanvasPanel_Slot')` or `query_ue_api('VerticalBox_Slot')` to find slot classes. Discover anchor/vector/margin struct construction via `dir()`.

### Widget Hierarchy Pattern

A typical WidgetTree hierarchy:
- **CanvasPanel** (root) — absolute positioning container
  - **VerticalBox** — stacks children vertically
    - **Button** — clickable, single-child wrapper
      - **TextBlock** — displays text
    - **Button**
      - **TextBlock**
  - **Image** — displays a texture
  - **WidgetSwitcher** — shows one child at a time

**Single-child wrappers** (SizeBox, Border, ScaleBox, Button) accept only ONE child. Panels (CanvasPanel, VerticalBox, HorizontalBox, WidgetSwitcher, Overlay) accept multiple.

## Step 3: Add Widget-Type Variables (for graph access)

To reference widgets from Blueprint graphs (e.g., bind a Button's OnClicked event), you need **member variables** with the correct type.

**Key rules:**
- **NEVER construct `EdGraphPinType` manually** — always use library helper methods
- For widget/UObject references, use the appropriate type helper that accepts a class
- For basic types (bool, int, real, string, name, text), use the appropriate type helper that accepts a type name
- For struct types, use the appropriate type helper that accepts a struct object

**Workflow:**
1. `query_ue_api('BlueprintEditorLibrary type')` to find type helper methods
2. Create the correct pin type for your widget class (e.g., Button, TextBlock, WidgetSwitcher)
3. Check if variable already exists before adding
4. Add the variable via the library's add-member-variable method
5. **MUST compile the blueprint** after adding variables — variables are not usable in graphs until compiled

**Discovery approach**: `query_ue_api('BlueprintEditorLibrary type')` to find type helpers and variable methods. Use `dir()` on the library to discover exact method names.

## Step 4: Build Graphs (Button Events, Logic)

Widget graphs use the same `build_graph_from_spec` as regular Blueprints. The key addition is the **`component_event`** node type for binding widget delegate events.

### component_event Node Type

Use `component_event` to create event nodes bound to widget delegates (OnClicked, OnPressed, etc.).

**Required fields:**
- `type` — must be `"component_event"`
- `component` — member variable name (e.g. `"Btn_Play"`) — the variable MUST exist and the BP MUST be compiled before graph building
- `delegate` — delegate name on the widget class (e.g. `"OnClicked"`, `"OnPressed"`, `"OnReleased"`, `"OnHovered"`, `"OnUnhovered"`)

**Example spec node:**
```json
{"id": "on_play", "type": "component_event", "component": "Btn_Play", "delegate": "OnClicked", "x": 0, "y": 0}
```

**Works with ANY widget delegate**, not just Button. `query_ue_api('Button delegate')` or `query_ue_api('CheckBox delegate')` to discover available delegates on a specific widget class.

### Widget Lifecycle Events

Use regular `event` node type (not `component_event`) for lifecycle events:

| Event | When it fires |
|-------|--------------|
| `PreConstruct` | Editor preview AND runtime — fires in both contexts |
| `Construct` | Runtime only — when widget is added to viewport or parent |
| `OnInitialized` | Runtime only — called once after construction |
| `Destruct` | Runtime only — when widget is removed |

## Step 5: Compile & Save

After all WidgetTree construction and graph building:
1. Compile the blueprint — `query_ue_api('compile blueprint')` to find compile methods
2. Save the asset — `query_ue_api('save asset')` to find save methods

**Always compile + save as the final step.**

## WidgetSwitcher Pattern (Multi-Panel UI)

**WidgetSwitcher** is a panel that shows exactly one child at a time, selected by index. Use it for tabbed UIs, menu screens, multi-step flows.

**Workflow:**
1. Create a WidgetSwitcher in the WidgetTree
2. Add child panels — each becomes an index (0, 1, 2, ...)
3. Children can be engine widgets (CanvasPanel, VerticalBox) or custom Widget Blueprints
4. Switch visible panel by calling the switcher's set-active-index method from a graph

**Discovery approach**: `query_ue_api('WidgetSwitcher')` to find its methods and properties.

## Custom / Reusable Widgets in WidgetTree

`construct_widget()` works with ANY UWidget subclass — including your own Widget Blueprints.

**To embed a custom widget inside another widget's tree:**
1. Load the custom Widget Blueprint asset
2. Compile it (must be compiled before embedding)
3. Get its `generated_class()` — this is the UClass to pass to `construct_widget()`
4. Add as child like any other widget

This is the **design-time** approach — widgets are baked into the WidgetTree at edit time.
For **runtime** instantiation (dynamic lists, pooling), use `CreateWidget` + `AddChild` in Blueprint graphs instead.

## Discovering Widget APIs

Use `query_ue_api` with these keywords, then `dir(unreal.ClassName)` to inspect methods:

| What you need | query_ue_api keyword |
|---|---|
| Widget blueprint factory | `WidgetBlueprintFactory` |
| Widget base classes | `UWidget` |
| Panel base classes | `UPanelWidget` |
| Type helpers for variables | `BlueprintEditorLibrary type` |
| WidgetTree API | `WidgetTree construct_widget` |
| Slot classes | `CanvasPanel_Slot`, `VerticalBox_Slot` |
| Widget delegates | `Button delegate`, `CheckBox delegate` |
| WidgetSwitcher | `WidgetSwitcher` |

## CRITICAL RULES
- **PREFER** `build_widget_tree_from_spec()` over manual WidgetTree construction — fewer errors, one call
- **NEVER** `open_editor_for_asset()` — crashes in automated context
- **NEVER** construct `EdGraphPinType` manually — `query_ue_api('BlueprintEditorLibrary type')` for type helpers
- ALWAYS set `root_widget` before adding children (manual approach)
- ALWAYS compile the blueprint after adding member variables and BEFORE graph building
- ALWAYS compile + save at the end
- Use `construct_widget()` for ALL widgets inside a WidgetTree (manual approach) — never regular constructors
- Names must be unique within a WidgetTree — duplicates cause silent failures
- Single-child wrappers (SizeBox, Border, ScaleBox, Button) accept only ONE child
- Widget lifecycle: `PreConstruct` (editor+runtime), `Construct` (runtime only), `Destruct`, `OnInitialized`
- Widget delegate events: use `component_event` node type with `component` + `delegate` fields
- For detailed slot/anchor/positioning → see **widget_layout** knowledge module
