diff --git a/game/src/app.rs b/game/src/app.rs index 89b03b06d8..bda00bddb1 100644 --- a/game/src/app.rs +++ b/game/src/app.rs @@ -22,6 +22,7 @@ use crate::challenges::HighScore; use crate::common::Warping; use crate::edit::apply_map_edits; use crate::layer::Layer; +use crate::sandbox::dashboards::DashTab; use crate::sandbox::{GameplayMode, TutorialState}; // Convenient typedef @@ -727,6 +728,7 @@ pub struct SessionState { pub high_scores: BTreeMap>, pub info_panel_tab: BTreeMap<&'static str, &'static str>, pub last_gmns_timing_csv: Option, + pub dash_tab: DashTab, } impl SessionState { @@ -742,6 +744,7 @@ impl SessionState { "bus" => "status", }, last_gmns_timing_csv: None, + dash_tab: DashTab::TripTable, } } } diff --git a/game/src/sandbox/dashboards/commuter.rs b/game/src/sandbox/dashboards/commuter.rs index a71faf99e9..881373e1e8 100644 --- a/game/src/sandbox/dashboards/commuter.rs +++ b/game/src/sandbox/dashboards/commuter.rs @@ -14,6 +14,7 @@ use widgetry::{ use crate::app::{App, Transition}; use crate::common::{checkbox_per_mode, CommonState}; +use crate::sandbox::dashboards::DashTab; pub struct CommuterPatterns { bldg_to_block: HashMap, @@ -335,14 +336,21 @@ impl State for CommuterPatterns { fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition { ctx.canvas_movement(); - if let Outcome::Clicked(x) = self.panel.event(ctx) { - match x.as_ref() { + match self.panel.event(ctx) { + Outcome::Clicked(x) => match x.as_ref() { "close" => { app.primary.sim = app.primary.suspended_sim.take().unwrap(); return Transition::Pop; } _ => unreachable!(), + }, + Outcome::Changed(_) => { + if let Some(tab) = DashTab::CommuterPatterns.tab_changed(app, &self.panel) { + app.primary.sim = app.primary.suspended_sim.take().unwrap(); + return Transition::Replace(tab.launch(ctx, app)); + } } + _ => {} } let block_selection = if let Some(Some(b)) = ctx @@ -674,12 +682,7 @@ fn partition_sidewalk_loops(app: &App) -> Vec { fn make_panel(ctx: &mut EventCtx, app: &App) -> Panel { Panel::new_builder(Widget::col(vec![ - Widget::row(vec![ - Line("Commute map by block") - .small_heading() - .into_widget(ctx), - ctx.style().btn_close_widget(ctx), - ]), + DashTab::CommuterPatterns.picker(ctx, app), Toggle::choice(ctx, "from / to this block", "from", "to", Key::Space, true), Toggle::switch(ctx, "include borders", None, true), Widget::row(vec![ diff --git a/game/src/sandbox/dashboards/mod.rs b/game/src/sandbox/dashboards/mod.rs index 4ae45dae94..fd9761b7c7 100644 --- a/game/src/sandbox/dashboards/mod.rs +++ b/game/src/sandbox/dashboards/mod.rs @@ -1,8 +1,7 @@ pub use commuter::CommuterPatterns; pub use traffic_signals::TrafficSignalDemand; -pub use trip_table::TripTable; -use widgetry::{Choice, EventCtx, Image, Line, Panel, TextExt, Widget}; +use widgetry::{Choice, EventCtx, Image, Line, Panel, State, TextExt, Widget}; use crate::app::App; use crate::app::Transition; @@ -61,19 +60,9 @@ impl DashTab { ]) } - pub fn transition( - self, - ctx: &mut EventCtx, - app: &mut App, - panel: &Panel, - ) -> Option { - let tab = panel.dropdown_value("tab"); - if tab == self { - return None; - } - - Some(Transition::Replace(match tab { - DashTab::TripTable => Box::new(TripTable::new(ctx, app)), + pub fn launch(self, ctx: &mut EventCtx, app: &mut App) -> Box> { + match self { + DashTab::TripTable => Box::new(trip_table::TripTable::new(ctx, app)), DashTab::TravelTimes => { travel_times::TravelTimes::new_state(ctx, app, travel_times::Filter::new()) } @@ -84,6 +73,25 @@ impl DashTab { DashTab::CommuterPatterns => CommuterPatterns::new_state(ctx, app), DashTab::TrafficSignals => TrafficSignalDemand::new_state(ctx, app), DashTab::ModeShift => mode_shift::ModeShift::new_state(ctx, app), - })) + } + } + + pub fn tab_changed(self, app: &mut App, panel: &Panel) -> Option { + let tab: DashTab = panel.dropdown_value("tab"); + if tab == self { + return None; + } + app.session.dash_tab = tab; + Some(tab) + } + + pub fn transition( + self, + ctx: &mut EventCtx, + app: &mut App, + panel: &Panel, + ) -> Option { + let tab = self.tab_changed(app, panel)?; + Some(Transition::Replace(tab.launch(ctx, app))) } } diff --git a/game/src/sandbox/dashboards/traffic_signals.rs b/game/src/sandbox/dashboards/traffic_signals.rs index 40b246f1c9..e6da1adc58 100644 --- a/game/src/sandbox/dashboards/traffic_signals.rs +++ b/game/src/sandbox/dashboards/traffic_signals.rs @@ -13,6 +13,7 @@ use widgetry::{ use crate::app::{App, ShowEverything, Transition}; use crate::common::CommonState; +use crate::sandbox::dashboards::DashTab; pub struct TrafficSignalDemand { panel: Panel, @@ -40,12 +41,7 @@ impl TrafficSignalDemand { draw_all, selected: None, panel: Panel::new_builder(Widget::col(vec![ - Widget::row(vec![ - Line("Traffic signal demand over time") - .small_heading() - .into_widget(ctx), - ctx.style().btn_close_widget(ctx), - ]), + DashTab::TrafficSignals.picker(ctx, app), Text::from_all(vec![ Line("Press "), Key::LeftArrow.txt(ctx), @@ -112,6 +108,10 @@ impl State for TrafficSignalDemand { _ => unreachable!(), }, Outcome::Changed(_) => { + if let Some(tab) = DashTab::TrafficSignals.tab_changed(app, &self.panel) { + app.primary.sim = app.primary.suspended_sim.take().unwrap(); + return Transition::Replace(tab.launch(ctx, app)); + } changed = true; } _ => {} diff --git a/game/src/sandbox/minimap.rs b/game/src/sandbox/minimap.rs index 6df1614d2e..27c9beb106 100644 --- a/game/src/sandbox/minimap.rs +++ b/game/src/sandbox/minimap.rs @@ -9,7 +9,6 @@ use crate::app::App; use crate::app::Transition; use crate::common::Warping; use crate::layer::PickLayer; -use crate::sandbox::dashboards::TripTable; pub struct MinimapController; @@ -94,7 +93,7 @@ impl MinimapControls for MinimapController { "change layers" => { return Some(Transition::Push(PickLayer::pick(ctx, app))); } - "more data" => Some(Transition::Push(Box::new(TripTable::new(ctx, app)))), + "more data" => Some(Transition::Push(app.session.dash_tab.launch(ctx, app))), _ => unreachable!(), } }