diff --git a/UI-Component-Hierarchy.-.md b/UI-Component-Hierarchy.-.md new file mode 100644 index 0000000..baf82d4 --- /dev/null +++ b/UI-Component-Hierarchy.-.md @@ -0,0 +1,299 @@ +# UI Component Hierarchy + +The UI Component Hierarchy defines how visual elements are structured, rendered, and managed in McRogueFace. + +## Quick Reference + +**Related Issues:** +- [#122](../../issues/122) - Parent-Child UI System (Tier 2) +- [#118](../../issues/118) - Scene as Drawable (Tier 2) +- [#102](../../issues/102) - Add global_position Property (Tier 1) +- [#10](../../issues/10) - Visibility System with AABB + +**Key Files:** +- `src/UIDrawable.h` - Base class for all UI components +- `src/UIFrame.h` / `.cpp` - Container with children +- `src/UICaption.h` / `.cpp` - Text rendering +- `src/UISprite.h` / `.cpp` - Image/sprite rendering +- `src/UIGrid.h` / `.cpp` - Tilemap grid (see [[Grid-System]]) +- `src/UIEntity.h` / `.cpp` - Grid entities (see [[Entity-Management]]) + +**API Reference:** +- See [mcrfpy UI Classes](../../docs/api_reference_dynamic.html) in generated API docs + +## Class Hierarchy + +``` +UIDrawable (base class) +├── UIFrame - Rectangle container with children +├── UICaption - Text labels +├── UISprite - Images and sprite sheets +├── UIGrid - Tilemap rendering (see [[Grid-System]]) +└── UIEntity - Grid-based game entities +``` + +**Base Class:** `src/UIDrawable.h::UIDrawable` + +### UIDrawable (Base) + +**Common Properties:** +- `x`, `y`, `pos` - Screen position +- `w`, `h`, `size` - Dimensions +- `visible` - Show/hide flag +- `opacity` - 0.0-1.0 transparency +- `z_index` - Render order (higher = front) + +**Common Methods:** +- `move(dx, dy)` - Relative movement +- `resize(w, h)` - Resize +- `get_bounds()` - Returns (x, y, w, h) + +**Lifetime:** +- All UI objects use `std::shared_ptr` for automatic memory management +- Collections (UICollection, UIEntityCollection) hold shared_ptrs +- Removal from collection doesn't destroy object if Python still references it + +**Implementation:** `src/UIDrawable.h`, exposed via [[Python-Binding-Layer]] + +### UIFrame + +**Purpose:** Container for grouping UI elements + +**Unique Properties:** +- `children` - UICollection of child drawables +- `fill_color`, `outline_color` - Rectangle colors +- `outline_thickness` - Border width +- `clip_children` - Clipping support (opt-in) + +**Use Cases:** +- GUI panels and windows +- Button groups +- Layout containers + +**File:** `src/UIFrame.h` / `src/UIFrame.cpp` + +### UICaption + +**Purpose:** Text rendering with fonts + +**Unique Properties:** +- `text` - String to display +- `font` - Font object +- `font_size` - Text size +- `fill_color` - Text color + +**Use Cases:** +- Labels +- HUD text +- Dialogue + +**File:** `src/UICaption.h` / `src/UICaption.cpp` + +### UISprite + +**Purpose:** Image and sprite sheet rendering + +**Unique Properties:** +- `texture` - Texture object +- `sprite_index` - Index in sprite sheet +- `scale_x`, `scale_y` - Independent scaling + +**Use Cases:** +- Character sprites +- UI icons +- Backgrounds + +**File:** `src/UISprite.h` / `src/UISprite.cpp` + +### UIGrid + +**Purpose:** Tilemap rendering for roguelikes + +See [[Grid-System]] for complete documentation. + +### UIEntity + +**Purpose:** Game entities that live on grids + +See [[Entity-Management]] for complete documentation. + +## Collections + +### UICollection + +**Purpose:** Container for Frame, Caption, Sprite, Grid + +**Type:** `std::vector>` + +**Features:** +- Python sequence protocol (indexing, slicing, iteration) +- Append, remove, extend operations +- Preserves z_index order for rendering + +**File:** `src/UICollection.h` / `.cpp` + +### UIEntityCollection + +**Purpose:** Container specifically for Entity objects + +**Type:** `std::list>` + +**Why std::list?** Allows stable iteration during entity removal + +**Features:** +- Python sequence protocol +- Entity-specific operations + +**File:** `src/UIEntityCollection.h` / `.cpp` + +## Rendering Pipeline + +### Z-Index Rendering + +**Order:** +1. Scene sorts UI elements by z_index (lower = back) +2. Elements rendered in sorted order +3. Children rendered after parents (relative to parent z_index) + +**Optimization:** Dirty flag prevents re-sorting static scenes + +**Implementation:** `src/Scene.cpp::render()`, issue [#63](../../issues/63) (Closed) + +### Parent-Child Relationships + +**Current State:** No automatic parent tracking + +**Planned:** [#122](../../issues/122) - Add parent field +- Children positioned relative to parent +- Parent movement affects children +- Automatic removal from old parent when added to new + +**Workaround:** Manual coordinate management + +## Type Preservation + +### Challenge: Shared Pointer Type Loss + +When retrieving from collections, C++ shared_ptr may lose Python type info: + +```python +# Adding derived type +frame.children.append(my_sprite) # my_sprite is Sprite + +# Retrieving +obj = frame.children[0] # Returns as UIDrawable, not Sprite! +``` + +**Solution:** `RET_PY_INSTANCE` macro (see [[Python-Binding-Layer]]) + +**Issue:** [#112](../../issues/112) - Object splitting bug + +## Common Tasks + +### Creating UI Elements + +```python +import mcrfpy + +# Frame (container) +frame = mcrfpy.Frame(100, 100, 200, 150) +frame.fill_color = mcrfpy.Color(50, 50, 50) + +# Caption (text) +label = mcrfpy.Caption((10, 10), "Hello!") +label.font_size = 24 + +# Sprite (image) +sprite = mcrfpy.Sprite("player.png", 50, 50) +sprite.sprite_index = 0 # If using sprite sheet + +# Add to scene +mcrfpy.sceneUI("game").append(frame) +frame.children.append(label) +``` + +### Animating Properties + +All UIDrawable properties are animatable: + +```python +# Animate position +mcrfpy.animate(sprite, "x", 300, 1000, "ease_in_out_cubic") + +# Animate color +mcrfpy.animate(frame, "fill_color", mcrfpy.Color(255, 0, 0), 500, "linear") + +# Animate opacity +mcrfpy.animate(label, "opacity", 0.0, 800, "ease_out_quad") +``` + +See [[Animation-System]] for complete animation documentation. + +### Z-Index Layering + +```python +# Background +background = mcrfpy.Sprite("bg.png", 0, 0) +background.z_index = 0 + +# Middleground +entities_grid = mcrfpy.Grid(50, 50, 16, 16) +entities_grid.z_index = 10 + +# Foreground UI +hud_frame = mcrfpy.Frame(0, 0, 800, 50) +hud_frame.z_index = 100 + +# Add to scene (order doesn't matter, z_index controls rendering) +scene_ui = mcrfpy.sceneUI("game") +scene_ui.append(hud_frame) +scene_ui.append(background) +scene_ui.append(entities_grid) +``` + +## Design Decisions + +**Why Shared Pointers?** +- Automatic memory management +- Python can hold references independently of C++ collections +- Safe removal from collections + +**Why Vector for UICollection vs List for EntityCollection?** +- Vector: Better cache locality, random access for UI +- List: Stable iterators during removal for entities + +**Why No Automatic Parent Tracking?** +- Performance: Avoids overhead for simple use cases +- Flexibility: Manual control when needed +- Planned: [#122](../../issues/122) will add optional parent tracking + +## Related Systems + +- [[Animation-System]] - All UIDrawable properties are animatable +- [[Python-Binding-Layer]] - How UI classes exposed to Python +- [[Grid-System]] - UIGrid specifics +- [[Performance-and-Profiling]] - Rendering performance metrics + +## Planned Improvements + +**[#122](../../issues/122): Parent-Child UI System** +- Add `parent` field to UIDrawable +- Automatic coordinate transformation +- Recursive visibility and opacity + +**[#118](../../issues/118): Scene as Drawable** +- Make Scene inherit from UIDrawable +- Enable scene composition and transitions as animations +- Scenes become first-class UI elements + +**[#102](../../issues/102): Global Position** +- Calculate absolute screen position for nested elements +- Useful for click detection, tooltips +- Depends on parent-child system + +--- + +**See Also:** +- [UIDrawable API](../../docs/api_reference_dynamic.html#UIDrawable) +- [[Python-Binding-Layer]] for implementation details +- [[Adding-Python-Bindings]] to add new UI components \ No newline at end of file