Share the panel style too for pathfinding. (It was a bigger change, easier to separate)

This commit is contained in:
Dustin Carlino 2021-12-29 11:54:12 +00:00
parent 4264682be8
commit 1e414d0f31
6 changed files with 88 additions and 82 deletions

View File

@ -36,18 +36,20 @@ impl Viewer {
app: &App,
neighborhood: Neighborhood,
) -> Box<dyn State<App>> {
let panel = Tab::Connectivity.make_panel(
ctx,
app,
Widget::col(vec![
Widget::row(vec![
"Draw traffic cells as".text_widget(ctx).centered_vert(),
Toggle::choice(ctx, "draw cells", "areas", "streets", Key::D, true),
let panel = Tab::Connectivity
.panel_builder(
ctx,
app,
Widget::col(vec![
Widget::row(vec![
"Draw traffic cells as".text_widget(ctx).centered_vert(),
Toggle::choice(ctx, "draw cells", "areas", "streets", Key::D, true),
]),
"Click a road to add or remove a modal filter".text_widget(ctx),
Text::new().into_widget(ctx).named("warnings"),
]),
"Click a road to add or remove a modal filter".text_widget(ctx),
Text::new().into_widget(ctx).named("warnings"),
]),
);
)
.build(ctx);
let mut viewer = Viewer {
panel,

View File

@ -1,6 +1,6 @@
use map_gui::tools::CityPicker;
use widgetry::{
EventCtx, HorizontalAlignment, Key, Panel, State, VerticalAlignment, Widget,
EventCtx, HorizontalAlignment, Key, Panel, PanelBuilder, State, VerticalAlignment, Widget,
DEFAULT_CORNER_RADIUS,
};
@ -19,7 +19,12 @@ pub trait TakeNeighborhood {
}
impl Tab {
pub fn make_panel(self, ctx: &mut EventCtx, app: &App, per_tab_contents: Widget) -> Panel {
pub fn panel_builder(
self,
ctx: &mut EventCtx,
app: &App,
per_tab_contents: Widget,
) -> PanelBuilder {
Panel::new_builder(Widget::col(vec![
map_gui::tools::app_header(ctx, app, "Low traffic neighborhoods"),
Widget::row(vec![
@ -38,7 +43,6 @@ impl Tab {
per_tab_contents.tab_body(ctx),
]))
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
.build(ctx)
}
pub fn must_handle_action<T: TakeNeighborhood + State<App>>(

View File

@ -67,49 +67,53 @@ impl BrowseRatRuns {
fn recalculate(&mut self, ctx: &mut EventCtx, app: &App) {
if self.rat_runs.paths.is_empty() {
self.panel = Tab::RatRuns.make_panel(ctx, app, "No rat runs detected".text_widget(ctx));
self.panel = Tab::RatRuns
.panel_builder(ctx, app, "No rat runs detected".text_widget(ctx))
.build(ctx);
return;
}
self.panel = Tab::RatRuns.make_panel(
ctx,
app,
Widget::col(vec![
Widget::row(vec![
"Rat runs:".text_widget(ctx).centered_vert(),
ctx.style()
.btn_prev()
.disabled(self.current_idx == 0)
.hotkey(Key::LeftArrow)
.build_widget(ctx, "previous rat run"),
Text::from(
Line(format!(
"{}/{}",
self.current_idx + 1,
self.rat_runs.paths.len()
))
.secondary(),
)
.into_widget(ctx)
.centered_vert(),
ctx.style()
.btn_next()
.disabled(self.current_idx == self.rat_runs.paths.len() - 1)
.hotkey(Key::RightArrow)
.build_widget(ctx, "next rat run"),
self.panel = Tab::RatRuns
.panel_builder(
ctx,
app,
Widget::col(vec![
Widget::row(vec![
"Rat runs:".text_widget(ctx).centered_vert(),
ctx.style()
.btn_prev()
.disabled(self.current_idx == 0)
.hotkey(Key::LeftArrow)
.build_widget(ctx, "previous rat run"),
Text::from(
Line(format!(
"{}/{}",
self.current_idx + 1,
self.rat_runs.paths.len()
))
.secondary(),
)
.into_widget(ctx)
.centered_vert(),
ctx.style()
.btn_next()
.disabled(self.current_idx == self.rat_runs.paths.len() - 1)
.hotkey(Key::RightArrow)
.build_widget(ctx, "next rat run"),
]),
// TODO This should disable the individual path controls, or maybe even be a different
// state entirely...
Toggle::checkbox(
ctx,
"show heatmap of all rat-runs",
Key::R,
self.panel
.maybe_is_checked("show heatmap of all rat-runs")
.unwrap_or(true),
),
]),
// TODO This should disable the individual path controls, or maybe even be a different
// state entirely...
Toggle::checkbox(
ctx,
"show heatmap of all rat-runs",
Key::R,
self.panel
.maybe_is_checked("show heatmap of all rat-runs")
.unwrap_or(true),
),
]),
);
)
.build(ctx);
let mut draw_path = ToggleZoomed::builder();
let color = Color::RED;

View File

@ -3,10 +3,10 @@ use map_model::NORMAL_LANE_THICKNESS;
use sim::{TripEndpoint, TripMode};
use widgetry::mapspace::{ObjectID, ToggleZoomed, World};
use widgetry::{
Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, RoundedF64, Spinner,
State, Text, VerticalAlignment, Widget,
Color, EventCtx, GfxCtx, Line, Outcome, Panel, RoundedF64, Spinner, State, Text, Widget,
};
use super::per_neighborhood::{Tab, TakeNeighborhood};
use super::Neighborhood;
use crate::app::{App, Transition};
use crate::common::{cmp_dist, cmp_duration, InputWaypoints, WaypointID};
@ -19,6 +19,12 @@ pub struct RoutePlanner {
neighborhood: Neighborhood,
}
impl TakeNeighborhood for RoutePlanner {
fn take_neighborhood(self) -> Neighborhood {
self.neighborhood
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
enum ID {
RouteAfterFilters,
@ -44,12 +50,7 @@ impl RoutePlanner {
}
fn update(&mut self, ctx: &mut EventCtx, app: &App) {
let mut panel = Panel::new_builder(Widget::col(vec![
ctx.style()
.btn_outline
.text("Back to editing modal filters")
.hotkey(Key::Escape)
.build_def(ctx),
let contents = Widget::col(vec![
self.waypoints.get_panel_widget(ctx),
Widget::row(vec![
Line("Slow-down factor for main roads:")
@ -63,11 +64,12 @@ impl RoutePlanner {
])
.into_widget(ctx),
Text::new().into_widget(ctx).named("note"),
]))
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
// Hovering on waypoint cards
.ignore_initial_events()
.build(ctx);
]);
let mut panel = Tab::Pathfinding
.panel_builder(ctx, app, contents)
// Hovering on waypoint cards
.ignore_initial_events()
.build(ctx);
panel.restore(ctx, &self.panel);
self.panel = panel;
@ -229,20 +231,7 @@ impl State<App> for RoutePlanner {
let panel_outcome = self.panel.event(ctx);
if let Outcome::Clicked(ref x) = panel_outcome {
if x == "Back to editing modal filters" {
// We'll cache a custom pathfinder per set of avoided roads. Avoid leaking memory
// by clearing this out
app.primary.map.clear_custom_pathfinder_cache();
return Transition::ConsumeState(Box::new(|state, ctx, app| {
let state = state.downcast::<RoutePlanner>().ok().unwrap();
vec![super::connectivity::Viewer::new_state(
ctx,
app,
state.neighborhood,
)]
}));
}
return Tab::Pathfinding.must_handle_action::<RoutePlanner>(ctx, app, x);
}
if let Outcome::Changed(ref x) = panel_outcome {
@ -278,4 +267,10 @@ impl State<App> for RoutePlanner {
self.world.draw(g);
}
fn on_destroy(&mut self, _: &mut EventCtx, app: &mut App) {
// We'll cache a custom pathfinder per set of avoided roads. Avoid leaking memory by
// clearing this out
app.primary.map.clear_custom_pathfinder_cache();
}
}

View File

@ -75,7 +75,8 @@ pub use crate::widgets::text_box::TextBox;
pub use crate::widgets::toggle::Toggle;
pub use crate::widgets::DEFAULT_CORNER_RADIUS;
pub use crate::widgets::{
ClickOutcome, CornerRounding, EdgeInsets, Outcome, Panel, Widget, WidgetImpl, WidgetOutput,
ClickOutcome, CornerRounding, EdgeInsets, Outcome, Panel, PanelBuilder, Widget, WidgetImpl,
WidgetOutput,
};
mod app_state;

View File

@ -11,7 +11,7 @@ use abstutil::CloneableAny;
use geom::{CornerRadii, Distance, Percent, Polygon};
use crate::widgets::containers::{Container, Nothing};
pub use crate::widgets::panel::Panel;
pub use crate::widgets::panel::{Panel, PanelBuilder};
use crate::{
Button, Choice, Color, DeferDraw, Drawable, Dropdown, EventCtx, GeomBatch, GfxCtx, JustDraw,
OutlineStyle, ScreenDims, ScreenPt, ScreenRectangle, Toggle,