mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-27 15:03:20 +03:00
At really low zoom levels, draw modal filters using the scale-invariant
circles. Otherwise they're just impossible to see. Since they're the most important thing to show in the LTN tool, seems worth it. This helps proceed on #851
This commit is contained in:
parent
067fdb8649
commit
635f508540
@ -11,13 +11,13 @@ use widgetry::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{Neighborhood, NeighborhoodID, Partitioning};
|
use super::{Neighborhood, NeighborhoodID, Partitioning};
|
||||||
use crate::{App, ModalFilters, Transition};
|
use crate::{App, ModalFilters, Toggle3Zoomed, Transition};
|
||||||
|
|
||||||
pub struct BrowseNeighborhoods {
|
pub struct BrowseNeighborhoods {
|
||||||
panel: Panel,
|
panel: Panel,
|
||||||
world: World<NeighborhoodID>,
|
world: World<NeighborhoodID>,
|
||||||
labels: DrawRoadLabels,
|
labels: DrawRoadLabels,
|
||||||
draw_all_filters: ToggleZoomed,
|
draw_all_filters: Toggle3Zoomed,
|
||||||
draw_boundary_roads: ToggleZoomed,
|
draw_boundary_roads: ToggleZoomed,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,10 +173,10 @@ impl State<App> for BrowseNeighborhoods {
|
|||||||
crate::draw_with_layering(g, app, |g| self.world.draw(g));
|
crate::draw_with_layering(g, app, |g| self.world.draw(g));
|
||||||
|
|
||||||
self.panel.draw(g);
|
self.panel.draw(g);
|
||||||
self.draw_all_filters.draw(g);
|
|
||||||
if self.panel.is_checked("highlight boundary roads") {
|
if self.panel.is_checked("highlight boundary roads") {
|
||||||
self.draw_boundary_roads.draw(g);
|
self.draw_boundary_roads.draw(g);
|
||||||
}
|
}
|
||||||
|
self.draw_all_filters.draw(g);
|
||||||
if g.canvas.is_unzoomed() {
|
if g.canvas.is_unzoomed() {
|
||||||
self.labels.draw(g, app);
|
self.labels.draw(g, app);
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ fn draw_boundary_roads(ctx: &EventCtx, app: &App) -> ToggleZoomed {
|
|||||||
let road = app.map.get_r(r);
|
let road = app.map.get_r(r);
|
||||||
batch
|
batch
|
||||||
.unzoomed
|
.unzoomed
|
||||||
.push(Color::RED.alpha(0.8), road.get_thick_polygon());
|
.push(Color::RED.alpha(0.6), road.get_thick_polygon());
|
||||||
batch
|
batch
|
||||||
.zoomed
|
.zoomed
|
||||||
.push(Color::RED.alpha(0.5), road.get_thick_polygon());
|
.push(Color::RED.alpha(0.5), road.get_thick_polygon());
|
||||||
@ -261,7 +261,7 @@ fn draw_boundary_roads(ctx: &EventCtx, app: &App) -> ToggleZoomed {
|
|||||||
seen_borders.insert(i);
|
seen_borders.insert(i);
|
||||||
batch
|
batch
|
||||||
.unzoomed
|
.unzoomed
|
||||||
.push(Color::RED.alpha(0.8), app.map.get_i(i).polygon.clone());
|
.push(Color::RED.alpha(0.6), app.map.get_i(i).polygon.clone());
|
||||||
batch
|
batch
|
||||||
.zoomed
|
.zoomed
|
||||||
.push(Color::RED.alpha(0.5), app.map.get_i(i).polygon.clone());
|
.push(Color::RED.alpha(0.5), app.map.get_i(i).polygon.clone());
|
||||||
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use geom::{Circle, Distance, Line};
|
use geom::{Circle, Distance, Line};
|
||||||
use map_model::{IntersectionID, Map, RoadID, RoutingParams, TurnID};
|
use map_model::{IntersectionID, Map, RoadID, RoutingParams, TurnID};
|
||||||
use widgetry::mapspace::ToggleZoomed;
|
use widgetry::mapspace::{DrawUnzoomedShapes, ToggleZoomed};
|
||||||
use widgetry::{Color, EventCtx, GeomBatch};
|
use widgetry::{Color, EventCtx, GeomBatch, GfxCtx};
|
||||||
|
|
||||||
use super::Neighborhood;
|
use super::Neighborhood;
|
||||||
use crate::App;
|
use crate::App;
|
||||||
@ -88,8 +88,10 @@ impl ModalFilters {
|
|||||||
ctx: &EventCtx,
|
ctx: &EventCtx,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
only_neighborhood: Option<&Neighborhood>,
|
only_neighborhood: Option<&Neighborhood>,
|
||||||
) -> ToggleZoomed {
|
) -> Toggle3Zoomed {
|
||||||
let mut batch = ToggleZoomed::builder();
|
let mut batch = ToggleZoomed::builder();
|
||||||
|
let mut low_zoom = DrawUnzoomedShapes::builder();
|
||||||
|
|
||||||
for (r, dist) in &self.roads {
|
for (r, dist) in &self.roads {
|
||||||
if only_neighborhood
|
if only_neighborhood
|
||||||
.map(|n| !n.orig_perimeter.interior.contains(r))
|
.map(|n| !n.orig_perimeter.interior.contains(r))
|
||||||
@ -102,6 +104,11 @@ impl ModalFilters {
|
|||||||
if let Ok((pt, angle)) = road.center_pts.dist_along(*dist) {
|
if let Ok((pt, angle)) = road.center_pts.dist_along(*dist) {
|
||||||
let road_width = road.get_width();
|
let road_width = road.get_width();
|
||||||
|
|
||||||
|
// TODO DrawUnzoomedShapes can do lines, but they don't stretch as the radius does,
|
||||||
|
// so it looks weird
|
||||||
|
low_zoom.add_circle(pt, Distance::meters(8.0), Color::RED);
|
||||||
|
low_zoom.add_circle(pt, Distance::meters(6.0), Color::WHITE);
|
||||||
|
|
||||||
batch
|
batch
|
||||||
.unzoomed
|
.unzoomed
|
||||||
.push(Color::RED, Circle::new(pt, road_width).to_polygon());
|
.push(Color::RED, Circle::new(pt, road_width).to_polygon());
|
||||||
@ -134,6 +141,13 @@ impl ModalFilters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let line = filter.geometry(map);
|
let line = filter.geometry(map);
|
||||||
|
|
||||||
|
// It's really hard to see a tiny squished line thickened, so use the same circle
|
||||||
|
// symbology at really low zooms
|
||||||
|
let pt = line.middle().unwrap();
|
||||||
|
low_zoom.add_circle(pt, Distance::meters(8.0), Color::RED);
|
||||||
|
low_zoom.add_circle(pt, Distance::meters(6.0), Color::WHITE);
|
||||||
|
|
||||||
batch
|
batch
|
||||||
.unzoomed
|
.unzoomed
|
||||||
.push(Color::RED, line.make_polygons(Distance::meters(3.0)));
|
.push(Color::RED, line.make_polygons(Distance::meters(3.0)));
|
||||||
@ -144,7 +158,7 @@ impl ModalFilters {
|
|||||||
line.percent_slice(0.3, 0.7).unwrap_or(line),
|
line.percent_slice(0.3, 0.7).unwrap_or(line),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
batch.build(ctx)
|
Toggle3Zoomed::new(batch.build(ctx), low_zoom.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,3 +264,27 @@ fn draw_zoomed_planters(ctx: &EventCtx, batch: &mut GeomBatch, line: Line) {
|
|||||||
.rotate(line.angle()),
|
.rotate(line.angle()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Depending on the canvas zoom level, draws one of 3 things.
|
||||||
|
pub struct Toggle3Zoomed {
|
||||||
|
draw: ToggleZoomed,
|
||||||
|
unzoomed: DrawUnzoomedShapes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Toggle3Zoomed {
|
||||||
|
fn new(draw: ToggleZoomed, unzoomed: DrawUnzoomedShapes) -> Self {
|
||||||
|
Self { draw, unzoomed }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn empty(ctx: &EventCtx) -> Self {
|
||||||
|
Self::new(ToggleZoomed::empty(ctx), DrawUnzoomedShapes::empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&self, g: &mut GfxCtx) {
|
||||||
|
if g.canvas.cam_zoom < 1.0 {
|
||||||
|
self.unzoomed.draw(g);
|
||||||
|
} else {
|
||||||
|
self.draw.draw(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,21 +3,20 @@ use std::collections::BTreeSet;
|
|||||||
use map_gui::load::FileLoader;
|
use map_gui::load::FileLoader;
|
||||||
use map_gui::tools::{checkbox_per_mode, PopupMsg};
|
use map_gui::tools::{checkbox_per_mode, PopupMsg};
|
||||||
use synthpop::{Scenario, TripMode};
|
use synthpop::{Scenario, TripMode};
|
||||||
use widgetry::mapspace::ToggleZoomed;
|
|
||||||
use widgetry::{
|
use widgetry::{
|
||||||
Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Line, Panel, SimpleState, Slider,
|
Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Line, Panel, SimpleState, Slider,
|
||||||
State, Text, TextExt, Toggle, VerticalAlignment, Widget,
|
State, Text, TextExt, Toggle, VerticalAlignment, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{end_of_day, Filters, Impact};
|
use super::{end_of_day, Filters, Impact};
|
||||||
use crate::{App, BrowseNeighborhoods, Transition};
|
use crate::{App, BrowseNeighborhoods, Toggle3Zoomed, Transition};
|
||||||
|
|
||||||
// TODO Share structure or pieces with Ungap's predict mode
|
// TODO Share structure or pieces with Ungap's predict mode
|
||||||
// ... can't we just produce data of a certain shape, and have a UI pretty tuned for that?
|
// ... can't we just produce data of a certain shape, and have a UI pretty tuned for that?
|
||||||
|
|
||||||
pub struct ShowResults {
|
pub struct ShowResults {
|
||||||
draw_all_neighborhoods: Drawable,
|
draw_all_neighborhoods: Drawable,
|
||||||
draw_all_filters: ToggleZoomed,
|
draw_all_filters: Toggle3Zoomed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShowResults {
|
impl ShowResults {
|
||||||
|
@ -5,7 +5,7 @@ use structopt::StructOpt;
|
|||||||
use widgetry::{GfxCtx, Settings};
|
use widgetry::{GfxCtx, Settings};
|
||||||
|
|
||||||
pub use browse::BrowseNeighborhoods;
|
pub use browse::BrowseNeighborhoods;
|
||||||
pub use filters::{DiagonalFilter, ModalFilters};
|
pub use filters::{DiagonalFilter, ModalFilters, Toggle3Zoomed};
|
||||||
pub use neighborhood::{Cell, DistanceInterval, Neighborhood};
|
pub use neighborhood::{Cell, DistanceInterval, Neighborhood};
|
||||||
pub use partition::{NeighborhoodID, Partitioning};
|
pub use partition::{NeighborhoodID, Partitioning};
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ fn run(mut settings: Settings) {
|
|||||||
|
|
||||||
impact: impact::Impact::empty(ctx),
|
impact: impact::Impact::empty(ctx),
|
||||||
|
|
||||||
highlight_boundary_roads: true,
|
highlight_boundary_roads: false,
|
||||||
draw_neighborhood_style: browse::Style::SimpleColoring,
|
draw_neighborhood_style: browse::Style::SimpleColoring,
|
||||||
draw_cells_as_areas: true,
|
draw_cells_as_areas: true,
|
||||||
draw_borders_as_arrows: true,
|
draw_borders_as_arrows: true,
|
||||||
|
@ -5,10 +5,9 @@ use maplit::btreeset;
|
|||||||
use geom::{Distance, Polygon};
|
use geom::{Distance, Polygon};
|
||||||
use map_gui::tools::DrawRoadLabels;
|
use map_gui::tools::DrawRoadLabels;
|
||||||
use map_model::{IntersectionID, Map, PathConstraints, Perimeter, RoadID};
|
use map_model::{IntersectionID, Map, PathConstraints, Perimeter, RoadID};
|
||||||
use widgetry::mapspace::ToggleZoomed;
|
|
||||||
use widgetry::{Drawable, EventCtx, GeomBatch};
|
use widgetry::{Drawable, EventCtx, GeomBatch};
|
||||||
|
|
||||||
use crate::{App, ModalFilters, NeighborhoodID};
|
use crate::{App, ModalFilters, NeighborhoodID, Toggle3Zoomed};
|
||||||
|
|
||||||
pub struct Neighborhood {
|
pub struct Neighborhood {
|
||||||
pub id: NeighborhoodID,
|
pub id: NeighborhoodID,
|
||||||
@ -24,7 +23,7 @@ pub struct Neighborhood {
|
|||||||
pub cells: Vec<Cell>,
|
pub cells: Vec<Cell>,
|
||||||
|
|
||||||
pub fade_irrelevant: Drawable,
|
pub fade_irrelevant: Drawable,
|
||||||
pub draw_filters: ToggleZoomed,
|
pub draw_filters: Toggle3Zoomed,
|
||||||
pub labels: DrawRoadLabels,
|
pub labels: DrawRoadLabels,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ impl Neighborhood {
|
|||||||
cells: Vec::new(),
|
cells: Vec::new(),
|
||||||
|
|
||||||
fade_irrelevant: Drawable::empty(ctx),
|
fade_irrelevant: Drawable::empty(ctx),
|
||||||
draw_filters: ToggleZoomed::empty(ctx),
|
draw_filters: Toggle3Zoomed::empty(ctx),
|
||||||
// Temporary value
|
// Temporary value
|
||||||
labels: DrawRoadLabels::only_major_roads(),
|
labels: DrawRoadLabels::only_major_roads(),
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user