pub struct ObjectNode { /* private fields */ }Expand description
Additive LVGL-like object tree node.
ObjectNode mirrors the current widget-tree ownership shape while keeping
object metadata in the node layer. Existing WidgetNode
users remain source-compatible; new parity work can opt into this richer
carrier.
§LPAR-04 handler storage
Each node owns three per-phase handler lists:
- Trickle handlers run root→target before the target phase.
- Target handlers run at the target node.
- Bubble handlers run target→root after the target phase, but only
while the node has
ObjectFlags::EVENT_BUBBLEset.
Handlers are closures stored as Box<dyn FnMut(…)> and are invoked in
registration order. A handler returning true consumes the event and
stops all remaining phases.
§Mutation and dispatch
Tree mutation helpers (append_child,
insert_child, detach_child)
MUST NOT be called from inside an active dispatch. They emit lifecycle
events (ObjectEvent::Attached, ObjectEvent::Detached,
ObjectEvent::ChildChanged) synchronously after the structural change,
outside any active trickle/target/bubble traversal.
Implementations§
Source§impl ObjectNode
impl ObjectNode
Sourcepub fn new(widget: Rc<RefCell<dyn Widget>>) -> Self
pub fn new(widget: Rc<RefCell<dyn Widget>>) -> Self
Create a new object node with no children, tag, flags, states, or handlers.
Sourcepub fn adopt(node: WidgetNode) -> Self
pub fn adopt(node: WidgetNode) -> Self
Recursively adopt a compatibility WidgetNode into an object tree.
The widget handle, child order, and test-automation tag are preserved. New object metadata is initialized to defaults for every adopted node. Nodes adopted this way start with empty handler lists.
Sourcepub const fn meta(&self) -> &ObjectMeta
pub const fn meta(&self) -> &ObjectMeta
Return immutable access to the node’s object metadata.
Sourcepub fn meta_mut(&mut self) -> &mut ObjectMeta
pub fn meta_mut(&mut self) -> &mut ObjectMeta
Return mutable access to the node’s object metadata.
Sourcepub const fn flags(&self) -> ObjectFlags
pub const fn flags(&self) -> ObjectFlags
Return this node’s object flags.
Sourcepub const fn states(&self) -> ObjectStates
pub const fn states(&self) -> ObjectStates
Return this node’s object state bits.
Sourcepub fn set_flag(&mut self, flag: ObjectFlags, enabled: bool)
pub fn set_flag(&mut self, flag: ObjectFlags, enabled: bool)
Set or clear a flag on this node.
Sourcepub fn set_state(&mut self, state: ObjectStates, enabled: bool)
pub fn set_state(&mut self, state: ObjectStates, enabled: bool)
Set or clear a state bit on this node.
Sourcepub const fn is_detached(&self) -> bool
pub const fn is_detached(&self) -> bool
Return whether this node is detached from a live object tree.
Sourcepub fn children(&self) -> &[ObjectNode]
pub fn children(&self) -> &[ObjectNode]
Return this node’s child list.
Sourcepub fn children_mut(&mut self) -> &mut Vec<ObjectNode>
pub fn children_mut(&mut self) -> &mut Vec<ObjectNode>
Return this node’s mutable child list.
Sourcepub fn set_scroll_state(&mut self, state: Box<ScrollState>)
pub fn set_scroll_state(&mut self, state: Box<ScrollState>)
Attach scroll state to this node, enabling it as a scroll container.
The node’s SCROLLABLE flag is set automatically. This is the primary
way to make a node a scroll container (LPAR-05 §5).
Sourcepub fn scroll_state(&self) -> Option<&ScrollState>
pub fn scroll_state(&self) -> Option<&ScrollState>
Return an immutable reference to the scroll state, if any.
Sourcepub fn scroll_state_mut(&mut self) -> Option<&mut ScrollState>
pub fn scroll_state_mut(&mut self) -> Option<&mut ScrollState>
Return a mutable reference to the scroll state, if any.
Sourcepub fn add_local_style(&mut self, patch: StylePatch, selector: Selector)
pub fn add_local_style(&mut self, patch: StylePatch, selector: Selector)
Add a locally owned style patch keyed by selector.
Local style entries take priority over added (shared) entries in the cascade. Within local entries, the last-added entry wins when multiple selectors match (§7.2 reverse-registration-order rule).
The style slot is lazily allocated on the first call.
Sourcepub fn add_style(&mut self, patch: &'static StylePatch, selector: Selector)
pub fn add_style(&mut self, patch: &'static StylePatch, selector: Selector)
Add a shared (added) style patch reference keyed by selector.
Added entries have lower precedence than local entries. Within added entries, the last-added entry wins when multiple selectors match (§7.2).
The 'static lifetime constraint is conservative in v1; see LPAR-07
§7.1 for the deferred object-lifetime-scoped extension.
The style slot is lazily allocated on the first call.
Sourcepub fn add_theme_style(&mut self, patch: StylePatch, selector: Selector)
pub fn add_theme_style(&mut self, patch: StylePatch, selector: Selector)
Add a default-theme style patch keyed by selector (LPAR-07 §9.1).
Theme entries resolve at the lowest style precedence — below local
and added styles — so a widget or application style always wins over the
theme regardless of registration order. Themes write here via
LparTheme::apply_to_node.
The style slot is lazily allocated on the first call.
Sourcepub fn clear_theme_styles(&mut self) -> usize
pub fn clear_theme_styles(&mut self) -> usize
Clear all default-theme style entries on this node (for theme re-apply).
Returns the number of entries removed; 0 when the style slot is None.
Sourcepub fn remove_local_styles(&mut self, part: Part, states: ObjectStates) -> usize
pub fn remove_local_styles(&mut self, part: Part, states: ObjectStates) -> usize
Remove local style entries whose selector matches (part, states).
A selector matches the (part, states) query when the selector’s part
equals part and all state bits in states are present in the
selector’s state mask (same predicate as cascade matching).
Returns the number of entries removed. Returns 0 when the style slot
is None.
To remove all local styles for a part regardless of state, call
remove_all_local_styles_by_part.
To clear everything, call remove_all_local_styles.
Sourcepub fn remove_all_local_styles_by_part(&mut self, part: Part) -> usize
pub fn remove_all_local_styles_by_part(&mut self, part: Part) -> usize
Remove all local style entries for part regardless of state mask.
This is the wildcard form described in §7.5 — removes every local entry
whose part equals part, regardless of its state selector.
Returns the number of entries removed.
Sourcepub fn remove_all_local_styles(&mut self) -> usize
pub fn remove_all_local_styles(&mut self) -> usize
Remove all local style entries from this node (unconditional clear).
Returns the number of entries removed.
Sourcepub fn effective_bounds(&self) -> Rect
pub fn effective_bounds(&self) -> Rect
Return the node’s layout-computed bounds override if present, otherwise
the widget’s intrinsic bounds (Widget::bounds()).
This is the canonical bounds query for hit-testing and draw positioning.
Code that needs layout-aware placement MUST call this rather than
widget.borrow().bounds() directly.
Sourcepub fn set_layout_flex(&mut self, config: FlexConfig)
pub fn set_layout_flex(&mut self, config: FlexConfig)
Configure this node as a flex layout container.
Lazily allocates the LayoutState slot, sets the role to
Container(Flex(config)), and marks the node dirty.
Sourcepub fn set_layout_grid(&mut self, config: GridConfig)
pub fn set_layout_grid(&mut self, config: GridConfig)
Configure this node as a grid layout container.
Lazily allocates the LayoutState slot, sets the role to
Container(Grid(config)), and marks the node dirty.
Sourcepub fn set_item_hints(&mut self, hints: ItemHints)
pub fn set_item_hints(&mut self, hints: ItemHints)
Set the layout item hints for this node.
Lazily allocates the LayoutState slot, sets the role to
Item(hints), and marks the node dirty.
Sourcepub fn mark_layout_dirty(&mut self)
pub fn mark_layout_dirty(&mut self)
Mark this node’s layout as dirty, triggering a re-layout on the next
run_layout call.
Sourcepub fn add_trickle_handler<F>(&mut self, handler: F)
pub fn add_trickle_handler<F>(&mut self, handler: F)
Register a trickle-phase handler on this node.
Trickle handlers run root→target before the target phase. A handler
returning true consumes the event and stops all phases.
Sourcepub fn add_target_handler<F>(&mut self, handler: F)
pub fn add_target_handler<F>(&mut self, handler: F)
Register a target-phase handler on this node.
Target handlers run at the node when it is the dispatch target, after
the trickle phase. A handler returning true consumes the event.
Sourcepub fn add_bubble_handler<F>(&mut self, handler: F)
pub fn add_bubble_handler<F>(&mut self, handler: F)
Register a bubble-phase handler on this node.
Bubble handlers run target→root after the target phase, but only while
ObjectFlags::EVENT_BUBBLE is set on the target (and on each
ancestor traversed). A handler returning true consumes the event.
Sourcepub fn invoke_handlers_for(&mut self, event: &ObjectEvent) -> bool
pub fn invoke_handlers_for(&mut self, event: &ObjectEvent) -> bool
Invoke all registered target-phase handlers for event.
This is the direct handler-invocation path used by lifecycle delivery (Attached/Detached/ChildChanged/Focused/Defocused), which runs outside the trickle/bubble dispatch phases.
Returns true if any handler consumed the event.
Sourcepub fn append_child(&mut self, child: ObjectNode) -> usize
pub fn append_child(&mut self, child: ObjectNode) -> usize
Append a child node and return its index.
After the structural change, emits ObjectEvent::Attached to the
added subtree root’s target handlers, then ObjectEvent::ChildChanged
to this node’s target handlers.
§Dispatch constraint
This method MUST NOT be called from inside an active
dispatch_object_event traversal (LPAR-02 §7.4 / LPAR-04 §6.6).
Sourcepub fn insert_child(&mut self, index: usize, child: ObjectNode) -> bool
pub fn insert_child(&mut self, index: usize, child: ObjectNode) -> bool
Insert a child node at index.
Returns false when index is greater than the current child count.
After the structural change, emits ObjectEvent::Attached to the
added subtree root’s target handlers, then ObjectEvent::ChildChanged
to this node’s target handlers.
§Dispatch constraint
This method MUST NOT be called from inside an active
dispatch_object_event traversal (LPAR-02 §7.4 / LPAR-04 §6.6).
Sourcepub fn detach_child(&mut self, index: usize) -> Option<ObjectNode>
pub fn detach_child(&mut self, index: usize) -> Option<ObjectNode>
Detach and return the child at index.
The returned subtree is marked detached recursively. After the
structural change, emits ObjectEvent::Detached to the detached
subtree root’s target handlers, then ObjectEvent::ChildChanged to
this node’s target handlers.
§Dispatch constraint
This method MUST NOT be called from inside an active
dispatch_object_event traversal (LPAR-02 §7.4 / LPAR-04 §6.6).
Sourcepub fn raise_child(&mut self, index: usize) -> bool
pub fn raise_child(&mut self, index: usize) -> bool
Move the child at index to the front of the draw order.
The front is the highest index and is considered visually topmost for
hit testing. On a successful move, emits ObjectEvent::ChildChanged
to this node’s target handlers (LPAR-04 §5.3).
Sourcepub fn lower_child(&mut self, index: usize) -> bool
pub fn lower_child(&mut self, index: usize) -> bool
Move the child at index to the back of the draw order.
On a successful move, emits ObjectEvent::ChildChanged to this node’s
target handlers (LPAR-04 §5.3).
Sourcepub fn move_child_before(&mut self, from: usize, before: usize) -> bool
pub fn move_child_before(&mut self, from: usize, before: usize) -> bool
Move child from directly before child before.
On an effective move (not a from == before no-op), emits
ObjectEvent::ChildChanged to this node’s target handlers
(LPAR-04 §5.3).
Sourcepub fn move_child_after(&mut self, from: usize, after: usize) -> bool
pub fn move_child_after(&mut self, from: usize, after: usize) -> bool
Move child from directly after child after.
On an effective move (not a from == after no-op), emits
ObjectEvent::ChildChanged to this node’s target handlers
(LPAR-04 §5.3).
Sourcepub fn draw(&self, renderer: &mut dyn Renderer)
pub fn draw(&self, renderer: &mut dyn Renderer)
Recursively draw this object subtree.
Hidden or detached subtrees are skipped. Visible nodes draw parent first and then children in sibling order.
§LPAR-10 translation mechanism (§5.A)
When a node has a layout-computed rect that differs from its widget’s
intrinsic bounds, drawing is routed through a
ClipRenderer that translates by
(effective_bounds.origin − widget.bounds().origin) and clips to
effective_bounds. This repositions the widget’s drawing to its
computed origin without requiring the widget to know its external
position.
For resize-aware widgets that override set_bounds, the widget’s own
bounds() equals effective_bounds so the translation is zero and no
ClipRenderer is interposed.
Sourcepub fn hit_test(&self, x: i32, y: i32) -> Option<&ObjectNode>
pub fn hit_test(&self, x: i32, y: i32) -> Option<&ObjectNode>
Return the topmost targetable node at x, y.
Hit testing searches children in reverse sibling order before testing the node itself. Hidden and detached subtrees are skipped. Disabled nodes are not targetable, but their visible children remain eligible in this base object phase.
Sourcepub fn visible_subtree_extent(&self) -> Option<Rect>
pub fn visible_subtree_extent(&self) -> Option<Rect>
Union of this widget’s bounds with every visible descendant’s bounds, in logical coordinates (LPAR-03 “subtree visual extent”).
Returns None when this node is hidden or detached, or when neither
this widget nor any visible descendant has positive-area bounds.
Zero-area bounds contribute nothing; hidden or detached subtrees are
excluded entirely, exactly mirroring draw skipping.
§Ordering contract (LPAR-03 §15)
A hidden root yields None by design: invalidation callers order
their operations as compute-then-hide (capture the extent before
setting ObjectFlags::HIDDEN) and show-then-compute (clear the
flag, then capture). The same applies to detach: capture the extent
before detach_child, then push the captured
rect into the invalidation planner.