mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 11:44:25 +03:00
displaying extra arbitraryish kml for debugging
This commit is contained in:
parent
432c9644fc
commit
b55e0ae263
@ -18,6 +18,7 @@ piston2d-graphics = "*"
|
||||
piston2d-opengl_graphics = "*"
|
||||
pistoncore-glutin_window = "*"
|
||||
pretty_assertions = "0.5.1"
|
||||
quick-xml = "0.10.0"
|
||||
rand = "0.5.1"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
|
@ -174,6 +174,12 @@
|
||||
0.7,
|
||||
1.0
|
||||
],
|
||||
"ExtraShape": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"MatchClassification": [
|
||||
0.0,
|
||||
1.0,
|
||||
|
@ -41,6 +41,7 @@ pub enum Colors {
|
||||
NextQueued,
|
||||
TurnIconCircle,
|
||||
TurnIconInactive,
|
||||
ExtraShape,
|
||||
|
||||
MatchClassification,
|
||||
DontMatchClassification,
|
||||
|
128
editor/src/kml.rs
Normal file
128
editor/src/kml.rs
Normal file
@ -0,0 +1,128 @@
|
||||
use geom::{Bounds, LonLat, PolyLine, Pt2D};
|
||||
use quick_xml::events::Event;
|
||||
use quick_xml::reader::Reader;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::{f64, fmt, io};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||
pub struct ExtraShapeID(pub usize);
|
||||
|
||||
impl fmt::Display for ExtraShapeID {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "ExtraShapeID({0})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExtraShape {
|
||||
pub id: ExtraShapeID,
|
||||
pub pts: PolyLine,
|
||||
pub attributes: HashMap<String, String>,
|
||||
}
|
||||
|
||||
pub fn load(path: &String, gps_bounds: &Bounds) -> Result<Vec<ExtraShape>, io::Error> {
|
||||
println!("Opening {}", path);
|
||||
let f = File::open(path).unwrap();
|
||||
let mut reader = Reader::from_reader(io::BufReader::new(f));
|
||||
reader.trim_text(true);
|
||||
|
||||
let mut buf = Vec::new();
|
||||
let mut last_progress_byte = 0;
|
||||
|
||||
// TODO uncomfortably stateful
|
||||
let mut shapes = Vec::new();
|
||||
let mut scanned_schema = false;
|
||||
let mut attributes: HashMap<String, String> = HashMap::new();
|
||||
let mut attrib_key: Option<String> = None;
|
||||
|
||||
let mut skipped_count = 0;
|
||||
|
||||
loop {
|
||||
if reader.buffer_position() - last_progress_byte >= 1024 * 1024 * 10 {
|
||||
last_progress_byte = reader.buffer_position();
|
||||
println!(
|
||||
"Processed {} MB of {}",
|
||||
last_progress_byte / (1024 * 1024),
|
||||
path
|
||||
);
|
||||
}
|
||||
match reader.read_event(&mut buf) {
|
||||
Ok(Event::Start(e)) => {
|
||||
let name = e.unescape_and_decode(&reader).unwrap();
|
||||
if name == "Placemark" {
|
||||
scanned_schema = true;
|
||||
} else if name.starts_with("SimpleData name=\"") {
|
||||
attrib_key = Some(name["SimpleData name=\"".len()..name.len() - 1].to_string());
|
||||
} else if name == "coordinates" {
|
||||
attrib_key = Some(name);
|
||||
} else {
|
||||
attrib_key = None;
|
||||
}
|
||||
}
|
||||
Ok(Event::Text(e)) => {
|
||||
if scanned_schema {
|
||||
if let Some(ref key) = attrib_key {
|
||||
let text = e.unescape_and_decode(&reader).unwrap();
|
||||
if key == "coordinates" {
|
||||
let mut ok = true;
|
||||
let mut pts: Vec<Pt2D> = Vec::new();
|
||||
for pair in text.split(" ") {
|
||||
if let Some(pt) = parse_pt(pair, gps_bounds) {
|
||||
pts.push(pt);
|
||||
} else {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
let id = ExtraShapeID(shapes.len());
|
||||
shapes.push(ExtraShape {
|
||||
id,
|
||||
pts: PolyLine::new(pts),
|
||||
attributes: attributes.clone(),
|
||||
});
|
||||
} else {
|
||||
skipped_count += 1;
|
||||
}
|
||||
attributes.clear();
|
||||
} else {
|
||||
attributes.insert(key.to_string(), text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Event::Eof) => break,
|
||||
Err(e) => panic!(
|
||||
"XML error at position {}: {:?}",
|
||||
reader.buffer_position(),
|
||||
e
|
||||
),
|
||||
_ => (),
|
||||
}
|
||||
buf.clear();
|
||||
}
|
||||
|
||||
println!(
|
||||
"Got {} shapes from {} and skipped {} shapes",
|
||||
shapes.len(),
|
||||
path,
|
||||
skipped_count
|
||||
);
|
||||
return Ok(shapes);
|
||||
}
|
||||
|
||||
fn parse_pt(input: &str, gps_bounds: &Bounds) -> Option<Pt2D> {
|
||||
let coords: Vec<&str> = input.split(",").collect();
|
||||
if coords.len() != 2 {
|
||||
return None;
|
||||
}
|
||||
return match (coords[0].parse::<f64>(), coords[1].parse::<f64>()) {
|
||||
(Ok(lon), Ok(lat)) => if gps_bounds.contains(lon, lat) {
|
||||
Some(Pt2D::from_gps(&LonLat::new(lon, lat), gps_bounds))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
}
|
@ -14,6 +14,7 @@ extern crate graphics;
|
||||
extern crate map_model;
|
||||
extern crate opengl_graphics;
|
||||
extern crate piston;
|
||||
extern crate quick_xml;
|
||||
#[macro_use]
|
||||
extern crate pretty_assertions;
|
||||
extern crate rand;
|
||||
@ -26,6 +27,14 @@ extern crate strum;
|
||||
#[macro_use]
|
||||
extern crate strum_macros;
|
||||
|
||||
mod colors;
|
||||
mod experimental;
|
||||
mod gui;
|
||||
mod kml;
|
||||
mod plugins;
|
||||
mod render;
|
||||
mod ui;
|
||||
|
||||
use ezgui::input::UserInput;
|
||||
use glutin_window::GlutinWindow;
|
||||
use opengl_graphics::{Filter, GlGraphics, GlyphCache, OpenGL, TextureSettings};
|
||||
@ -34,13 +43,6 @@ use piston::input::RenderEvent;
|
||||
use piston::window::{Window, WindowSettings};
|
||||
use structopt::StructOpt;
|
||||
|
||||
mod colors;
|
||||
mod experimental;
|
||||
mod gui;
|
||||
mod plugins;
|
||||
mod render;
|
||||
mod ui;
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "editor")]
|
||||
struct Flags {
|
||||
@ -59,6 +61,10 @@ struct Flags {
|
||||
/// Use the old parametric sim
|
||||
#[structopt(long = "parametric_sim")]
|
||||
parametric_sim: bool,
|
||||
|
||||
/// Extra KML to display
|
||||
#[structopt(long = "kml")]
|
||||
kml: Option<String>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@ -103,6 +109,7 @@ fn main() {
|
||||
window_size,
|
||||
flags.rng_seed,
|
||||
flags.parametric_sim,
|
||||
flags.kml,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use ezgui::canvas::Canvas;
|
||||
use ezgui::input::UserInput;
|
||||
use ezgui::GfxCtx;
|
||||
use graphics::types::Color;
|
||||
use kml::ExtraShapeID;
|
||||
use map_model;
|
||||
use map_model::{BuildingID, IntersectionID, LaneID, Map, TurnID};
|
||||
use piston::input::{Button, Key, ReleaseEvent};
|
||||
@ -21,6 +22,7 @@ pub enum ID {
|
||||
Building(BuildingID),
|
||||
Car(CarID),
|
||||
Pedestrian(PedestrianID),
|
||||
ExtraShape(ExtraShapeID),
|
||||
//Parcel(ParcelID),
|
||||
}
|
||||
|
||||
@ -36,6 +38,7 @@ pub enum SelectionState {
|
||||
SelectedTurn(TurnID),
|
||||
SelectedCar(CarID),
|
||||
SelectedPedestrian(PedestrianID),
|
||||
SelectedExtraShape(ExtraShapeID),
|
||||
Tooltip(ID),
|
||||
}
|
||||
|
||||
@ -135,6 +138,14 @@ impl SelectionState {
|
||||
false
|
||||
}
|
||||
}
|
||||
SelectionState::SelectedExtraShape(id) => {
|
||||
if input.key_pressed(Key::LCtrl, &format!("Hold Ctrl to show {}'s tooltip", id)) {
|
||||
new_state = Some(SelectionState::Tooltip(ID::ExtraShape(*id)));
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
SelectionState::Empty => false,
|
||||
};
|
||||
if let Some(s) = new_state {
|
||||
@ -158,7 +169,8 @@ impl SelectionState {
|
||||
| SelectionState::SelectedTurn(_)
|
||||
| SelectionState::SelectedBuilding(_)
|
||||
| SelectionState::SelectedCar(_)
|
||||
| SelectionState::SelectedPedestrian(_) => {}
|
||||
| SelectionState::SelectedPedestrian(_)
|
||||
| SelectionState::SelectedExtraShape(_) => {}
|
||||
SelectionState::SelectedIntersection(id) => {
|
||||
if let Some(signal) = control_map.traffic_signals.get(&id) {
|
||||
let (cycle, _) = signal.current_cycle_and_remaining_time(sim.time.as_time());
|
||||
@ -199,6 +211,7 @@ impl SelectionState {
|
||||
ID::Pedestrian(id) => sim.ped_tooltip(id),
|
||||
ID::Intersection(id) => vec![format!("{}", id)],
|
||||
ID::Turn(id) => vec![format!("{}", id)],
|
||||
ID::ExtraShape(id) => draw_map.get_es(id).tooltip_lines(),
|
||||
};
|
||||
canvas.draw_mouse_tooltip(g, &lines);
|
||||
}
|
||||
@ -259,6 +272,16 @@ impl SelectionState {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn color_es(&self, es: ExtraShapeID, cs: &ColorScheme) -> Option<Color> {
|
||||
match *self {
|
||||
SelectionState::SelectedExtraShape(id) if es == id => Some(cs.get(Colors::Selected)),
|
||||
SelectionState::Tooltip(ID::ExtraShape(id)) if es == id => {
|
||||
Some(cs.get(Colors::Selected))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn selection_state_for(some_id: ID) -> SelectionState {
|
||||
@ -269,6 +292,7 @@ fn selection_state_for(some_id: ID) -> SelectionState {
|
||||
ID::Turn(id) => SelectionState::SelectedTurn(id),
|
||||
ID::Car(id) => SelectionState::SelectedCar(id),
|
||||
ID::Pedestrian(id) => SelectionState::SelectedPedestrian(id),
|
||||
ID::ExtraShape(id) => SelectionState::SelectedExtraShape(id),
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,6 +318,7 @@ impl Hider {
|
||||
SelectionState::SelectedIntersection(id) => Some(ID::Intersection(*id)),
|
||||
SelectionState::SelectedLane(id, _) => Some(ID::Lane(*id)),
|
||||
SelectionState::SelectedBuilding(id) => Some(ID::Building(*id)),
|
||||
SelectionState::SelectedExtraShape(id) => Some(ID::ExtraShape(*id)),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(id) = item {
|
||||
@ -318,4 +343,8 @@ impl Hider {
|
||||
pub fn show_i(&self, id: IntersectionID) -> bool {
|
||||
!self.items.contains(&ID::Intersection(id))
|
||||
}
|
||||
|
||||
pub fn show_es(&self, id: ExtraShapeID) -> bool {
|
||||
!self.items.contains(&ID::ExtraShape(id))
|
||||
}
|
||||
}
|
||||
|
44
editor/src/render/extra_shape.rs
Normal file
44
editor/src/render/extra_shape.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use aabb_quadtree::geom::Rect;
|
||||
use ezgui::GfxCtx;
|
||||
use geom::{Polygon, Pt2D};
|
||||
use graphics::types::Color;
|
||||
use kml::{ExtraShape, ExtraShapeID};
|
||||
use render::{get_bbox, EXTRA_SHAPE_THICKNESS};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DrawExtraShape {
|
||||
pub id: ExtraShapeID,
|
||||
polygon: Polygon,
|
||||
attributes: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl DrawExtraShape {
|
||||
pub fn new(s: ExtraShape) -> DrawExtraShape {
|
||||
DrawExtraShape {
|
||||
id: s.id,
|
||||
polygon: s.pts.make_polygons(EXTRA_SHAPE_THICKNESS).unwrap(),
|
||||
attributes: s.attributes,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&self, g: &mut GfxCtx, color: Color) {
|
||||
g.draw_polygon(color, &self.polygon);
|
||||
}
|
||||
|
||||
pub fn contains_pt(&self, pt: Pt2D) -> bool {
|
||||
self.polygon.contains_pt(pt)
|
||||
}
|
||||
|
||||
pub fn get_bbox(&self) -> Rect {
|
||||
get_bbox(&self.polygon.get_bounds())
|
||||
}
|
||||
|
||||
pub fn tooltip_lines(&self) -> Vec<String> {
|
||||
let mut lines = Vec::new();
|
||||
for (k, v) in &self.attributes {
|
||||
lines.push(format!("{} = {}", k, v));
|
||||
}
|
||||
lines
|
||||
}
|
||||
}
|
@ -3,9 +3,11 @@
|
||||
use aabb_quadtree::geom::{Point, Rect};
|
||||
use aabb_quadtree::QuadTree;
|
||||
use geom::{LonLat, Pt2D};
|
||||
use kml::{ExtraShape, ExtraShapeID};
|
||||
use map_model::{BuildingID, IntersectionID, Lane, LaneID, Map, ParcelID, Turn, TurnID};
|
||||
use plugins::selection::Hider;
|
||||
use render::building::DrawBuilding;
|
||||
use render::extra_shape::DrawExtraShape;
|
||||
use render::intersection::DrawIntersection;
|
||||
use render::lane::DrawLane;
|
||||
use render::parcel::DrawParcel;
|
||||
@ -18,16 +20,18 @@ pub struct DrawMap {
|
||||
pub turns: HashMap<TurnID, DrawTurn>,
|
||||
pub buildings: Vec<DrawBuilding>,
|
||||
pub parcels: Vec<DrawParcel>,
|
||||
pub extra_shapes: Vec<DrawExtraShape>,
|
||||
|
||||
lanes_quadtree: QuadTree<LaneID>,
|
||||
intersections_quadtree: QuadTree<IntersectionID>,
|
||||
buildings_quadtree: QuadTree<BuildingID>,
|
||||
parcels_quadtree: QuadTree<ParcelID>,
|
||||
extra_shapes_quadtree: QuadTree<ExtraShapeID>,
|
||||
}
|
||||
|
||||
impl DrawMap {
|
||||
// Also returns the center of the map in map-space
|
||||
pub fn new(map: &Map) -> (DrawMap, Pt2D) {
|
||||
pub fn new(map: &Map, raw_extra_shapes: Vec<ExtraShape>) -> (DrawMap, Pt2D) {
|
||||
let mut lanes: Vec<DrawLane> = Vec::new();
|
||||
for l in map.all_lanes() {
|
||||
lanes.push(DrawLane::new(l, map));
|
||||
@ -56,6 +60,11 @@ impl DrawMap {
|
||||
.map(|p| DrawParcel::new(p))
|
||||
.collect();
|
||||
|
||||
let extra_shapes: Vec<DrawExtraShape> = raw_extra_shapes
|
||||
.into_iter()
|
||||
.map(|s| DrawExtraShape::new(s))
|
||||
.collect();
|
||||
|
||||
// min_y here due to the wacky y inversion
|
||||
let bounds = map.get_gps_bounds();
|
||||
let max_screen_pt = Pt2D::from_gps(&LonLat::new(bounds.max_x, bounds.min_y), &bounds);
|
||||
@ -84,6 +93,11 @@ impl DrawMap {
|
||||
parcels_quadtree.insert_with_box(p.id, p.get_bbox());
|
||||
}
|
||||
|
||||
let mut extra_shapes_quadtree = QuadTree::default(map_bbox);
|
||||
for s in &extra_shapes {
|
||||
extra_shapes_quadtree.insert_with_box(s.id, s.get_bbox());
|
||||
}
|
||||
|
||||
(
|
||||
DrawMap {
|
||||
lanes,
|
||||
@ -91,11 +105,13 @@ impl DrawMap {
|
||||
turns,
|
||||
buildings,
|
||||
parcels,
|
||||
extra_shapes,
|
||||
|
||||
lanes_quadtree,
|
||||
intersections_quadtree,
|
||||
buildings_quadtree,
|
||||
parcels_quadtree,
|
||||
extra_shapes_quadtree,
|
||||
},
|
||||
Pt2D::new(max_screen_pt.x() / 2.0, max_screen_pt.y() / 2.0),
|
||||
)
|
||||
@ -159,6 +175,10 @@ impl DrawMap {
|
||||
&self.parcels[id.0]
|
||||
}
|
||||
|
||||
pub fn get_es(&self, id: ExtraShapeID) -> &DrawExtraShape {
|
||||
&self.extra_shapes[id.0]
|
||||
}
|
||||
|
||||
pub fn get_loads_onscreen(&self, screen_bbox: Rect, hider: &Hider) -> Vec<&DrawLane> {
|
||||
let mut v = Vec::new();
|
||||
for &(id, _, _) in &self.lanes_quadtree.query(screen_bbox) {
|
||||
@ -200,4 +220,18 @@ impl DrawMap {
|
||||
}
|
||||
v
|
||||
}
|
||||
|
||||
pub fn get_extra_shapes_onscreen(
|
||||
&self,
|
||||
screen_bbox: Rect,
|
||||
hider: &Hider,
|
||||
) -> Vec<&DrawExtraShape> {
|
||||
let mut v = Vec::new();
|
||||
for &(id, _, _) in &self.extra_shapes_quadtree.query(screen_bbox) {
|
||||
if hider.show_es(*id) {
|
||||
v.push(self.get_es(*id));
|
||||
}
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
mod building;
|
||||
mod extra_shape;
|
||||
mod intersection;
|
||||
mod lane;
|
||||
mod map;
|
||||
@ -17,6 +18,7 @@ use std::f64;
|
||||
|
||||
// These are all in meters
|
||||
const PARCEL_BOUNDARY_THICKNESS: f64 = 0.5;
|
||||
const EXTRA_SHAPE_THICKNESS: f64 = 1.0;
|
||||
|
||||
const TURN_ICON_ARROW_THICKNESS: f64 = geometry::BIG_ARROW_THICKNESS / 3.0;
|
||||
const BIG_ARROW_TIP_LENGTH: f64 = 1.0;
|
||||
|
@ -13,6 +13,7 @@ use ezgui::{GfxCtx, ToggleableLayer};
|
||||
use geom::Pt2D;
|
||||
use graphics::types::Color;
|
||||
use gui;
|
||||
use kml;
|
||||
use map_model;
|
||||
use map_model::{Edits, IntersectionID};
|
||||
use piston::input::{Key, MouseCursorEvent};
|
||||
@ -50,6 +51,7 @@ pub struct UI {
|
||||
show_buildings: ToggleableLayer,
|
||||
show_intersections: ToggleableLayer,
|
||||
show_parcels: ToggleableLayer,
|
||||
show_extra_shapes: ToggleableLayer,
|
||||
debug_mode: ToggleableLayer,
|
||||
|
||||
// This is a particularly special plugin, since it's always kind of active and other things
|
||||
@ -81,12 +83,20 @@ impl UI {
|
||||
window_size: Size,
|
||||
rng_seed: Option<u8>,
|
||||
parametric_sim: bool,
|
||||
kml: Option<String>,
|
||||
) -> UI {
|
||||
let edits: Edits = abstutil::read_json("road_edits.json").unwrap_or(Edits::new());
|
||||
|
||||
println!("Opening {}", abst_path);
|
||||
let map = map_model::Map::new(abst_path, &edits).expect("Couldn't load map");
|
||||
let (draw_map, center_pt) = render::DrawMap::new(&map);
|
||||
|
||||
let extra_shapes = if let Some(path) = kml {
|
||||
kml::load(&path, &map.get_gps_bounds()).expect("Couldn't load extra KML shapes")
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let (draw_map, center_pt) = render::DrawMap::new(&map, extra_shapes);
|
||||
let control_map = ControlMap::new(&map);
|
||||
|
||||
let steepness_viz = SteepnessVisualizer::new(&map);
|
||||
@ -110,6 +120,12 @@ impl UI {
|
||||
Some(MIN_ZOOM_FOR_LANES),
|
||||
),
|
||||
show_parcels: ToggleableLayer::new("parcels", Key::D4, "4", Some(MIN_ZOOM_FOR_PARCELS)),
|
||||
show_extra_shapes: ToggleableLayer::new(
|
||||
"extra KML shapes",
|
||||
Key::D7,
|
||||
"7",
|
||||
Some(MIN_ZOOM_FOR_LANES),
|
||||
),
|
||||
debug_mode: ToggleableLayer::new("debug mode", Key::G, "G", None),
|
||||
|
||||
current_selection_state: SelectionState::Empty,
|
||||
@ -155,6 +171,7 @@ impl UI {
|
||||
self.show_buildings.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_extra_shapes.handle_zoom(old_zoom, new_zoom);
|
||||
self.debug_mode.handle_zoom(old_zoom, new_zoom);
|
||||
}
|
||||
|
||||
@ -211,6 +228,16 @@ impl UI {
|
||||
}
|
||||
}
|
||||
|
||||
if self.show_extra_shapes.is_enabled() {
|
||||
for s in &self.draw_map
|
||||
.get_extra_shapes_onscreen(screen_bbox, &self.hider)
|
||||
{
|
||||
if s.contains_pt(pt) {
|
||||
return Some(ID::ExtraShape(s.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.show_lanes.is_enabled() {
|
||||
for l in &lanes_onscreen {
|
||||
if l.contains_pt(pt) {
|
||||
@ -447,6 +474,15 @@ impl gui::GUI for UI {
|
||||
}
|
||||
return gui::EventLoopMode::InputOnly;
|
||||
}
|
||||
if self.show_extra_shapes.handle_event(input) {
|
||||
if let SelectionState::SelectedExtraShape(_) = self.current_selection_state {
|
||||
self.current_selection_state = SelectionState::Empty;
|
||||
}
|
||||
if let SelectionState::Tooltip(ID::ExtraShape(_)) = self.current_selection_state {
|
||||
self.current_selection_state = SelectionState::Empty;
|
||||
}
|
||||
return gui::EventLoopMode::InputOnly;
|
||||
}
|
||||
|
||||
stop_if_done!(self.show_parcels.handle_event(input));
|
||||
stop_if_done!(self.debug_mode.handle_event(input));
|
||||
@ -611,6 +647,20 @@ impl gui::GUI for UI {
|
||||
}
|
||||
}
|
||||
|
||||
if self.show_extra_shapes.is_enabled() {
|
||||
for s in &self.draw_map
|
||||
.get_extra_shapes_onscreen(screen_bbox, &self.hider)
|
||||
{
|
||||
// TODO no separate color method?
|
||||
s.draw(
|
||||
g,
|
||||
self.current_selection_state
|
||||
.color_es(s.id, &self.cs)
|
||||
.unwrap_or(self.cs.get(Colors::ExtraShape)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.current_selection_state.draw(
|
||||
&self.map,
|
||||
&self.canvas,
|
||||
|
Loading…
Reference in New Issue
Block a user