1 UI-Component-Hierarchy
John McCardle edited this page 2025-10-25 21:00:02 +00:00

UI Component Hierarchy

The UI Component Hierarchy defines how visual elements are structured, rendered, and managed in McRogueFace.

Quick Reference

Related Issues:

  • #122 - Parent-Child UI System (Tier 2)
  • #118 - Scene as Drawable (Tier 2)
  • #102 - Add global_position Property (Tier 1)
  • #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:

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 (Closed)

Parent-Child Relationships

Current State: No automatic parent tracking

Planned: #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:

# 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 - Object splitting bug

Common Tasks

Creating UI Elements

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:

# 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

# 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 will add optional parent tracking

Planned Improvements

#122: Parent-Child UI System

  • Add parent field to UIDrawable
  • Automatic coordinate transformation
  • Recursive visibility and opacity

#118: Scene as Drawable

  • Make Scene inherit from UIDrawable
  • Enable scene composition and transitions as animations
  • Scenes become first-class UI elements

#102: Global Position

  • Calculate absolute screen position for nested elements
  • Useful for click detection, tooltips
  • Depends on parent-child system

See Also: