traaains/editor/track/placing/
observers.rs1use bevy::{
2 asset::Assets,
3 ecs::{
4 component::Component,
5 event::EntityEvent,
6 observer::On,
7 query::{With, Without},
8 system::{Query, Res, ResMut, Single},
9 },
10 mesh::{Mesh, Mesh2d},
11 picking::events::{PointerEnter, PointerLeave},
12 sprite_render::{ColorMaterial, MeshMaterial2d},
13 transform::components::Transform,
14};
15
16use crate::{
17 AssetsManager,
18 editor::track::placing::{FromNodeType, NodeType, VirtualNode, VirtualSegment},
19 shape::BezierMeshProps,
20 sim::track::node::TrackNode,
21 utils::Meshable,
22};
23
24#[derive(Component)]
26pub struct PlacingTrackObserver;
27
28pub fn on_enter_node(
30 e: On<PointerEnter>,
31 mut virtual_s: Option<
32 Single<(&mut VirtualSegment, &Transform, &mut Mesh2d), Without<VirtualNode>>,
33 >,
34 mut virtual_n: Single<&mut Transform, With<VirtualNode>>,
35 mut q_nodes: Query<
36 (&Transform, &mut MeshMaterial2d<ColorMaterial>),
37 (With<TrackNode>, Without<VirtualNode>),
38 >,
39 mut from_node_type: ResMut<FromNodeType>,
40 mut meshes: ResMut<Assets<Mesh>>,
41 assets_manager: Res<AssetsManager>,
42) {
43 let Ok((tn_transform, mut tn_mat)) = q_nodes.get_mut(e.event_target()) else {
45 return;
46 };
47
48 match virtual_s.as_mut() {
50 Some(virtual_s) => {
51 if virtual_s.0.from == e.event_target() {
53 return;
54 }
55
56 let last_point_pos = (tn_transform.translation - virtual_s.1.translation).truncate();
57
58 virtual_s.0.shape.set_last_point(last_point_pos);
59 virtual_s.0.to = NodeType::Physical(e.event_target());
60 virtual_s.2.0 = meshes.add(virtual_s.0.shape.mesh(BezierMeshProps::default()));
61 }
62 None => {
63 from_node_type.0 = NodeType::Physical(e.event_target());
64 tn_mat.0 = assets_manager
65 .materials
66 .get(&crate::AssetType::TrackNodeActive)
67 .cloned()
68 .unwrap();
69 virtual_n.translation = tn_transform.translation;
70 }
71 }
72}
73
74pub fn on_exit_node(
75 e: On<PointerLeave>,
76 virtual_s: Option<Single<&mut VirtualSegment>>,
77 mut q_nodes: Query<&mut MeshMaterial2d<ColorMaterial>, With<TrackNode>>,
78 mut from_node_type: ResMut<FromNodeType>,
79 assets_manager: Res<AssetsManager>,
80) {
81 let Ok(mut tn_mat) = q_nodes.get_mut(e.event_target()) else {
83 return;
84 };
85
86 match virtual_s {
87 Some(mut virtual_s) => {
89 virtual_s.to = NodeType::Virtual;
90 }
91 None => {
93 if let NodeType::Physical(_) = from_node_type.0 {
94 from_node_type.0 = NodeType::Virtual;
95 }
96 }
97 }
98
99 tn_mat.0 = assets_manager
100 .materials
101 .get(&crate::AssetType::TrackNodeNormal)
102 .cloned()
103 .unwrap();
104}