Add "UI-Component-Hierarchy"
parent
1f06157855
commit
b8af2bd821
|
|
@ -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<std::shared_ptr<UIDrawable>>`
|
||||
|
||||
**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<std::shared_ptr<UIEntity>>`
|
||||
|
||||
**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
|
||||
Loading…
Reference in New Issue