Blacksite/crates/editor/src/ui/selection_ops.rs

80 lines
2.6 KiB
Rust

//! Selection delete/duplicate and camera focus helpers.
use bevy::prelude::*;
use bevy_inspector_egui::bevy_inspector::hierarchy::SelectedEntities;
use shared::LevelObject;
use crate::camera::EditorCamera;
use crate::history::{
delete_entities_with_history, duplicate_entities_with_history, set_transform_group_with_history,
};
use crate::selection::SelectedEntity;
use crate::ui::UiState;
pub fn focus_editor_camera_on_selection(world: &mut World) {
let Some(entity) = world.resource::<SelectedEntity>().0 else {
return;
};
let Some(target) = world.get::<GlobalTransform>(entity) else {
return;
};
let center = target.translation();
let mut cameras = world.query_filtered::<&mut Transform, With<EditorCamera>>();
for mut transform in cameras.iter_mut(world) {
let offset = transform.translation - center;
let distance = offset.length().max(8.0);
transform.translation = center - transform.forward().as_vec3() * distance;
transform.look_at(center, Vec3::Y);
}
}
pub fn selected_level_entities(world: &World, selected: &SelectedEntities) -> Vec<Entity> {
selected
.iter()
.filter(|entity| {
world
.get_entity(*entity)
.is_ok_and(|entity_ref| entity_ref.contains::<LevelObject>())
})
.collect()
}
pub fn entity_name(world: &World, entity: Entity) -> String {
world
.get::<Name>(entity)
.map(|name| name.as_str().to_string())
.unwrap_or_else(|| format!("{entity:?}"))
}
pub fn is_level_object(world: &World, entity: Entity) -> bool {
world
.get_entity(entity)
.is_ok_and(|entity_ref| entity_ref.contains::<LevelObject>())
}
pub fn delete_selection(world: &mut World, selected: &SelectedEntities) {
let entities = selected_level_entities(world, selected);
delete_entities_with_history(world, &entities);
}
pub fn duplicate_selection(world: &mut World, selected: &SelectedEntities) {
let entities = selected_level_entities(world, selected);
duplicate_entities_with_history(world, &entities);
}
pub fn reset_selected_transforms(world: &mut World) {
let changes: Vec<_> = world
.resource::<UiState>()
.selected_entities
.iter()
.filter(|entity| is_level_object(world, *entity))
.filter_map(|entity| {
world
.get::<Transform>(entity)
.copied()
.map(|old| (entity, old, Transform::default()))
})
.collect();
set_transform_group_with_history(world, changes);
}