move tool panel to Composite, the first one with interaction. edit mode

exit temporarily broken, need to rearrange things a bit
This commit is contained in:
Dustin Carlino 2019-12-16 09:42:12 -08:00
parent 1e9f14f62d
commit 2c8f68344c
12 changed files with 229 additions and 245 deletions

View File

@ -1,4 +1,3 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect opacity="0.95" width="36" height="36" rx="5.76" fill="#4C4C4C"/>
<path d="M17.99 24.54L10.62 18.81L9 20.07L18 27.07L27 20.07L25.37 18.8L17.99 24.54ZM18 22L25.36 16.27L27 15L18 8L9 15L10.63 16.27L18 22Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 327 B

After

Width:  |  Height:  |  Size: 256 B

View File

@ -1,4 +1,3 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect opacity="0.95" width="36" height="36" rx="5.76" fill="#4C4C4C"/>
<path d="M21.5 20H20.71L20.43 19.73C21.41 18.59 22 17.11 22 15.5C22 11.91 19.09 9 15.5 9C11.91 9 9 11.91 9 15.5C9 19.09 11.91 22 15.5 22C17.11 22 18.59 21.41 19.73 20.43L20 20.71V21.5L25 26.49L26.49 25L21.5 20ZM15.5 20C13.01 20 11 17.99 11 15.5C11 13.01 13.01 11 15.5 11C17.99 11 20 13.01 20 15.5C20 17.99 17.99 20 15.5 20Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 443 B

View File

@ -1,4 +1,3 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect opacity="0.95" width="36" height="36" rx="5.76" fill="#4C4C4C"/>
<path d="M18 6L20.6942 14.2918H29.4127L22.3593 19.4164L25.0534 27.7082L18 22.5836L10.9466 27.7082L13.6407 19.4164L6.58732 14.2918H15.3058L18 6Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 334 B

After

Width:  |  Height:  |  Size: 263 B

View File

@ -1,6 +1,6 @@
pub mod setup;
use crate::common::{AgentTools, CommonState};
use crate::common::{AgentTools, CommonState, ToolPanel};
use crate::debug::DebugMode;
use crate::game::{State, Transition};
use crate::render::MIN_ZOOM_FOR_DETAIL;
@ -45,7 +45,12 @@ impl ABTestMode {
secondary_agent_tools: AgentTools::new(),
diff_trip: None,
diff_all: None,
common: CommonState::new(ctx, false),
// TODO Confirm before leaving state
common: CommonState::new(ToolPanel::new(
ctx,
Box::new(|_, _| Some(Transition::Pop)),
None,
)),
test_name: test_name.to_string(),
flipped: false,
}
@ -169,10 +174,6 @@ impl State for ABTestMode {
if let Some(t) = self.common.event(ctx, ui) {
return t;
}
// TODO Confirm first
if self.common.tool_panel.home_btn.clicked() {
return Transition::Pop;
}
Transition::Keep
}

View File

@ -17,14 +17,13 @@ pub use self::colors::{
ColorLegend, ObjectColorer, ObjectColorerBuilder, RoadColorer, RoadColorerBuilder,
};
pub use self::minimap::Minimap;
use self::panels::ToolPanel;
pub use self::panels::ToolPanel;
pub use self::plot::{Histogram, Plot, Series};
pub use self::route_explorer::RouteExplorer;
pub use self::trip_explorer::TripExplorer;
pub use self::warp::Warping;
use crate::game::Transition;
use crate::helpers::ID;
use crate::options;
use crate::render::DrawOptions;
use crate::ui::UI;
use ezgui::{
@ -34,14 +33,16 @@ use std::collections::BTreeSet;
pub struct CommonState {
turn_cycler: turn_cycler::TurnCyclerState,
pub tool_panel: ToolPanel,
tool_panel: ToolPanel,
}
impl CommonState {
pub fn new(ctx: &EventCtx, with_layers: bool) -> CommonState {
// TODO Should CommonState even own the ToolPanel? Maybe each State just winds up with some
// generic onscreen Composite controls.
pub fn new(tool_panel: ToolPanel) -> CommonState {
CommonState {
turn_cycler: turn_cycler::TurnCyclerState::Inactive,
tool_panel: ToolPanel::new(ctx, with_layers),
tool_panel,
}
}
@ -70,17 +71,8 @@ impl CommonState {
}
}
self.tool_panel.event(ctx);
// Up to the caller to reach in and check if home_btn was clicked. Means different stuff in
// some modes.
if self.tool_panel.settings_btn.clicked() {
return Some(Transition::Push(options::open_panel()));
}
if self.tool_panel.search_btn.clicked() {
return Some(Transition::Push(Box::new(navigate::Navigator::new(ui))));
}
if self.tool_panel.shortcuts_btn.clicked() {
return Some(Transition::Push(shortcuts::ChoosingShortcut::new()));
if let Some(t) = self.tool_panel.event(ctx, ui) {
return Some(t);
}
None

View File

@ -1,121 +1,85 @@
use ezgui::layout::Widget;
use ezgui::{
hotkey, layout, Button, Color, DrawBoth, EventCtx, GeomBatch, GfxCtx, JustDraw, Key,
RewriteColor, ScreenDims, ScreenPt, ScreenRectangle,
};
use geom::{Distance, Polygon};
use crate::common::{navigate, shortcuts};
use crate::game::Transition;
use crate::managed::{Callback, Composite, ManagedWidget};
use crate::options;
use crate::ui::UI;
use ezgui::{hotkey, Button, Color, EventCtx, GfxCtx, Key, RewriteColor, ScreenPt};
// TODO Why wrap at all?
pub struct ToolPanel {
bg: JustDraw,
rect: ScreenRectangle,
pub home_btn: Button,
pub settings_btn: Button,
// TODO These three belong by the minimap, but doing the layout change if the minimap is there
// or not is hard right now.
pub search_btn: Button,
pub shortcuts_btn: Button,
pub layers_btn: Option<Button>,
composite: Composite,
}
impl ToolPanel {
pub fn new(ctx: &EventCtx, with_layers: bool) -> ToolPanel {
let top_left = ScreenPt::new(30.0, ctx.canvas.window_height - 80.0);
let width = 50.0;
let height = 30.0;
// TODO Hardcoding guessed dims
let rect_bg = GeomBatch::from(vec![(
Color::grey(0.4),
Polygon::rounded_rectangle(
Distance::meters(width),
Distance::meters(height),
Distance::meters(5.0),
pub fn new(
ctx: &EventCtx,
home_btn_callback: Callback,
layers_callback: Option<Callback>,
) -> ToolPanel {
let mut row = vec![
// TODO Maybe this is confusing -- it doesn't jump to the title screen necessarily.
ManagedWidget::btn(
Button::rectangle_svg(
"assets/tools/home.svg",
"back",
hotkey(Key::Escape),
RewriteColor::ChangeAll(Color::ORANGE),
ctx,
),
home_btn_callback,
),
)]);
let mut bg = JustDraw::wrap(DrawBoth::new(ctx, rect_bg, Vec::new()));
bg.set_pos(top_left);
// TODO Maybe this is confusing -- it doesn't jump to the title screen necessarily.
let mut home_btn = Button::rectangle_svg(
"assets/tools/home.svg",
"back",
hotkey(Key::Escape),
RewriteColor::ChangeAll(Color::ORANGE),
ctx,
);
let mut settings_btn = Button::rectangle_svg(
"assets/tools/settings.svg",
"settings",
None,
RewriteColor::ChangeAll(Color::ORANGE),
ctx,
);
let mut search_btn = Button::rectangle_svg(
"assets/tools/search.svg",
"search",
hotkey(Key::K),
RewriteColor::Change(Color::WHITE, Color::ORANGE),
ctx,
);
let mut shortcuts_btn = Button::rectangle_svg(
"assets/tools/shortcuts.svg",
"shortcuts",
hotkey(Key::SingleQuote),
RewriteColor::Change(Color::WHITE, Color::ORANGE),
ctx,
);
let mut layers_btn = if with_layers {
Some(Button::rectangle_svg(
ManagedWidget::btn(
Button::rectangle_svg(
"assets/tools/settings.svg",
"settings",
None,
RewriteColor::ChangeAll(Color::ORANGE),
ctx,
),
Box::new(|_, _| Some(Transition::Push(options::open_panel()))),
),
ManagedWidget::svg_button(
ctx,
"assets/tools/search.svg",
"search",
hotkey(Key::K),
Box::new(|_, ui| Some(Transition::Push(Box::new(navigate::Navigator::new(ui))))),
),
ManagedWidget::svg_button(
ctx,
"assets/tools/shortcuts.svg",
"shortcuts",
hotkey(Key::SingleQuote),
Box::new(|_, _| Some(Transition::Push(shortcuts::ChoosingShortcut::new()))),
),
];
if let Some(cb) = layers_callback {
row.push(ManagedWidget::svg_button(
ctx,
"assets/tools/layers.svg",
"change overlay",
hotkey(Key::L),
RewriteColor::Change(Color::WHITE, Color::ORANGE),
ctx,
))
} else {
None
};
let mut widgets: Vec<&mut dyn Widget> = vec![
&mut home_btn,
&mut settings_btn,
&mut search_btn,
&mut shortcuts_btn,
];
if let Some(ref mut w) = layers_btn {
widgets.push(w);
cb,
));
}
layout::stack_horizontally(top_left, 5.0, widgets);
ToolPanel {
bg,
rect: ScreenRectangle::top_left(top_left, ScreenDims::new(width, height)),
home_btn,
settings_btn,
search_btn,
shortcuts_btn,
layers_btn,
composite: Composite::minimal_size(
ManagedWidget::row(row)
.padding(10)
.bg(Color::grey(0.4))
.min_width(200)
.evenly_spaced(),
ScreenPt::new(30.0, ctx.canvas.window_height - 80.0),
),
}
}
pub fn event(&mut self, ctx: &mut EventCtx) {
self.home_btn.event(ctx);
self.settings_btn.event(ctx);
self.search_btn.event(ctx);
self.shortcuts_btn.event(ctx);
if let Some(ref mut btn) = self.layers_btn {
btn.event(ctx);
}
pub fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Transition> {
self.composite.event(ctx, ui)
}
pub fn draw(&self, g: &mut GfxCtx) {
self.bg.draw(g);
self.home_btn.draw(g);
self.settings_btn.draw(g);
self.search_btn.draw(g);
self.shortcuts_btn.draw(g);
if let Some(ref btn) = self.layers_btn {
btn.draw(g);
}
g.canvas.mark_covered_area(self.rect.clone());
self.composite.draw(g);
}
}

View File

@ -6,7 +6,7 @@ mod objects;
mod polygons;
mod routes;
use crate::common::CommonState;
use crate::common::{CommonState, ToolPanel};
use crate::game::{msg, State, Transition, WizardState};
use crate::helpers::ID;
use crate::render::MIN_ZOOM_FOR_DETAIL;
@ -54,7 +54,11 @@ impl DebugMode {
],
ctx,
),
common: CommonState::new(ctx, false),
common: CommonState::new(ToolPanel::new(
ctx,
Box::new(|_, _| Some(Transition::Pop)),
None,
)),
associated: associated::ShowAssociatedState::Inactive,
connected_roads: connected_roads::ShowConnectedRoads::new(),
objects: objects::ObjectDebugger::new(),
@ -265,9 +269,6 @@ impl State for DebugMode {
if let Some(t) = self.common.event(ctx, ui) {
return t;
}
if self.common.tool_panel.home_btn.clicked() {
return Transition::Pop;
}
Transition::Keep
}

View File

@ -2,7 +2,7 @@ mod lanes;
mod stop_signs;
mod traffic_signals;
use crate::common::{CommonState, Warping};
use crate::common::{CommonState, ToolPanel, Warping};
use crate::debug::DebugMode;
use crate::game::{State, Transition, WizardState};
use crate::helpers::{ColorScheme, ID};
@ -30,7 +30,7 @@ pub struct EditMode {
impl EditMode {
pub fn new(ctx: &EventCtx, mode: GameplayMode) -> EditMode {
EditMode {
common: CommonState::new(ctx, false),
common: CommonState::new(ToolPanel::new(ctx, Box::new(|_, _| None), None)),
menu: ModalMenu::new(
"Map Edit Mode",
vec![
@ -232,7 +232,7 @@ impl State for EditMode {
if let Some(t) = self.common.event(ctx, ui) {
return t;
}
if self.common.tool_panel.home_btn.clicked() {
/*if self.common.tool_panel.home_btn.clicked() {
// TODO Maybe put a loading screen around these.
ui.primary
.map
@ -240,7 +240,7 @@ impl State for EditMode {
// Parking state might've changed
ui.primary.clear_sim();
return Transition::Replace(Box::new(SandboxMode::new(ctx, ui, self.mode.clone())));
}
}*/
Transition::Keep
}

View File

@ -10,7 +10,7 @@ use stretch::geometry::{Rect, Size};
use stretch::node::{Node, Stretch};
use stretch::style::{AlignItems, Dimension, FlexDirection, FlexWrap, JustifyContent, Style};
type Callback = Box<dyn Fn(&mut EventCtx, &mut UI) -> Option<Transition>>;
pub type Callback = Box<dyn Fn(&mut EventCtx, &mut UI) -> Option<Transition>>;
pub struct ManagedWidget {
widget: WidgetType,
@ -32,6 +32,7 @@ struct LayoutStyle {
justify_content: Option<JustifyContent>,
flex_wrap: Option<FlexWrap>,
padding: Option<Rect<Dimension>>,
min_size: Option<Size<Dimension>>,
}
impl LayoutStyle {
@ -48,6 +49,9 @@ impl LayoutStyle {
if let Some(x) = self.padding {
style.padding = x;
}
if let Some(x) = self.min_size {
style.min_size = x;
}
}
}
@ -61,6 +65,7 @@ impl ManagedWidget {
justify_content: None,
flex_wrap: None,
padding: None,
min_size: None,
},
rect: None,
bg: None,
@ -99,6 +104,14 @@ impl ManagedWidget {
self
}
pub fn min_width(mut self, pixels: usize) -> ManagedWidget {
self.style.min_size = Some(Size {
width: Dimension::Points(pixels as f32),
height: Dimension::Undefined,
});
self
}
pub fn draw_batch(ctx: &EventCtx, batch: GeomBatch) -> ManagedWidget {
ManagedWidget::new(WidgetType::Draw(JustDraw::wrap(DrawBoth::new(
ctx,
@ -116,14 +129,17 @@ impl ManagedWidget {
ManagedWidget::new(WidgetType::Draw(JustDraw::svg(filename, ctx)))
}
pub fn btn(btn: Button, onclick: Callback) -> ManagedWidget {
ManagedWidget::new(WidgetType::Btn(btn, onclick))
}
pub fn img_button(
ctx: &EventCtx,
filename: &str,
hotkey: Option<MultiKey>,
onclick: Callback,
) -> ManagedWidget {
let btn = Button::rectangle_img(filename, hotkey, ctx);
ManagedWidget::new(WidgetType::Btn(btn, onclick))
ManagedWidget::btn(Button::rectangle_img(filename, hotkey, ctx), onclick)
}
pub fn svg_button(
@ -133,14 +149,16 @@ impl ManagedWidget {
hotkey: Option<MultiKey>,
onclick: Callback,
) -> ManagedWidget {
let btn = Button::rectangle_svg(
filename,
tooltip,
hotkey,
RewriteColor::Change(Color::WHITE, Color::ORANGE),
ctx,
);
ManagedWidget::new(WidgetType::Btn(btn, onclick))
ManagedWidget::btn(
Button::rectangle_svg(
filename,
tooltip,
hotkey,
RewriteColor::Change(Color::WHITE, Color::ORANGE),
ctx,
),
onclick,
)
}
pub fn text_button(
@ -164,8 +182,10 @@ impl ManagedWidget {
onclick: Callback,
) -> ManagedWidget {
// TODO Default style. Lots of variations.
let btn = Button::text(txt, Color::WHITE, Color::ORANGE, hotkey, "", ctx);
ManagedWidget::new(WidgetType::Btn(btn, onclick))
ManagedWidget::btn(
Button::text(txt, Color::WHITE, Color::ORANGE, hotkey, "", ctx),
onclick,
)
}
pub fn row(widgets: Vec<ManagedWidget>) -> ManagedWidget {

View File

@ -1,4 +1,4 @@
use crate::common::{CommonState, ObjectColorer, ObjectColorerBuilder, Warping};
use crate::common::{CommonState, ObjectColorer, ObjectColorerBuilder, ToolPanel, Warping};
use crate::game::{State, Transition, WizardState};
use crate::helpers::ID;
use crate::mission::pick_time_range;
@ -122,7 +122,11 @@ impl ScenarioManager {
],
ctx,
),
common: CommonState::new(ctx, false),
common: CommonState::new(ToolPanel::new(
ctx,
Box::new(|_, _| Some(Transition::Pop)),
None,
)),
scenario,
trips_from_bldg,
trips_to_bldg,
@ -239,9 +243,6 @@ impl State for ScenarioManager {
if let Some(t) = self.common.event(ctx, ui) {
return t;
}
if self.common.tool_panel.home_btn.clicked() {
return Transition::Pop;
}
Transition::Keep
}

View File

@ -5,7 +5,7 @@ mod score;
mod speed;
use self::overlays::Overlays;
use crate::common::{AgentTools, CommonState, Minimap};
use crate::common::{AgentTools, CommonState, Minimap, ToolPanel};
use crate::debug::DebugMode;
use crate::edit::EditMode;
use crate::edit::{apply_map_edits, save_edits};
@ -43,7 +43,69 @@ impl SandboxMode {
agent_meter: AgentMeter::new(ctx, ui),
agent_tools: AgentTools::new(),
overlay: Overlays::Inactive,
common: CommonState::new(ctx, true),
// TODO Clear edits?
common: CommonState::new(ToolPanel::new(
ctx,
Box::new(|_, _| {
Some(Transition::Push(WizardState::new(Box::new(
move |wiz, ctx, ui| {
let mut wizard = wiz.wrap(ctx);
let dirty = ui.primary.map.get_edits().dirty;
let (resp, _) = wizard.choose(
"Sure you want to abandon the current challenge?",
|| {
let mut choices = Vec::new();
choices.push(Choice::new("keep playing", ()));
if dirty {
choices.push(Choice::new("save edits and quit", ()));
}
choices.push(Choice::new("quit challenge", ()).key(Key::Q));
choices
},
)?;
let map_name = ui.primary.map.get_name().to_string();
match resp.as_str() {
"save edits and quit" => {
save_edits(&mut wizard, ui)?;
// Always reset edits if we just saved edits.
apply_map_edits(
&mut ui.primary,
&ui.cs,
ctx,
MapEdits::new(map_name),
);
ui.primary.map.mark_edits_fresh();
ui.primary.map.recalculate_pathfinding_after_edits(
&mut Timer::new("reset edits"),
);
ui.primary.clear_sim();
Some(Transition::Clear(main_menu(ctx, ui)))
}
"quit challenge" => {
if !ui.primary.map.get_edits().is_empty() {
apply_map_edits(
&mut ui.primary,
&ui.cs,
ctx,
MapEdits::new(map_name),
);
ui.primary.map.mark_edits_fresh();
ui.primary.map.recalculate_pathfinding_after_edits(
&mut Timer::new("reset edits"),
);
}
ui.primary.clear_sim();
Some(Transition::Clear(main_menu(ctx, ui)))
}
"keep playing" => Some(Transition::Pop),
_ => unreachable!(),
}
},
))))
}),
Some(Box::new(Overlays::change_overlays)),
)),
minimap: if mode.has_minimap() {
Some(Minimap::new())
} else {
@ -182,61 +244,9 @@ impl State for SandboxMode {
if let Some(t) = self.common.event(ctx, ui) {
return t;
}
if let Some(t) = self.overlay.event(
ctx,
ui,
self.common.tool_panel.layers_btn.as_mut().unwrap(),
&self.gameplay.prebaked,
) {
if let Some(t) = self.overlay.event(ctx, ui, &self.gameplay.prebaked) {
return t;
}
if self.common.tool_panel.home_btn.clicked() {
// TODO Clear edits?
return Transition::Push(WizardState::new(Box::new(move |wiz, ctx, ui| {
let mut wizard = wiz.wrap(ctx);
let dirty = ui.primary.map.get_edits().dirty;
let (resp, _) =
wizard.choose("Sure you want to abandon the current challenge?", || {
let mut choices = Vec::new();
choices.push(Choice::new("keep playing", ()));
if dirty {
choices.push(Choice::new("save edits and quit", ()));
}
choices.push(Choice::new("quit challenge", ()).key(Key::Q));
choices
})?;
let map_name = ui.primary.map.get_name().to_string();
match resp.as_str() {
"save edits and quit" => {
save_edits(&mut wizard, ui)?;
// Always reset edits if we just saved edits.
apply_map_edits(&mut ui.primary, &ui.cs, ctx, MapEdits::new(map_name));
ui.primary.map.mark_edits_fresh();
ui.primary
.map
.recalculate_pathfinding_after_edits(&mut Timer::new("reset edits"));
ui.primary.clear_sim();
Some(Transition::Clear(main_menu(ctx, ui)))
}
"quit challenge" => {
if !ui.primary.map.get_edits().is_empty() {
apply_map_edits(&mut ui.primary, &ui.cs, ctx, MapEdits::new(map_name));
ui.primary.map.mark_edits_fresh();
ui.primary
.map
.recalculate_pathfinding_after_edits(&mut Timer::new(
"reset edits",
));
}
ui.primary.clear_sim();
Some(Transition::Clear(main_menu(ctx, ui)))
}
"keep playing" => Some(Transition::Pop),
_ => unreachable!(),
}
})));
}
if self.speed.is_paused() {
Transition::Keep

View File

@ -8,7 +8,7 @@ use crate::sandbox::bus_explorer::ShowBusRoute;
use crate::sandbox::SandboxMode;
use crate::ui::{ShowEverything, UI};
use abstutil::{prettyprint_usize, Counter};
use ezgui::{Button, Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, Text};
use ezgui::{Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, Text};
use geom::{Distance, Duration, PolyLine, Statistic, Time};
use map_model::{IntersectionID, RoadID};
use sim::{Analytics, ParkingSpot, TripMode};
@ -52,44 +52,8 @@ impl Overlays {
&mut self,
ctx: &mut EventCtx,
ui: &UI,
btn: &mut Button,
baseline: &Analytics,
) -> Option<Transition> {
if btn.clicked() {
return Some(Transition::Push(WizardState::new(Box::new(
|wiz, ctx, _| {
let (choice, _) =
wiz.wrap(ctx).choose("Show which analytics overlay?", || {
// TODO Filter out the current
vec![
Choice::new("none", ()).key(Key::N),
Choice::new("parking availability", ()).key(Key::P),
Choice::new("intersection delay", ()).key(Key::I),
Choice::new("cumulative throughput", ()).key(Key::T),
Choice::new("finished trips", ()).key(Key::F),
// TODO baseline borrow doesn't live long enough
//Choice::new("finished trips histogram", ()).key(Key::H),
Choice::new("bike network", ()).key(Key::B),
Choice::new("bus network", ()).key(Key::U),
]
})?;
Some(Transition::PopWithData(Box::new(move |state, ui, ctx| {
let mut sandbox = state.downcast_mut::<SandboxMode>().unwrap();
sandbox.overlay = match choice.as_ref() {
"none" => Overlays::Inactive,
"parking availability" => Overlays::parking_availability(ctx, ui),
"intersection delay" => Overlays::intersection_delay(ctx, ui),
"cumulative throughput" => Overlays::cumulative_throughput(ctx, ui),
"finished trips" => Overlays::finished_trips(ctx, ui),
"bike network" => Overlays::bike_network(ctx, ui),
"bus network" => Overlays::bus_network(ctx, ui),
_ => unreachable!(),
};
})))
},
))));
}
let now = ui.primary.sim.time();
match self {
// Don't bother with Inactive, BusRoute, BusDelaysOverTime, BikeNetwork, BusNetwork --
@ -190,6 +154,40 @@ impl Overlays {
}
}
}
pub fn change_overlays(_: &mut EventCtx, _: &mut UI) -> Option<Transition> {
Some(Transition::Push(WizardState::new(Box::new(
|wiz, ctx, _| {
let (choice, _) = wiz.wrap(ctx).choose("Show which analytics overlay?", || {
// TODO Filter out the current
vec![
Choice::new("none", ()).key(Key::N),
Choice::new("parking availability", ()).key(Key::P),
Choice::new("intersection delay", ()).key(Key::I),
Choice::new("cumulative throughput", ()).key(Key::T),
Choice::new("finished trips", ()).key(Key::F),
// TODO baseline borrow doesn't live long enough
//Choice::new("finished trips histogram", ()).key(Key::H),
Choice::new("bike network", ()).key(Key::B),
Choice::new("bus network", ()).key(Key::U),
]
})?;
Some(Transition::PopWithData(Box::new(move |state, ui, ctx| {
let mut sandbox = state.downcast_mut::<SandboxMode>().unwrap();
sandbox.overlay = match choice.as_ref() {
"none" => Overlays::Inactive,
"parking availability" => Overlays::parking_availability(ctx, ui),
"intersection delay" => Overlays::intersection_delay(ctx, ui),
"cumulative throughput" => Overlays::cumulative_throughput(ctx, ui),
"finished trips" => Overlays::finished_trips(ctx, ui),
"bike network" => Overlays::bike_network(ctx, ui),
"bus network" => Overlays::bus_network(ctx, ui),
_ => unreachable!(),
};
})))
},
))))
}
}
impl Overlays {