Don't erase modal filters when switching neighborhoods

This commit is contained in:
Dustin Carlino 2021-11-06 15:58:28 -07:00
parent 7e07bac35a
commit 6b766ea750
3 changed files with 22 additions and 26 deletions

View File

@ -1,5 +1,5 @@
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, BTreeSet};
use anyhow::Result;
use maplit::btreemap;
@ -14,7 +14,7 @@ use map_gui::render::{unzoomed_agent_radius, AgentCache, DrawMap, DrawOptions, R
use map_gui::tools::CameraState;
use map_gui::ID;
use map_model::AreaType;
use map_model::{BufferType, IntersectionID, LaneType, Map, Traversable};
use map_model::{BufferType, IntersectionID, LaneType, Map, RoadID, Traversable};
use sim::{AgentID, Analytics, Scenario, Sim, SimCallback, SimFlags, VehicleType};
use widgetry::mapspace::ToggleZoomed;
use widgetry::{Cached, Canvas, EventCtx, GfxCtx, Prerender, SharedAppState, State};
@ -756,6 +756,9 @@ pub struct SessionState {
pub ungap_current_trip_name: Option<String>,
// Map and edit change key
pub mode_shift: Cached<(MapName, usize), crate::ungap::ModeShiftData>,
// Specific to LTN
pub modal_filters: BTreeSet<RoadID>,
}
impl SessionState {
@ -778,6 +781,8 @@ impl SessionState {
routing_preferences: crate::ungap::RoutingPreferences::default(),
ungap_current_trip_name: None,
mode_shift: Cached::new(),
modal_filters: BTreeSet::new(),
}
}
}

View File

@ -17,8 +17,8 @@ struct Neighborhood {
perimeter: BTreeSet<RoadID>,
borders: BTreeSet<IntersectionID>,
// The cells change as a result of modal filters
modal_filters: BTreeSet<RoadID>,
// The cells change as a result of modal filters, which're stored for all neighborhoods in
// app.session.
cells: Vec<BTreeSet<RoadID>>,
fade_irrelevant: Drawable,
@ -26,21 +26,15 @@ struct Neighborhood {
}
impl Neighborhood {
fn new(
ctx: &EventCtx,
app: &App,
orig_perimeter: Perimeter,
modal_filters: BTreeSet<RoadID>,
) -> Neighborhood {
fn new(ctx: &EventCtx, app: &App, orig_perimeter: Perimeter) -> Neighborhood {
let map = &app.primary.map;
let cells = find_cells(map, &orig_perimeter, &modal_filters);
let cells = find_cells(map, &orig_perimeter, &app.session.modal_filters);
let mut n = Neighborhood {
orig_perimeter,
perimeter: BTreeSet::new(),
borders: BTreeSet::new(),
modal_filters,
cells,
fade_irrelevant: Drawable::empty(ctx),
@ -77,7 +71,11 @@ impl Neighborhood {
n.fade_irrelevant = GeomBatch::from(vec![(app.cs.fade_map_dark, fade_area)]).upload(ctx);
let mut batch = GeomBatch::new();
for r in &n.modal_filters {
for r in &app.session.modal_filters {
if !n.orig_perimeter.interior.contains(r) {
continue;
}
let road = map.get_r(*r);
// If this road touches a border, place it closer to that intersection. If it's an
// inner neighborhood split, then stick to the middle of that road.

View File

@ -1,5 +1,3 @@
use std::collections::BTreeSet;
use geom::Distance;
use map_gui::tools::{CityPicker, DrawRoadLabels};
use map_model::{Block, RoadID};
@ -43,8 +41,7 @@ impl Viewer {
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
.build(ctx);
let modal_filters = BTreeSet::new();
let neighborhood = Neighborhood::new(ctx, app, block.perimeter.clone(), modal_filters);
let neighborhood = Neighborhood::new(ctx, app, block.perimeter.clone());
let mut label_roads = neighborhood.perimeter.clone();
label_roads.extend(neighborhood.orig_perimeter.interior.clone());
@ -82,19 +79,15 @@ impl State<App> for Viewer {
match self.world.event(ctx) {
WorldOutcome::ClickedObject(Obj::InteriorRoad(r)) => {
if self.neighborhood.modal_filters.contains(&r) {
self.neighborhood.modal_filters.remove(&r);
if app.session.modal_filters.contains(&r) {
app.session.modal_filters.remove(&r);
} else {
self.neighborhood.modal_filters.insert(r);
app.session.modal_filters.insert(r);
}
// TODO The cell coloring changes quite spuriously just by toggling a filter, even
// when it doesn't matter
self.neighborhood = Neighborhood::new(
ctx,
app,
self.neighborhood.orig_perimeter.clone(),
std::mem::take(&mut self.neighborhood.modal_filters),
);
self.neighborhood =
Neighborhood::new(ctx, app, self.neighborhood.orig_perimeter.clone());
self.world = make_world(ctx, app, &self.neighborhood);
}
_ => {}