mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 01:15:12 +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 crate::{App, ModalFilters, Transition};
|
||||
use crate::{App, ModalFilters, Toggle3Zoomed, Transition};
|
||||
|
||||
pub struct BrowseNeighborhoods {
|
||||
panel: Panel,
|
||||
world: World<NeighborhoodID>,
|
||||
labels: DrawRoadLabels,
|
||||
draw_all_filters: ToggleZoomed,
|
||||
draw_all_filters: Toggle3Zoomed,
|
||||
draw_boundary_roads: ToggleZoomed,
|
||||
}
|
||||
|
||||
@ -173,10 +173,10 @@ impl State<App> for BrowseNeighborhoods {
|
||||
crate::draw_with_layering(g, app, |g| self.world.draw(g));
|
||||
|
||||
self.panel.draw(g);
|
||||
self.draw_all_filters.draw(g);
|
||||
if self.panel.is_checked("highlight boundary roads") {
|
||||
self.draw_boundary_roads.draw(g);
|
||||
}
|
||||
self.draw_all_filters.draw(g);
|
||||
if g.canvas.is_unzoomed() {
|
||||
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);
|
||||
batch
|
||||
.unzoomed
|
||||
.push(Color::RED.alpha(0.8), road.get_thick_polygon());
|
||||
.push(Color::RED.alpha(0.6), road.get_thick_polygon());
|
||||
batch
|
||||
.zoomed
|
||||
.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);
|
||||
batch
|
||||
.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
|
||||
.zoomed
|
||||
.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 map_model::{IntersectionID, Map, RoadID, RoutingParams, TurnID};
|
||||
use widgetry::mapspace::ToggleZoomed;
|
||||
use widgetry::{Color, EventCtx, GeomBatch};
|
||||
use widgetry::mapspace::{DrawUnzoomedShapes, ToggleZoomed};
|
||||
use widgetry::{Color, EventCtx, GeomBatch, GfxCtx};
|
||||
|
||||
use super::Neighborhood;
|
||||
use crate::App;
|
||||
@ -88,8 +88,10 @@ impl ModalFilters {
|
||||
ctx: &EventCtx,
|
||||
map: &Map,
|
||||
only_neighborhood: Option<&Neighborhood>,
|
||||
) -> ToggleZoomed {
|
||||
) -> Toggle3Zoomed {
|
||||
let mut batch = ToggleZoomed::builder();
|
||||
let mut low_zoom = DrawUnzoomedShapes::builder();
|
||||
|
||||
for (r, dist) in &self.roads {
|
||||
if only_neighborhood
|
||||
.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) {
|
||||
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
|
||||
.unzoomed
|
||||
.push(Color::RED, Circle::new(pt, road_width).to_polygon());
|
||||
@ -134,6 +141,13 @@ impl ModalFilters {
|
||||
}
|
||||
|
||||
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
|
||||
.unzoomed
|
||||
.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),
|
||||
);
|
||||
}
|
||||
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()),
|
||||
);
|
||||
}
|
||||
|
||||
/// 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::tools::{checkbox_per_mode, PopupMsg};
|
||||
use synthpop::{Scenario, TripMode};
|
||||
use widgetry::mapspace::ToggleZoomed;
|
||||
use widgetry::{
|
||||
Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Line, Panel, SimpleState, Slider,
|
||||
State, Text, TextExt, Toggle, VerticalAlignment, Widget,
|
||||
};
|
||||
|
||||
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
|
||||
// ... can't we just produce data of a certain shape, and have a UI pretty tuned for that?
|
||||
|
||||
pub struct ShowResults {
|
||||
draw_all_neighborhoods: Drawable,
|
||||
draw_all_filters: ToggleZoomed,
|
||||
draw_all_filters: Toggle3Zoomed,
|
||||
}
|
||||
|
||||
impl ShowResults {
|
||||
|
@ -5,7 +5,7 @@ use structopt::StructOpt;
|
||||
use widgetry::{GfxCtx, Settings};
|
||||
|
||||
pub use browse::BrowseNeighborhoods;
|
||||
pub use filters::{DiagonalFilter, ModalFilters};
|
||||
pub use filters::{DiagonalFilter, ModalFilters, Toggle3Zoomed};
|
||||
pub use neighborhood::{Cell, DistanceInterval, Neighborhood};
|
||||
pub use partition::{NeighborhoodID, Partitioning};
|
||||
|
||||
@ -63,7 +63,7 @@ fn run(mut settings: Settings) {
|
||||
|
||||
impact: impact::Impact::empty(ctx),
|
||||
|
||||
highlight_boundary_roads: true,
|
||||
highlight_boundary_roads: false,
|
||||
draw_neighborhood_style: browse::Style::SimpleColoring,
|
||||
draw_cells_as_areas: true,
|
||||
draw_borders_as_arrows: true,
|
||||
|
@ -5,10 +5,9 @@ use maplit::btreeset;
|
||||
use geom::{Distance, Polygon};
|
||||
use map_gui::tools::DrawRoadLabels;
|
||||
use map_model::{IntersectionID, Map, PathConstraints, Perimeter, RoadID};
|
||||
use widgetry::mapspace::ToggleZoomed;
|
||||
use widgetry::{Drawable, EventCtx, GeomBatch};
|
||||
|
||||
use crate::{App, ModalFilters, NeighborhoodID};
|
||||
use crate::{App, ModalFilters, NeighborhoodID, Toggle3Zoomed};
|
||||
|
||||
pub struct Neighborhood {
|
||||
pub id: NeighborhoodID,
|
||||
@ -24,7 +23,7 @@ pub struct Neighborhood {
|
||||
pub cells: Vec<Cell>,
|
||||
|
||||
pub fade_irrelevant: Drawable,
|
||||
pub draw_filters: ToggleZoomed,
|
||||
pub draw_filters: Toggle3Zoomed,
|
||||
pub labels: DrawRoadLabels,
|
||||
}
|
||||
|
||||
@ -74,7 +73,7 @@ impl Neighborhood {
|
||||
cells: Vec::new(),
|
||||
|
||||
fade_irrelevant: Drawable::empty(ctx),
|
||||
draw_filters: ToggleZoomed::empty(ctx),
|
||||
draw_filters: Toggle3Zoomed::empty(ctx),
|
||||
// Temporary value
|
||||
labels: DrawRoadLabels::only_major_roads(),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user