game/sandbox/dashboards/
mod.rs

1pub 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// Oh the dashboards melted, but we still had the radio
22#[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}