mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 00:12:55 +03:00
make plugins track their own active state
This commit is contained in:
parent
2770b59f85
commit
d54bce01ac
7
TODO.md
7
TODO.md
@ -69,12 +69,17 @@
|
|||||||
- clean up code
|
- clean up code
|
||||||
- master Map struct
|
- master Map struct
|
||||||
- line type / ditch vec2d / settle on types
|
- 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
|
- one-at-a-time UI plugins
|
||||||
- UI plugins track their own active state
|
- UI plugins track their own active state
|
||||||
- UI colors in one place
|
- 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
|
- add/plan tests
|
||||||
- document pieces that're stabilizing
|
- document pieces that're stabilizing
|
||||||
- run clippy everywhere
|
- run clippy everywhere
|
||||||
|
@ -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
|
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
|
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.
|
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.
|
||||||
|
@ -1,14 +1,37 @@
|
|||||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
use colors::{ColorScheme, Colors};
|
use colors::{ColorScheme, Colors};
|
||||||
|
use ezgui::input::UserInput;
|
||||||
use graphics::types::Color;
|
use graphics::types::Color;
|
||||||
use map_model;
|
use map_model;
|
||||||
|
use piston::input::Key;
|
||||||
|
|
||||||
// TODO have some UI for editing these rules and saving them
|
// TODO have some UI for editing these rules and saving them
|
||||||
pub struct OsmClassifier {}
|
pub struct OsmClassifier {
|
||||||
|
active: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl OsmClassifier {
|
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<Color> {
|
pub fn color_r(&self, r: &map_model::Road, cs: &ColorScheme) -> Option<Color> {
|
||||||
|
if !self.active {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
for tag in &r.osm_tags {
|
for tag in &r.osm_tags {
|
||||||
if tag == "highway=primary" || tag == "highway=secondary" || tag == "highway=tertiary" {
|
if tag == "highway=primary" || tag == "highway=secondary" || tag == "highway=tertiary" {
|
||||||
return Some(cs.get(Colors::MatchClassification));
|
return Some(cs.get(Colors::MatchClassification));
|
||||||
@ -17,6 +40,10 @@ impl OsmClassifier {
|
|||||||
Some(cs.get(Colors::DontMatchClassification))
|
Some(cs.get(Colors::DontMatchClassification))
|
||||||
}
|
}
|
||||||
pub fn color_b(&self, b: &map_model::Building, cs: &ColorScheme) -> Option<Color> {
|
pub fn color_b(&self, b: &map_model::Building, cs: &ColorScheme) -> Option<Color> {
|
||||||
|
if !self.active {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
for tag in &b.osm_tags {
|
for tag in &b.osm_tags {
|
||||||
if tag.contains("addr:housenumber") {
|
if tag.contains("addr:housenumber") {
|
||||||
return Some(cs.get(Colors::MatchClassification));
|
return Some(cs.get(Colors::MatchClassification));
|
||||||
|
@ -4,11 +4,14 @@
|
|||||||
|
|
||||||
extern crate map_model;
|
extern crate map_model;
|
||||||
|
|
||||||
|
use ezgui::input::UserInput;
|
||||||
use graphics::types::Color;
|
use graphics::types::Color;
|
||||||
use map_model::{Map, Road};
|
use map_model::{Map, Road};
|
||||||
|
use piston::input::Key;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
|
|
||||||
pub struct SteepnessVisualizer {
|
pub struct SteepnessVisualizer {
|
||||||
|
active: bool,
|
||||||
min_difference: f64,
|
min_difference: f64,
|
||||||
max_difference: f64,
|
max_difference: f64,
|
||||||
}
|
}
|
||||||
@ -16,6 +19,7 @@ pub struct SteepnessVisualizer {
|
|||||||
impl SteepnessVisualizer {
|
impl SteepnessVisualizer {
|
||||||
pub fn new(map: &Map) -> SteepnessVisualizer {
|
pub fn new(map: &Map) -> SteepnessVisualizer {
|
||||||
let mut s = SteepnessVisualizer {
|
let mut s = SteepnessVisualizer {
|
||||||
|
active: false,
|
||||||
min_difference: f64::MAX,
|
min_difference: f64::MAX,
|
||||||
max_difference: f64::MIN_POSITIVE,
|
max_difference: f64::MIN_POSITIVE,
|
||||||
};
|
};
|
||||||
@ -31,6 +35,17 @@ impl SteepnessVisualizer {
|
|||||||
s
|
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 {
|
fn get_delta(&self, map: &Map, r: &Road) -> f64 {
|
||||||
let e1 = map.get_source_intersection(r.id).elevation_meters;
|
let e1 = map.get_source_intersection(r.id).elevation_meters;
|
||||||
let e2 = map.get_destination_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<Color> {
|
pub fn color_r(&self, map: &Map, r: &Road) -> Option<Color> {
|
||||||
|
if !self.active {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let normalized = (self.get_delta(map, r) - self.min_difference)
|
let normalized = (self.get_delta(map, r) - self.min_difference)
|
||||||
/ (self.max_difference - self.min_difference);
|
/ (self.max_difference - self.min_difference);
|
||||||
Some([normalized as f32, 0.0, 0.0, 1.0])
|
Some([normalized as f32, 0.0, 0.0, 1.0])
|
||||||
|
@ -46,9 +46,6 @@ pub struct UI {
|
|||||||
show_intersections: ToggleableLayer,
|
show_intersections: ToggleableLayer,
|
||||||
show_parcels: ToggleableLayer,
|
show_parcels: ToggleableLayer,
|
||||||
show_icons: ToggleableLayer,
|
show_icons: ToggleableLayer,
|
||||||
// TODO should these be more associated with their plugins?
|
|
||||||
steepness_active: ToggleableLayer,
|
|
||||||
osm_classifier_active: ToggleableLayer,
|
|
||||||
debug_mode: ToggleableLayer,
|
debug_mode: ToggleableLayer,
|
||||||
|
|
||||||
current_selection_state: SelectionState,
|
current_selection_state: SelectionState,
|
||||||
@ -104,14 +101,12 @@ impl UI {
|
|||||||
"7",
|
"7",
|
||||||
Some(MIN_ZOOM_FOR_ROAD_MARKERS),
|
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),
|
debug_mode: ToggleableLayer::new("debug mode", Key::G, "G", None),
|
||||||
|
|
||||||
current_selection_state: SelectionState::Empty,
|
current_selection_state: SelectionState::Empty,
|
||||||
current_search_state: SearchState::Empty,
|
current_search_state: SearchState::Empty,
|
||||||
floodfiller: None,
|
floodfiller: None,
|
||||||
osm_classifier: OsmClassifier {},
|
osm_classifier: OsmClassifier::new(),
|
||||||
traffic_signal_editor: None,
|
traffic_signal_editor: None,
|
||||||
stop_sign_editor: None,
|
stop_sign_editor: None,
|
||||||
color_picker: ColorPicker::new(),
|
color_picker: ColorPicker::new(),
|
||||||
@ -144,8 +139,6 @@ impl UI {
|
|||||||
ui.show_intersections.handle_zoom(old_zoom, new_zoom);
|
ui.show_intersections.handle_zoom(old_zoom, new_zoom);
|
||||||
ui.show_parcels.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.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.debug_mode.handle_zoom(old_zoom, new_zoom);
|
||||||
|
|
||||||
ui
|
ui
|
||||||
@ -212,8 +205,6 @@ impl UI {
|
|||||||
self.show_intersections.handle_zoom(old_zoom, new_zoom);
|
self.show_intersections.handle_zoom(old_zoom, new_zoom);
|
||||||
self.show_parcels.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.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);
|
self.debug_mode.handle_zoom(old_zoom, new_zoom);
|
||||||
|
|
||||||
if !edit_mode {
|
if !edit_mode {
|
||||||
@ -237,8 +228,8 @@ impl UI {
|
|||||||
}
|
}
|
||||||
self.show_parcels.handle_event(input);
|
self.show_parcels.handle_event(input);
|
||||||
self.show_icons.handle_event(input);
|
self.show_icons.handle_event(input);
|
||||||
self.steepness_active.handle_event(input);
|
self.steepness_viz.handle_event(input);
|
||||||
self.osm_classifier_active.handle_event(input);
|
self.osm_classifier.handle_event(input);
|
||||||
self.debug_mode.handle_event(input);
|
self.debug_mode.handle_event(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,16 +488,8 @@ impl UI {
|
|||||||
self.floodfiller
|
self.floodfiller
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|f| f.color_r(r, &self.cs)),
|
.and_then(|f| f.color_r(r, &self.cs)),
|
||||||
if self.steepness_active.is_enabled() {
|
self.steepness_viz.color_r(&self.map, r),
|
||||||
self.steepness_viz.color_r(&self.map, r)
|
self.osm_classifier.color_r(r, &self.cs),
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
if self.osm_classifier_active.is_enabled() {
|
|
||||||
self.osm_classifier.color_r(r, &self.cs)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
].iter()
|
].iter()
|
||||||
.filter_map(|c| *c)
|
.filter_map(|c| *c)
|
||||||
.next()
|
.next()
|
||||||
@ -564,11 +547,7 @@ impl UI {
|
|||||||
vec![
|
vec![
|
||||||
self.current_selection_state.color_b(b, &self.cs),
|
self.current_selection_state.color_b(b, &self.cs),
|
||||||
self.current_search_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),
|
||||||
self.osm_classifier.color_b(b, &self.cs)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
].iter()
|
].iter()
|
||||||
.filter_map(|c| *c)
|
.filter_map(|c| *c)
|
||||||
.next()
|
.next()
|
||||||
|
Loading…
Reference in New Issue
Block a user