aetna-core 0.3.0

Aetna — backend-agnostic UI library core
Documentation
//! Layout/key lookup helpers for [`UiState`](super::UiState).

use crate::event::UiTarget;
use crate::tree::{El, Rect};

use super::UiState;

impl UiState {
    /// Look up the layout-assigned rect for `id`; returns a zero rect
    /// when `id` is unknown (pre-layout, or not in the laid-out tree).
    pub fn rect(&self, id: &str) -> Rect {
        self.layout
            .computed_rects
            .get(id)
            .copied()
            .unwrap_or_default()
    }

    /// Look up the layout-assigned rect for an app-supplied element
    /// key. Returns `None` when the key is absent from `root` or layout
    /// has not written a rect for that node yet.
    pub fn rect_of_key(&self, root: &El, key: &str) -> Option<Rect> {
        find_target_by_key(root, key)
            .and_then(|target| self.layout.computed_rects.get(&target.node_id).copied())
    }

    /// Build a [`UiTarget`] for an app-supplied element key using the
    /// current layout rect. Useful for hosts that need to anchor native
    /// overlays or forward events into externally painted regions.
    pub fn target_of_key(&self, root: &El, key: &str) -> Option<UiTarget> {
        let target = find_target_by_key(root, key)?;
        let rect = self.layout.computed_rects.get(&target.node_id).copied()?;
        Some(UiTarget { rect, ..target })
    }
}

fn find_target_by_key(root: &El, key: &str) -> Option<UiTarget> {
    if root.key.as_deref() == Some(key) {
        return Some(UiTarget {
            key: key.to_string(),
            node_id: root.computed_id.clone(),
            rect: Rect::default(),
        });
    }
    root.children
        .iter()
        .find_map(|child| find_target_by_key(child, key))
}