traaains/ui/track/segment/signals_list/item/
index_input.rs1use bevy::{
2 ecs::{
3 event::EntityEvent,
4 observer::On,
5 query::With,
6 system::{Commands, Query},
7 },
8 feathers::controls::{FeathersNumberInput, HardLimit, NumberInputValue},
9 scene::{Scene, SceneComponent, bsn, on},
10 ui_widgets::ValueChange,
11};
12
13use crate::{
14 sim::{
15 signal::Signals,
16 track::{pos::TrackPos, segment::signals_manager::SignalsManager},
17 },
18 ui::Target,
19};
20
21fn on_signal_index_change(
22 e: On<ValueChange<f32>>,
23 mut cmd: Commands,
24 q_targets: Query<(&Target, &SignalIndexInput)>,
25 mut q_signals: Query<&mut TrackPos, With<Signals>>,
26 mut q_segments: Query<&mut SignalsManager>,
27) {
28 if !e.is_final {
29 return;
30 }
31
32 let (ts_target, ts_index_input) = q_targets.get(e.event_target()).unwrap();
33 let mut signal_track_pos = q_signals.get_mut(ts_target.0).unwrap();
34 let mut ts_signals = q_segments.get_mut(signal_track_pos.segment).unwrap();
35
36 let signal_idx = e.value.try_into().unwrap();
37
38 if ts_signals.inner.contains_key(&signal_idx) {
39 return; }
41
42 ts_signals
43 .inner
44 .remove(&ts_index_input.old.try_into().unwrap());
45 ts_signals.inner.insert(signal_idx, ts_target.0);
46
47 signal_track_pos.idx = e.value;
48
49 cmd.entity(e.event_target())
51 .insert(NumberInputValue::F32(e.value));
52 cmd.entity(e.event_target())
53 .insert(SignalIndexInput { old: e.value });
54}
55
56#[derive(Clone, Default, SceneComponent)]
57#[scene(SignalIndexInputProps)]
58pub struct SignalIndexInput {
59 old: f32,
60}
61
62#[derive(Default)]
63pub struct SignalIndexInputProps {
64 pub value: f32,
65}
66
67impl SignalIndexInput {
68 fn scene(props: SignalIndexInputProps) -> impl Scene {
69 bsn! {
70 @FeathersNumberInput
71 HardLimit::f32(0.0..=1.0)
72 NumberInputValue::F32({props.value})
73 SignalIndexInput { old: {props.value} }
74 on(on_signal_index_change)
75 }
76 }
77}