paiagram/interface/widgets/
timetable_popup.rs

1use bevy::ecs::{entity::Entity, message::MessageWriter};
2use egui::{Button, RichText, Ui};
3
4use crate::{
5    units::time::{Duration, TimetableTime},
6    vehicles::{
7        AdjustTimetableEntry, TimetableAdjustment,
8        entries::{TimetableEntry, TimetableEntryCache, TravelMode},
9    },
10};
11
12pub fn popup(
13    entry_entity: Entity,
14    (current_entry, current_entry_cache): (&TimetableEntry, &TimetableEntryCache),
15    previous_entry: Option<(&TimetableEntry, &TimetableEntryCache)>,
16    msg_adjust_entry: &mut MessageWriter<AdjustTimetableEntry>,
17    ui: &mut Ui,
18    arrival: bool,
19) {
20    let dt = match (previous_entry, arrival) {
21        (Some((pe, pec)), true) => {
22            if let Some(ae) = current_entry_cache.estimate.as_ref().map(|e| e.arrival)
23                && let Some(de) = pec.estimate.as_ref().map(|e| e.departure)
24            {
25                Some(ae - de)
26            } else {
27                None
28            }
29        }
30        (None, true) => None,
31        (_, false) => {
32            if let Some(de) = current_entry_cache.estimate.as_ref().map(|e| e.departure)
33                && let Some(ae) = current_entry_cache.estimate.as_ref().map(|e| e.arrival)
34            {
35                Some(de - ae)
36            } else {
37                None
38            }
39        }
40    };
41    let (show_at, show_for, show_flexible, show_bypass) = if arrival {
42        match current_entry.arrival {
43            TravelMode::At(_) => (false, true, true, false),
44            TravelMode::For(_) => (true, false, true, false),
45            TravelMode::Flexible => (true, true, false, false),
46        }
47    } else {
48        match current_entry.departure {
49            Some(TravelMode::At(_)) => (false, true, true, true),
50            Some(TravelMode::For(_)) => (true, false, true, true),
51            Some(TravelMode::Flexible) => (true, true, false, true),
52            None => (true, true, true, false),
53        }
54    };
55    ui.add_enabled_ui(show_at ^ show_for, |ui: &mut Ui| {
56        ui.horizontal(|ui| {
57            for (s, dt) in [("-10", -10), ("-1", -1), ("+1", 1), ("+10", 10)] {
58                let response =
59                    ui.add_sized((24.0, 18.0), Button::new(RichText::monospace(s.into())));
60                if response.clicked() {
61                    msg_adjust_entry.write(AdjustTimetableEntry {
62                        entity: entry_entity,
63                        adjustment: if arrival {
64                            TimetableAdjustment::AdjustArrivalTime(Duration(dt))
65                        } else {
66                            TimetableAdjustment::AdjustDepartureTime(Duration(dt))
67                        },
68                    });
69                }
70                if response.secondary_clicked() {
71                    msg_adjust_entry.write(AdjustTimetableEntry {
72                        entity: entry_entity,
73                        adjustment: if arrival {
74                            TimetableAdjustment::AdjustArrivalTime(Duration(dt * 60))
75                        } else {
76                            TimetableAdjustment::AdjustArrivalTime(Duration(dt * 60))
77                        },
78                    });
79                }
80            }
81        })
82    });
83    if ui
84        .add_enabled(
85            show_at,
86            Button::new("At").right_text(RichText::monospace(
87                if arrival {
88                    current_entry_cache.estimate.as_ref().map(|e| e.arrival)
89                } else {
90                    current_entry_cache.estimate.as_ref().map(|e| e.departure)
91                }
92                .map_or("--:--:--".into(), |t| t.to_string().into()),
93            )),
94        )
95        .clicked()
96    {
97        msg_adjust_entry.write(AdjustTimetableEntry {
98            entity: entry_entity,
99            adjustment: if arrival {
100                TimetableAdjustment::SetArrivalType(TravelMode::At(
101                    if let Some(ae) = current_entry_cache.estimate.as_ref().map(|e| e.arrival) {
102                        ae
103                    } else {
104                        TimetableTime(0)
105                    },
106                ))
107            } else {
108                TimetableAdjustment::SetDepartureType(Some(TravelMode::At(
109                    if let Some(de) = current_entry_cache.estimate.as_ref().map(|e| e.departure) {
110                        de
111                    } else {
112                        TimetableTime(0)
113                    },
114                )))
115            },
116        });
117    }
118    if ui
119        .add_enabled(
120            show_for,
121            Button::new("For").right_text(RichText::monospace(
122                dt.map_or("--:--:--".into(), |t| t.to_string().into()),
123            )),
124        )
125        .clicked()
126    {
127        msg_adjust_entry.write(AdjustTimetableEntry {
128            entity: entry_entity,
129            adjustment: if arrival {
130                TimetableAdjustment::SetArrivalType(TravelMode::For(if let Some(dt) = dt {
131                    dt
132                } else {
133                    Duration(0)
134                }))
135            } else {
136                TimetableAdjustment::SetDepartureType(Some(TravelMode::For(if let Some(dt) = dt {
137                    dt
138                } else {
139                    Duration(0)
140                })))
141            },
142        });
143    }
144    if ui
145        .add_enabled(show_flexible, Button::new("Flexible"))
146        .clicked()
147    {
148        msg_adjust_entry.write(AdjustTimetableEntry {
149            entity: entry_entity,
150            adjustment: if arrival {
151                TimetableAdjustment::SetArrivalType(TravelMode::Flexible)
152            } else {
153                TimetableAdjustment::SetDepartureType(Some(TravelMode::Flexible))
154            },
155        });
156    }
157    if arrival {
158        return;
159    }
160    if ui
161        .add_enabled(show_bypass, Button::new("Non-Stop"))
162        .clicked()
163    {
164        msg_adjust_entry.write(AdjustTimetableEntry {
165            entity: entry_entity,
166            adjustment: TimetableAdjustment::SetDepartureType(None),
167        });
168    }
169}