Skip to main content

traaains/ui/track/segment/signals_list/item/
index_input.rs

1use 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; // currently multiple signals with same positions are not supported
40    }
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    // finally, update the displayed value and stored old value
50    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}