paiagram/interface/widgets/
timetable_popup.rs1use 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}