diff --git a/TODO.md b/TODO.md index 6ecd8c6c33..ad5bc6bd18 100644 --- a/TODO.md +++ b/TODO.md @@ -69,12 +69,17 @@ - clean up code - master Map struct - line type / ditch vec2d / settle on types - - better layering: GeomParcel, GeomIntersection, etc, so that render layer doesn't need to know Bounds and use gps_to_screen - one-at-a-time UI plugins - UI plugins track their own active state - UI colors in one place + - cleaner pipeline of map construction + - serde, not pb + - logically be able to shift what gets recomputed or not + - better layering: GeomParcel, GeomIntersection, etc, so that render layer doesn't need to know Bounds and use gps_to_screen + - more uniformity with polygon + center line? + - add/plan tests - document pieces that're stabilizing - run clippy everywhere diff --git a/docs/design.md b/docs/design.md index af43d38d5f..1b00747b2d 100644 --- a/docs/design.md +++ b/docs/design.md @@ -62,3 +62,10 @@ deriving Eq is a headache. Since the timestep size is fixed anyway, this should just become ticks. Was tempted to use usize, but arch dependence is weird, and with a 0.1s timestep, 2^32 - 1 ticks is about 13.5 years, which is quite a long timescale for a traffic simulation. :) So, let's switch to u32. + +## UI plugins + +- Things like steepness visualizer used to just be UI-less logic, making it + easy to understand and test. Maybe the sim_ctrl pattern is nicer? A light +adapter to control the thing from the UI? ezgui's textbox and menu are similar +-- no rendering, some input handling. diff --git a/editor/src/plugins/classification.rs b/editor/src/plugins/classification.rs index 7c9136057d..1a74488c70 100644 --- a/editor/src/plugins/classification.rs +++ b/editor/src/plugins/classification.rs @@ -1,14 +1,37 @@ // Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0 use colors::{ColorScheme, Colors}; +use ezgui::input::UserInput; use graphics::types::Color; use map_model; +use piston::input::Key; // TODO have some UI for editing these rules and saving them -pub struct OsmClassifier {} +pub struct OsmClassifier { + active: bool, +} impl OsmClassifier { + pub fn new() -> OsmClassifier { + OsmClassifier { active: false } + } + + pub fn handle_event(&mut self, input: &mut UserInput) { + let msg = if self.active { + "Press 6 to stop showing OSM classes" + } else { + "Press 6 to show OSM classifications" + }; + if input.unimportant_key_pressed(Key::D6, msg) { + self.active = !self.active; + } + } + pub fn color_r(&self, r: &map_model::Road, cs: &ColorScheme) -> Option { + if !self.active { + return None; + } + for tag in &r.osm_tags { if tag == "highway=primary" || tag == "highway=secondary" || tag == "highway=tertiary" { return Some(cs.get(Colors::MatchClassification)); @@ -17,6 +40,10 @@ impl OsmClassifier { Some(cs.get(Colors::DontMatchClassification)) } pub fn color_b(&self, b: &map_model::Building, cs: &ColorScheme) -> Option { + if !self.active { + return None; + } + for tag in &b.osm_tags { if tag.contains("addr:housenumber") { return Some(cs.get(Colors::MatchClassification)); diff --git a/editor/src/plugins/steep.rs b/editor/src/plugins/steep.rs index 28f0881b22..d27be6c739 100644 --- a/editor/src/plugins/steep.rs +++ b/editor/src/plugins/steep.rs @@ -4,11 +4,14 @@ extern crate map_model; +use ezgui::input::UserInput; use graphics::types::Color; use map_model::{Map, Road}; +use piston::input::Key; use std::f64; pub struct SteepnessVisualizer { + active: bool, min_difference: f64, max_difference: f64, } @@ -16,6 +19,7 @@ pub struct SteepnessVisualizer { impl SteepnessVisualizer { pub fn new(map: &Map) -> SteepnessVisualizer { let mut s = SteepnessVisualizer { + active: false, min_difference: f64::MAX, max_difference: f64::MIN_POSITIVE, }; @@ -31,6 +35,17 @@ impl SteepnessVisualizer { s } + pub fn handle_event(&mut self, input: &mut UserInput) { + let msg = if self.active { + "Press 5 to stop showing steepness" + } else { + "Press 5 to visualize steepness" + }; + if input.unimportant_key_pressed(Key::D5, msg) { + self.active = !self.active; + } + } + fn get_delta(&self, map: &Map, r: &Road) -> f64 { let e1 = map.get_source_intersection(r.id).elevation_meters; let e2 = map.get_destination_intersection(r.id).elevation_meters; @@ -38,6 +53,10 @@ impl SteepnessVisualizer { } pub fn color_r(&self, map: &Map, r: &Road) -> Option { + if !self.active { + return None; + } + let normalized = (self.get_delta(map, r) - self.min_difference) / (self.max_difference - self.min_difference); Some([normalized as f32, 0.0, 0.0, 1.0]) diff --git a/editor/src/ui.rs b/editor/src/ui.rs index 1a4c6df2ca..28ca25a928 100644 --- a/editor/src/ui.rs +++ b/editor/src/ui.rs @@ -46,9 +46,6 @@ pub struct UI { show_intersections: ToggleableLayer, show_parcels: ToggleableLayer, show_icons: ToggleableLayer, - // TODO should these be more associated with their plugins? - steepness_active: ToggleableLayer, - osm_classifier_active: ToggleableLayer, debug_mode: ToggleableLayer, current_selection_state: SelectionState, @@ -104,14 +101,12 @@ impl UI { "7", Some(MIN_ZOOM_FOR_ROAD_MARKERS), ), - steepness_active: ToggleableLayer::new("steepness visualize", Key::D5, "5", None), - osm_classifier_active: ToggleableLayer::new("OSM type classifier", Key::D6, "6", None), debug_mode: ToggleableLayer::new("debug mode", Key::G, "G", None), current_selection_state: SelectionState::Empty, current_search_state: SearchState::Empty, floodfiller: None, - osm_classifier: OsmClassifier {}, + osm_classifier: OsmClassifier::new(), traffic_signal_editor: None, stop_sign_editor: None, color_picker: ColorPicker::new(), @@ -144,8 +139,6 @@ impl UI { ui.show_intersections.handle_zoom(old_zoom, new_zoom); ui.show_parcels.handle_zoom(old_zoom, new_zoom); ui.show_icons.handle_zoom(old_zoom, new_zoom); - ui.steepness_active.handle_zoom(old_zoom, new_zoom); - ui.osm_classifier_active.handle_zoom(old_zoom, new_zoom); ui.debug_mode.handle_zoom(old_zoom, new_zoom); ui @@ -212,8 +205,6 @@ impl UI { self.show_intersections.handle_zoom(old_zoom, new_zoom); self.show_parcels.handle_zoom(old_zoom, new_zoom); self.show_icons.handle_zoom(old_zoom, new_zoom); - self.steepness_active.handle_zoom(old_zoom, new_zoom); - self.osm_classifier_active.handle_zoom(old_zoom, new_zoom); self.debug_mode.handle_zoom(old_zoom, new_zoom); if !edit_mode { @@ -237,8 +228,8 @@ impl UI { } self.show_parcels.handle_event(input); self.show_icons.handle_event(input); - self.steepness_active.handle_event(input); - self.osm_classifier_active.handle_event(input); + self.steepness_viz.handle_event(input); + self.osm_classifier.handle_event(input); self.debug_mode.handle_event(input); } @@ -497,16 +488,8 @@ impl UI { self.floodfiller .as_ref() .and_then(|f| f.color_r(r, &self.cs)), - if self.steepness_active.is_enabled() { - self.steepness_viz.color_r(&self.map, r) - } else { - None - }, - if self.osm_classifier_active.is_enabled() { - self.osm_classifier.color_r(r, &self.cs) - } else { - None - }, + self.steepness_viz.color_r(&self.map, r), + self.osm_classifier.color_r(r, &self.cs), ].iter() .filter_map(|c| *c) .next() @@ -564,11 +547,7 @@ impl UI { vec![ self.current_selection_state.color_b(b, &self.cs), self.current_search_state.color_b(b, &self.cs), - if self.osm_classifier_active.is_enabled() { - self.osm_classifier.color_b(b, &self.cs) - } else { - None - }, + self.osm_classifier.color_b(b, &self.cs), ].iter() .filter_map(|c| *c) .next()