use crate::ecs::world::World;
use crate::prelude::*;
pub fn ui_event_bubble_system(world: &mut World) {
if !world.resources.retained_ui.enabled {
return;
}
world.resources.retained_ui.frame.bubbled_events.clear();
let events: Vec<crate::ecs::ui::resources::UiEvent> =
world.resources.retained_ui.events_for_active().to_vec();
if !world.resources.transform_state.children_cache_valid {
validate_and_rebuild_children_cache(world);
}
for event in &events {
if !event.bubbles() {
continue;
}
let target = event.target_entity();
let mut current = target;
loop {
let parent_opt = world.core.get_parent(current).and_then(|p| p.0);
let Some(parent) = parent_opt else {
break;
};
world.resources.retained_ui.frame.bubbled_events.push(
crate::ecs::ui::resources::BubbledUiEvent {
event: event.clone(),
target,
ancestor: parent,
stopped: false,
},
);
current = parent;
}
}
}
pub fn ui_emit_click_events_system(world: &mut World) {
if !world.resources.retained_ui.enabled {
return;
}
let already_emitted: std::collections::HashSet<freecs::Entity> = world
.resources
.retained_ui
.events_for_active()
.iter()
.filter_map(|event| match event {
crate::ecs::ui::resources::UiEvent::ButtonClicked(entity)
| crate::ecs::ui::resources::UiEvent::SelectableLabelClicked { entity, .. } => {
Some(*entity)
}
_ => None,
})
.collect();
let candidates: Vec<freecs::Entity> = world
.ui
.query_entities(crate::ecs::world::UI_NODE_INTERACTION)
.collect();
for entity in candidates {
if already_emitted.contains(&entity) {
continue;
}
let clicked = world
.ui
.get_ui_node_interaction(entity)
.is_some_and(|interaction| interaction.clicked);
if clicked {
world
.resources
.retained_ui
.events_for_active_mut()
.push(crate::ecs::ui::resources::UiEvent::ButtonClicked(entity));
}
}
}