game/sandbox/dashboards/
mod.rs1pub use commuter::CommuterPatterns;
2pub use traffic_signals::TrafficSignalDemand;
3
4use widgetry::{Choice, EventCtx, Image, Line, Panel, State, TextExt, Widget};
5
6use crate::app::App;
7use crate::app::Transition;
8
9mod commuter;
10mod generic_trip_table;
11mod misc;
12mod mode_shift;
13mod parking_overhead;
14mod risks;
15mod selector;
16mod traffic_signals;
17mod travel_times;
18mod trip_problems;
19mod trip_table;
20
21#[derive(Clone, Copy, PartialEq, Debug)]
23pub enum DashTab {
24 TripTable,
25 TravelTimes,
26 RiskSummaries,
27 ParkingOverhead,
28 ActiveTraffic,
29 TransitRoutes,
30 CommuterPatterns,
31 TrafficSignals,
32 ModeShift,
33}
34
35impl DashTab {
36 pub fn picker(self, ctx: &EventCtx, app: &App) -> Widget {
37 let mut choices = vec![
38 Choice::new("Trip Table", DashTab::TripTable),
39 Choice::new("Travel Times", DashTab::TravelTimes),
40 Choice::new("Risk Exposure", DashTab::RiskSummaries),
41 Choice::new("Parking Overhead", DashTab::ParkingOverhead),
42 Choice::new("Active Traffic", DashTab::ActiveTraffic),
43 Choice::new("Transit Routes", DashTab::TransitRoutes),
44 Choice::new("Commuter Patterns", DashTab::CommuterPatterns),
45 Choice::new("Traffic Signal Demand", DashTab::TrafficSignals),
46 Choice::new("Mode shift (experimental)", DashTab::ModeShift),
47 ];
48 if app.has_prebaked().is_none() {
49 choices.remove(1);
50 choices.remove(1);
51 }
52 Widget::row(vec![
53 Image::from_path("system/assets/meters/trip_histogram.svg").into_widget(ctx),
54 Line("Data").big_heading_plain().into_widget(ctx),
55 Widget::dropdown(ctx, "tab", self, choices),
56 format!("By {}", app.primary.sim.time().ampm_tostring())
57 .text_widget(ctx)
58 .centered_vert(),
59 ctx.style().btn_close_widget(ctx),
60 ])
61 }
62
63 pub fn launch(self, ctx: &mut EventCtx, app: &mut App) -> Box<dyn State<App>> {
64 match self {
65 DashTab::TripTable => Box::new(trip_table::TripTable::new(ctx, app)),
66 DashTab::TravelTimes => {
67 travel_times::TravelTimes::new_state(ctx, app, travel_times::Filter::new())
68 }
69 DashTab::RiskSummaries => risks::RiskSummaries::new_state(ctx, app, false),
70 DashTab::ParkingOverhead => parking_overhead::ParkingOverhead::new_state(ctx, app),
71 DashTab::ActiveTraffic => misc::ActiveTraffic::new_state(ctx, app),
72 DashTab::TransitRoutes => misc::TransitRoutes::new_state(ctx, app),
73 DashTab::CommuterPatterns => CommuterPatterns::new_state(ctx, app),
74 DashTab::TrafficSignals => TrafficSignalDemand::new_state(ctx, app),
75 DashTab::ModeShift => mode_shift::ModeShift::new_state(ctx, app),
76 }
77 }
78
79 pub fn tab_changed(self, app: &mut App, panel: &Panel) -> Option<DashTab> {
80 let tab: DashTab = panel.dropdown_value("tab");
81 if tab == self {
82 return None;
83 }
84 app.session.dash_tab = tab;
85 Some(tab)
86 }
87
88 pub fn transition(
89 self,
90 ctx: &mut EventCtx,
91 app: &mut App,
92 panel: &Panel,
93 ) -> Option<Transition> {
94 let tab = self.tab_changed(app, panel)?;
95 Some(Transition::Replace(tab.launch(ctx, app)))
96 }
97}