use bevy::camera::NormalizedRenderTarget;
use bevy::ecs::entity::EntityHashMap;
use bevy::ecs::system::RunSystemOnce;
use bevy::picking::backend::HitData;
use bevy::picking::events::PointerState;
use bevy::picking::hover::HoverMap;
use bevy::picking::pointer::{
Location, PointerAction, PointerButton, PointerId, PointerInput, PointerLocation, PointerMap,
};
use bevy::platform::time::Instant;
use bevy::prelude::*;
pub(crate) fn at(position: Vec2) -> Location {
Location {
target: NormalizedRenderTarget::Image(Handle::<Image>::default().into()),
position,
}
}
pub(crate) fn hit(depth: f32) -> HitData {
HitData::new(Entity::PLACEHOLDER, depth, None, None)
}
pub(crate) fn spawn_pointer(world: &mut World, id: PointerId, position: Vec2) -> Entity {
world.init_resource::<PointerMap>();
world.spawn((id, PointerLocation::new(at(position)))).id()
}
pub(crate) fn move_to(world: &mut World, pointer: Entity, position: Vec2) {
world.get_mut::<PointerLocation>(pointer).unwrap().location = Some(at(position));
}
pub(crate) fn hover(world: &mut World, pointer: PointerId, entities: &[Entity]) {
let entry: EntityHashMap<HitData> = entities
.iter()
.enumerate()
.map(|(i, &entity)| (entity, hit(i as f32 * 0.00001)))
.collect();
world
.get_resource_or_init::<HoverMap>()
.insert(pointer, entry);
}
pub(crate) fn hold(world: &mut World, pointer: PointerId) {
world.init_resource::<Messages<PointerInput>>();
world.write_message(PointerInput::new(
pointer,
at(Vec2::ZERO),
PointerAction::Press(PointerButton::Primary),
));
world.run_system_once(PointerInput::receive).unwrap();
}
pub(crate) fn press(
world: &mut World,
pointer: PointerId,
button: PointerButton,
entities: &[Entity],
) {
let mut state = world.get_resource_or_init::<PointerState>();
let pressing = &mut state.get_mut(pointer, button).pressing;
pressing.clear();
for &entity in entities {
pressing.insert(entity, (at(Vec2::ZERO), Instant::now(), hit(0.0)));
}
}