lgui-core 0.2.0

Platform-neutral runtime and UI primitives for LGUI
Documentation
use super::{
    input::{event_target_ids, interaction_state_target_ids},
    *,
};

impl UiRuntime {
    pub fn handle_default_action(
        &mut self,
        tree: &HostTree,
        pending: UiDefaultAction,
    ) -> RuntimeOutput {
        if pending.action.id().as_str() == FOCUS_TRAVERSAL_ACTION {
            let events = self
                .events
                .focus_adjacent(tree, pending.action.payload_value() == Some("reverse"));
            let handler_events = events
                .iter()
                .flat_map(|event| tree.handler_events(event))
                .collect();
            for event in events.iter().cloned() {
                self.dirty.mark_event(event);
            }
            self.mark_component_owners(tree, events.iter().flat_map(interaction_state_target_ids));
            let animation_changed =
                apply_events_to_animations(tree, &mut self.animations, events.iter().cloned());
            if animation_changed {
                self.mark_component_owners(tree, events.iter().flat_map(event_target_ids));
            }
            let dirty_bounds = self.dirty.take().bounds(tree);
            return RuntimeOutput {
                events,
                handler_events,
                action_events: Vec::new(),
                default_actions: Vec::new(),
                dirty_bounds,
                animation_changed,
                route_changed: false,
            };
        }
        let mut action_events = Vec::new();
        let (_, changed, route_changed) = self.apply_component_action(
            tree,
            &pending.action_target,
            &pending.action,
            &mut action_events,
        );
        let handler_events = changed
            .then(|| {
                tree.handler_event(
                    &pending.action_target,
                    UiEventPayload::Change {
                        value: pending.action.payload_value().map(str::to_owned),
                    },
                )
            })
            .flatten()
            .into_iter()
            .collect();
        let dirty_bounds = self.dirty.take().bounds(tree);
        RuntimeOutput {
            events: Vec::new(),
            handler_events,
            action_events,
            default_actions: Vec::new(),
            dirty_bounds,
            animation_changed: changed,
            route_changed,
        }
    }

    fn apply_component_action(
        &mut self,
        tree: &HostTree,
        target: &UiId,
        action: &UiAction,
        action_events: &mut Vec<UiActionEvent>,
    ) -> (bool, bool, bool) {
        let outcome = self.component_states.handle_action(target, action);
        if outcome.changed {
            self.mark_component_owners(tree, std::iter::once(target));
            self.dirty.mark_id(target.clone());
        }
        for action in outcome.events {
            let Some(handler) = tree.action_handler(target, action.id()) else {
                continue;
            };
            action_events.push(UiActionEvent {
                target: target.clone(),
                action,
                handler,
            });
        }
        let route_changed =
            outcome.changed && self.component_states.take_route_invalidation(target);
        (outcome.handled, outcome.changed, route_changed)
    }
}