From 973f733d360ae198a101ee5641e52c0b3a404a67 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sat, 15 Jan 2022 18:23:13 +0000 Subject: [PATCH] Preview cell connectivity from the browse neighborhoods screen --- game/src/ltn/browse.rs | 87 ++++++++++++++++++++++++++++++------------ game/src/ltn/mod.rs | 3 +- 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/game/src/ltn/browse.rs b/game/src/ltn/browse.rs index 5a74082b86..626334bae4 100644 --- a/game/src/ltn/browse.rs +++ b/game/src/ltn/browse.rs @@ -1,15 +1,14 @@ use std::collections::HashSet; -use abstutil::Timer; use geom::Distance; use map_gui::tools::{CityPicker, DrawRoadLabels, Navigator, PopupMsg, URLManager}; use widgetry::mapspace::{ToggleZoomed, World, WorldOutcome}; use widgetry::{ - lctrl, Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Outcome, Panel, State, TextExt, - Toggle, VerticalAlignment, Widget, + lctrl, Choice, Color, EventCtx, GfxCtx, HorizontalAlignment, Key, Outcome, Panel, State, + TextExt, Toggle, VerticalAlignment, Widget, }; -use super::{NeighborhoodID, Partitioning}; +use super::{Neighborhood, NeighborhoodID, Partitioning}; use crate::app::{App, Transition}; use crate::debug::DebugMode; @@ -25,8 +24,14 @@ impl BrowseNeighborhoods { pub fn new_state(ctx: &mut EventCtx, app: &mut App) -> Box> { URLManager::update_url_map_name(app); + let style = Style::SimpleColoring; let world = ctx.loading_screen("calculate neighborhoods", |ctx, timer| { - detect_neighborhoods(ctx, app, timer) + // TODO Or if the map doesn't match? Do we take care of this in SessionState for + // anything?! + if app.session.partitioning.neighborhoods.is_empty() { + app.session.partitioning = Partitioning::seed_using_heuristics(app, timer); + } + make_world(ctx, app, style) }); let draw_all_filters = app.session.modal_filters.draw(ctx, &app.primary.map, None); @@ -42,6 +47,18 @@ impl BrowseNeighborhoods { .align_right(), ]), Toggle::checkbox(ctx, "highlight boundary roads", Key::H, true), + Widget::row(vec![ + "Draw neighborhoods:".text_widget(ctx).centered_vert(), + Widget::dropdown( + ctx, + "style", + style, + vec![ + Choice::new("simple", Style::SimpleColoring), + Choice::new("cells", Style::Cells), + ], + ), + ]), ctx.style() .btn_outline .text("Export to GeoJSON") @@ -61,8 +78,8 @@ impl BrowseNeighborhoods { impl State for BrowseNeighborhoods { fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition { - 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() { "Home" => { return Transition::Clear(vec![crate::pregame::TitleScreen::new_state( ctx, app, @@ -99,7 +116,13 @@ impl State for BrowseNeighborhoods { }); } _ => unreachable!(), + }, + Outcome::Changed(_) => { + self.world = ctx.loading_screen("change style", |ctx, _| { + make_world(ctx, app, self.panel.dropdown_value("style")) + }); } + _ => {} } if let WorldOutcome::ClickedObject(id) = self.world.event(ctx) { @@ -126,25 +149,35 @@ impl State for BrowseNeighborhoods { } } -fn detect_neighborhoods( - ctx: &mut EventCtx, - app: &mut App, - timer: &mut Timer, -) -> World { - // TODO Or if the map doesn't match? Do we take care of this in SessionState for anything?! - if app.session.partitioning.neighborhoods.is_empty() { - app.session.partitioning = Partitioning::seed_using_heuristics(app, timer); - } - +fn make_world(ctx: &mut EventCtx, app: &App, style: Style) -> World { let mut world = World::bounded(app.primary.map.get_bounds()); for (id, (block, color)) in &app.session.partitioning.neighborhoods { - world - .add(*id) - .hitbox(block.polygon.clone()) - .draw_color(color.alpha(0.5)) - .hover_outline(Color::BLACK, Distance::meters(5.0)) - .clickable() - .build(ctx); + match style { + Style::SimpleColoring => { + world + .add(*id) + .hitbox(block.polygon.clone()) + .draw_color(color.alpha(0.5)) + .hover_outline(Color::BLACK, Distance::meters(5.0)) + .clickable() + .build(ctx); + } + Style::Cells => { + // TODO The cell colors are confusing alongside the other neighborhood colors. I + // tried greying out everything else, but then the view is too jumpy. + let map = &app.primary.map; + let neighborhood = Neighborhood::new(ctx, app, *id); + let render_cells = super::draw_cells::RenderCells::new(map, &neighborhood); + let hovered_batch = render_cells.draw_grid(); + world + .add(*id) + .hitbox(block.polygon.clone()) + .draw_color(color.alpha(0.5)) + .draw_hovered(hovered_batch) + .clickable() + .build(ctx); + } + } } world } @@ -186,3 +219,9 @@ fn draw_boundary_roads(ctx: &EventCtx, app: &App) -> ToggleZoomed { } batch.build(ctx) } + +#[derive(Clone, Copy, Debug, PartialEq)] +enum Style { + SimpleColoring, + Cells, +} diff --git a/game/src/ltn/mod.rs b/game/src/ltn/mod.rs index 8df0568b68..d3761c47df 100644 --- a/game/src/ltn/mod.rs +++ b/game/src/ltn/mod.rs @@ -170,7 +170,7 @@ fn find_cells( no_car_roads.push(start); continue; } - let cell = floodfill(map, start, perimeter, borders, &modal_filters); + let cell = floodfill(map, start, borders, &modal_filters); visited.extend(cell.roads.keys().cloned()); cells.push(cell); } @@ -244,7 +244,6 @@ fn find_cells( fn floodfill( map: &Map, start: RoadID, - perimeter: &Perimeter, neighborhood_borders: &BTreeSet, modal_filters: &ModalFilters, ) -> Cell {