use crate::ecs::{EditorMode, EditorWorld};
use nightshade::ecs::world::PREFAB_SOURCE;
use nightshade::prelude::*;
pub fn tick_mode(editor_world: &mut EditorWorld, world: &World, shell_active: bool) {
if shell_active || crate::systems::input::ui_capturing(world) {
editor_world.resources.mode.tab_was_pressed = false;
return;
}
let pressed = world.resources.input.keyboard.is_key_pressed(KeyCode::Tab);
let was_pressed = editor_world.resources.mode.tab_was_pressed;
editor_world.resources.mode.tab_was_pressed = pressed;
if !pressed || was_pressed {
return;
}
let next = match editor_world.resources.mode.mode {
EditorMode::Object => {
let Some(selected) = editor_world.resources.ui.selected_entity else {
return;
};
let Some(target) = nearest_prefab_instance(world, selected) else {
return;
};
EditorMode::Edit { target }
}
EditorMode::Edit { .. } => EditorMode::Object,
};
editor_world.resources.mode.mode = next;
crate::systems::picking::reset_cycle(editor_world);
if let EditorMode::Edit { target } = next {
crate::systems::selection::set_primary(editor_world, Some(target));
}
}
pub fn nearest_prefab_instance(world: &World, entity: Entity) -> Option<Entity> {
let mut current = entity;
loop {
if entity_has_prefab_instance(world, current) {
return Some(current);
}
let parent = world.core.get_parent(current).and_then(|parent| parent.0)?;
current = parent;
}
}
pub fn is_descendant_of(world: &World, entity: Entity, ancestor: Entity) -> bool {
if entity == ancestor {
return true;
}
let mut current = entity;
while let Some(parent) = world.core.get_parent(current).and_then(|parent| parent.0) {
if parent == ancestor {
return true;
}
current = parent;
}
false
}
fn entity_has_prefab_instance(world: &World, entity: Entity) -> bool {
world.core.entity_has_components(entity, PREFAB_SOURCE)
}