The last of ToggleZoomed conversion!

This commit is contained in:
Dustin Carlino 2021-09-27 14:21:59 -07:00
parent 59a6b4e546
commit 40b018e1bc
12 changed files with 92 additions and 98 deletions

View File

@ -11,12 +11,12 @@ use geom::{Bounds, Circle, Distance, Duration, FindClosest, Polygon, Pt2D, Time}
use map_gui::colors::ColorScheme;
use map_gui::options::Options;
use map_gui::render::{unzoomed_agent_radius, AgentCache, DrawMap, DrawOptions, Renderable};
use map_gui::tools::CameraState;
use map_gui::tools::{CameraState, ToggleZoomed};
use map_gui::ID;
use map_model::AreaType;
use map_model::{BufferType, IntersectionID, LaneType, Map, RoutingParams, Traversable};
use sim::{AgentID, Analytics, Scenario, Sim, SimCallback, SimFlags, VehicleType};
use widgetry::{Cached, Canvas, Drawable, EventCtx, GfxCtx, Prerender, SharedAppState, State};
use widgetry::{Cached, Canvas, EventCtx, GfxCtx, Prerender, SharedAppState, State};
use crate::challenges::HighScore;
use crate::common::Warping;
@ -731,7 +731,7 @@ pub struct SessionState {
pub buffer_lane_type: LaneType,
// Specific to the ungap tool
pub elevation_contours: Cached<MapName, (FindClosest<Distance>, Drawable)>,
pub elevation_contours: Cached<MapName, (FindClosest<Distance>, ToggleZoomed)>,
pub routing_params: RoutingParams,
// Map and edit change key
pub mode_shift: Cached<(MapName, usize), crate::ungap::ModeShiftData>,

View File

@ -92,9 +92,10 @@ fn info_body(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BuildingI
)));
details
.draw_extra
.unzoomed
.push(color, pl.make_polygons(Distance::meters(10.0)));
details.zoomed.extend(
details.draw_extra.zoomed.extend(
color,
pl.dashed_lines(
Distance::meters(0.75),
@ -289,14 +290,14 @@ pub fn draw_occupants(details: &mut Details, app: &App, id: BuildingID, focus: O
);
if Some(person) == focus {
details.zoomed.push(
details.draw_extra.zoomed.push(
Color::YELLOW.alpha(0.8),
Circle::new(pos, SIDEWALK_THICKNESS).to_polygon(),
);
}
DrawPedestrian::geometry(
&mut details.zoomed,
&mut details.draw_extra.zoomed,
&app.primary.sim,
&app.cs,
&DrawPedestrianInput {

View File

@ -95,7 +95,7 @@ fn stop_body(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusStopID
rows.push(txt.into_widget(ctx));
// Draw where the bus/train stops
details.zoomed.push(
details.draw_extra.zoomed.push(
app.cs.bus_body.alpha(0.5),
Circle::new(bs.driving_pos.pt(&app.primary.map), Distance::meters(2.5)).to_polygon(),
);
@ -337,15 +337,15 @@ fn route_body(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusRoute
}
}
}
details.unzoomed.append(colorer.unzoomed);
details.zoomed.append(colorer.zoomed);
details.draw_extra.unzoomed.append(colorer.unzoomed);
details.draw_extra.zoomed.append(colorer.zoomed);
for pt in bus_locations {
details.unzoomed.push(
details.draw_extra.unzoomed.push(
Color::BLUE,
Circle::new(pt, Distance::meters(20.0)).to_polygon(),
);
details.zoomed.push(
details.draw_extra.zoomed.push(
Color::BLUE.alpha(0.5),
Circle::new(pt, Distance::meters(5.0)).to_polygon(),
);
@ -353,13 +353,13 @@ fn route_body(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusRoute
for (idx, bs) in route.stops.iter().enumerate() {
let bs = map.get_bs(*bs);
details.unzoomed.append(
details.draw_extra.unzoomed.append(
Text::from(format!("{}) {}", idx + 1, bs.name))
.with_bg()
.render_autocropped(ctx)
.centered_on(bs.sidewalk_pos.pt(map)),
);
details.zoomed.append(
details.draw_extra.zoomed.append(
Text::from(format!("{}) {}", idx + 1, bs.name))
.with_bg()
.render_autocropped(ctx)

View File

@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
pub use trip::OpenTrip;
use geom::{Circle, Distance, Polygon, Time};
use map_gui::tools::open_browser;
use map_gui::tools::{open_browser, ToggleZoomed, ToggleZoomedBuilder};
use map_gui::ID;
use map_model::{AreaID, BuildingID, BusRouteID, BusStopID, IntersectionID, LaneID, ParkingLotID};
use sim::{
@ -11,8 +11,8 @@ use sim::{
VehicleType,
};
use widgetry::{
Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, LinePlot, Outcome, Panel, PlotOptions,
Series, Text, TextExt, Toggle, Widget,
EventCtx, GfxCtx, Key, Line, LinePlot, Outcome, Panel, PlotOptions, Series, Text, TextExt,
Toggle, Widget,
};
use crate::app::{App, Transition};
@ -37,8 +37,7 @@ pub struct InfoPanel {
is_paused: bool,
panel: Panel,
unzoomed: Drawable,
zoomed: Drawable,
draw_extra: ToggleZoomed,
tooltips: Vec<(Polygon, Text)>,
hyperlinks: HashMap<String, Tab>,
@ -286,10 +285,8 @@ impl Tab {
// TODO Name sucks
pub struct Details {
/// Draw extra things when unzoomed.
pub unzoomed: GeomBatch,
/// Draw extra things when zoomed.
pub zoomed: GeomBatch,
/// Draw extra things when unzoomed or zoomed.
pub draw_extra: ToggleZoomedBuilder,
/// Show these tooltips over the map.
pub tooltips: Vec<(Polygon, Text)>,
/// When a button with this label is clicked, open this info panel tab instead.
@ -313,8 +310,7 @@ impl InfoPanel {
app.session.info_panel_tab.insert(k, v);
let mut details = Details {
unzoomed: GeomBatch::new(),
zoomed: GeomBatch::new(),
draw_extra: ToggleZoomed::builder(),
tooltips: Vec::new(),
hyperlinks: HashMap::new(),
warpers: HashMap::new(),
@ -419,14 +415,17 @@ impl InfoPanel {
// Make a circle to cover the object.
let bounds = outline.get_bounds();
let radius = multiplier * Distance::meters(bounds.width().max(bounds.height()));
details.unzoomed.push(
details.draw_extra.unzoomed.push(
app.cs.current_object.alpha(0.5),
Circle::new(bounds.center(), radius).to_polygon(),
);
match Circle::new(bounds.center(), radius).to_outline(Distance::meters(0.3)) {
Ok(poly) => {
details.unzoomed.push(app.cs.current_object, poly.clone());
details.zoomed.push(app.cs.current_object, poly);
details
.draw_extra
.unzoomed
.push(app.cs.current_object, poly.clone());
details.draw_extra.zoomed.push(app.cs.current_object, poly);
}
Err(err) => {
warn!("No outline for {:?}: {}", id, err);
@ -438,9 +437,13 @@ impl InfoPanel {
}
_ => {
details
.draw_extra
.unzoomed
.push(app.cs.perma_selected_object, outline.clone());
details.zoomed.push(app.cs.perma_selected_object, outline);
details
.draw_extra
.zoomed
.push(app.cs.perma_selected_object, outline);
}
}
}
@ -454,8 +457,7 @@ impl InfoPanel {
// TODO Some headings are too wide.. Intersection #xyz (Traffic signals)
.exact_size_percent(30, 60)
.build_custom(ctx),
unzoomed: details.unzoomed.upload(ctx),
zoomed: details.zoomed.upload(ctx),
draw_extra: details.draw_extra.build(ctx),
tooltips: details.tooltips,
hyperlinks: details.hyperlinks,
warpers: details.warpers,
@ -631,11 +633,7 @@ impl InfoPanel {
pub fn draw(&self, g: &mut GfxCtx, app: &App) {
self.panel.draw(g);
if g.canvas.cam_zoom < app.opts.min_zoom_for_detail {
g.redraw(&self.unzoomed);
} else {
g.redraw(&self.zoomed);
}
self.draw_extra.draw(g, app);
if let Some(pt) = g.canvas.get_cursor_in_map_space() {
for (poly, txt) in &self.tooltips {
if poly.contains_pt(pt) {

View File

@ -56,7 +56,7 @@ fn trips_body(
// overlay for better contrast in the unzoomed view. Only add it once, even if multiple trips
// are open.
if !open_trips.is_empty() {
details.unzoomed.push(
details.draw_extra.unzoomed.push(
app.cs.fade_map_dark,
app.primary.map.get_boundary_polygon().clone(),
);

View File

@ -503,13 +503,13 @@ fn draw_problems(
} else {
(Color::WHITE, app.cs.slowest_intersection)
};
details.unzoomed.append(
details.draw_extra.unzoomed.append(
Text::from(Line(format!("{}", delay)).fg(fg_color))
.bg(bg_color)
.render(ctx)
.centered_on(i.polygon.center()),
);
details.zoomed.append(
details.draw_extra.zoomed.append(
Text::from(Line(format!("{}", delay)).fg(fg_color))
.bg(bg_color)
.render(ctx)
@ -523,12 +523,12 @@ fn draw_problems(
}
Problem::ComplexIntersectionCrossing(i) => {
let i = map.get_i(*i);
details.unzoomed.append(
details.draw_extra.unzoomed.append(
GeomBatch::load_svg(ctx, "system/assets/tools/alert.svg")
.centered_on(i.polygon.center())
.color(RewriteColor::ChangeAlpha(0.8)),
);
details.zoomed.append(
details.draw_extra.zoomed.append(
GeomBatch::load_svg(ctx, "system/assets/tools/alert.svg")
.scale(0.5)
.color(RewriteColor::ChangeAlpha(0.5))
@ -545,12 +545,12 @@ fn draw_problems(
}
Problem::OvertakeDesired(on) => {
let pt = on.get_polyline(map).middle();
details.unzoomed.append(
details.draw_extra.unzoomed.append(
GeomBatch::load_svg(ctx, "system/assets/tools/alert.svg")
.centered_on(pt)
.color(RewriteColor::ChangeAlpha(0.8)),
);
details.zoomed.append(
details.draw_extra.zoomed.append(
GeomBatch::load_svg(ctx, "system/assets/tools/alert.svg")
.scale(0.5)
.color(RewriteColor::ChangeAlpha(0.5))
@ -568,12 +568,12 @@ fn draw_problems(
let t = map.get_t(*t);
let geom = t.geom.make_polygons(Distance::meters(10.0));
details.unzoomed.append(
details.draw_extra.unzoomed.append(
GeomBatch::load_svg(ctx, "system/assets/tools/alert.svg")
.centered_on(geom.center())
.color(RewriteColor::ChangeAlpha(0.8)),
);
details.zoomed.append(
details.draw_extra.zoomed.append(
GeomBatch::load_svg(ctx, "system/assets/tools/alert.svg")
.scale(0.5)
.color(RewriteColor::ChangeAlpha(0.5))
@ -725,9 +725,11 @@ fn make_trip_details(
.insert(format!("jump to start of {}", trip_id), id);
details
.draw_extra
.unzoomed
.append(map_gui::tools::start_marker(ctx, center, 2.0));
details
.draw_extra
.zoomed
.append(map_gui::tools::start_marker(ctx, center, 0.5));
@ -746,9 +748,11 @@ fn make_trip_details(
.insert(format!("jump to goal of {}", trip_id), id);
details
.draw_extra
.unzoomed
.append(map_gui::tools::goal_marker(ctx, center, 2.0));
details
.draw_extra
.zoomed
.append(map_gui::tools::goal_marker(ctx, center, 0.5));
@ -797,8 +801,8 @@ fn make_trip_details(
}
}
if let Some((ref unzoomed, ref zoomed)) = open_trip.cached_routes[idx] {
details.unzoomed.push(color, unzoomed.clone());
details.zoomed.extend(color, zoomed.clone());
details.draw_extra.unzoomed.push(color, unzoomed.clone());
details.draw_extra.zoomed.extend(color, zoomed.clone());
}
} else if p.has_path_req {
path_impossible = true;

View File

@ -1,7 +1,7 @@
use geom::{Angle, Distance, FindClosest, PolyLine, Polygon, Pt2D};
use map_gui::tools::{ColorDiscrete, ColorScale, Grid, ToggleZoomed};
use map_gui::ID;
use widgetry::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, Panel, Text, TextExt, Widget};
use widgetry::{Color, EventCtx, GeomBatch, GfxCtx, Panel, Text, TextExt, Widget};
use crate::app::App;
use crate::layer::{header, Layer, LayerOutcome, PANEL_PLACEMENT};
@ -157,7 +157,7 @@ const CONTOUR_STEP_SIZE: Distance = Distance::const_meters(15.0);
pub struct ElevationContours {
tooltip: Option<Text>,
closest_elevation: FindClosest<Distance>,
unzoomed: Drawable,
draw: ToggleZoomed,
panel: Panel,
}
@ -187,15 +187,13 @@ impl Layer for ElevationContours {
}
fn draw(&self, g: &mut GfxCtx, app: &App) {
self.panel.draw(g);
if g.canvas.cam_zoom < app.opts.min_zoom_for_detail {
g.redraw(&self.unzoomed);
}
self.draw.draw(g, app);
if let Some(ref txt) = self.tooltip {
g.draw_mouse_tooltip(txt.clone());
}
}
fn draw_minimap(&self, g: &mut GfxCtx) {
g.redraw(&self.unzoomed);
g.redraw(&self.draw.unzoomed);
}
}
@ -208,7 +206,7 @@ impl ElevationContours {
high = high.max(i.elevation);
}
let (closest_elevation, unzoomed) = ElevationContours::make_contours(ctx, app, low, high);
let (closest_elevation, draw) = ElevationContours::make_contours(ctx, app, low, high);
let panel = Panel::new_builder(Widget::col(vec![
header(ctx, "Elevation"),
@ -225,7 +223,7 @@ impl ElevationContours {
ElevationContours {
tooltip: None,
closest_elevation,
unzoomed,
draw,
panel,
}
}
@ -235,10 +233,10 @@ impl ElevationContours {
app: &App,
low: Distance,
high: Distance,
) -> (FindClosest<Distance>, Drawable) {
) -> (FindClosest<Distance>, ToggleZoomed) {
let bounds = app.primary.map.get_bounds();
let mut closest = FindClosest::new(bounds);
let mut batch = GeomBatch::new();
let mut draw = ToggleZoomed::builder();
ctx.loading_screen("generate contours", |_, timer| {
timer.start("gather input");
@ -304,9 +302,9 @@ impl ElevationContours {
if let Ok(p) = Polygon::from_geojson(&p) {
let poly = p.scale(resolution_m);
if let Ok(x) = poly.to_outline(Distance::meters(5.0)) {
batch.push(Color::BLACK.alpha(0.5), x);
draw.unzoomed.push(Color::BLACK.alpha(0.5), x);
}
batch.push(color.alpha(0.1), poly);
draw.unzoomed.push(color.alpha(0.1), poly);
}
}
}
@ -315,6 +313,6 @@ impl ElevationContours {
}
});
(closest, batch.upload(ctx))
(closest, draw.build(ctx))
}
}

View File

@ -2,11 +2,10 @@ use std::collections::HashSet;
use abstutil::prettyprint_usize;
use geom::{Circle, Distance, Pt2D, Time};
use map_gui::tools::{make_heatmap, HeatmapOptions};
use map_gui::tools::{make_heatmap, HeatmapOptions, ToggleZoomed};
use sim::PersonState;
use widgetry::{
Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, Outcome, Panel, Text, TextExt,
Toggle, Widget,
Choice, Color, EventCtx, GfxCtx, Line, Outcome, Panel, Text, TextExt, Toggle, Widget,
};
use crate::app::App;
@ -17,7 +16,7 @@ use crate::layer::{header, Layer, LayerOutcome, PANEL_PLACEMENT};
pub struct Pandemic {
time: Time,
opts: Options,
draw: Drawable,
draw: ToggleZoomed,
panel: Panel,
}
@ -50,12 +49,10 @@ impl Layer for Pandemic {
}
fn draw(&self, g: &mut GfxCtx, app: &App) {
self.panel.draw(g);
if g.canvas.cam_zoom < app.opts.min_zoom_for_detail {
g.redraw(&self.draw);
}
self.draw.draw(g, app);
}
fn draw_minimap(&self, g: &mut GfxCtx) {
g.redraw(&self.draw);
g.redraw(&self.draw.unzoomed);
}
}
@ -108,12 +105,12 @@ impl Pandemic {
}
}
let mut batch = GeomBatch::new();
let mut draw = ToggleZoomed::builder();
let legend = if let Some(ref o) = opts.heatmap {
pts.extend(repeat_pts);
Some(make_heatmap(
ctx,
&mut batch,
&mut draw.unzoomed,
app.primary.map.get_bounds(),
pts,
o,
@ -122,7 +119,8 @@ impl Pandemic {
// It's quite silly to produce triangles for the same circle over and over again. ;)
let circle = Circle::new(Pt2D::new(0.0, 0.0), Distance::meters(10.0)).to_polygon();
for pt in pts {
batch.push(Color::RED.alpha(0.8), circle.translate(pt.x(), pt.y()));
draw.unzoomed
.push(Color::RED.alpha(0.8), circle.translate(pt.x(), pt.y()));
}
None
};
@ -130,7 +128,7 @@ impl Pandemic {
Pandemic {
time: app.primary.sim.time(),
opts,
draw: ctx.upload(batch),
draw: draw.build(ctx),
panel: controls,
}
}

View File

@ -2,11 +2,9 @@ use std::collections::HashSet;
use abstutil::prettyprint_usize;
use geom::{Circle, Distance, Pt2D, Time};
use map_gui::tools::{make_heatmap, HeatmapOptions};
use map_gui::tools::{make_heatmap, HeatmapOptions, ToggleZoomed};
use sim::PersonState;
use widgetry::{
Color, Drawable, EventCtx, GeomBatch, GfxCtx, Image, Line, Outcome, Panel, Toggle, Widget,
};
use widgetry::{Color, EventCtx, GfxCtx, Image, Line, Outcome, Panel, Toggle, Widget};
use crate::app::App;
use crate::layer::{header, Layer, LayerOutcome, PANEL_PLACEMENT};
@ -16,7 +14,7 @@ use crate::layer::{header, Layer, LayerOutcome, PANEL_PLACEMENT};
pub struct PopulationMap {
time: Time,
opts: Options,
draw: Drawable,
draw: ToggleZoomed,
panel: Panel,
}
@ -49,12 +47,10 @@ impl Layer for PopulationMap {
}
fn draw(&self, g: &mut GfxCtx, app: &App) {
self.panel.draw(g);
if g.canvas.cam_zoom < app.opts.min_zoom_for_detail {
g.redraw(&self.draw);
}
self.draw.draw(g, app);
}
fn draw_minimap(&self, g: &mut GfxCtx) {
g.redraw(&self.draw);
g.redraw(&self.draw.unzoomed);
}
}
@ -100,12 +96,12 @@ impl PopulationMap {
}
}
let mut batch = GeomBatch::new();
let mut draw = ToggleZoomed::builder();
let legend = if let Some(ref o) = opts.heatmap {
pts.extend(repeat_pts);
Some(make_heatmap(
ctx,
&mut batch,
&mut draw.unzoomed,
app.primary.map.get_bounds(),
pts,
o,
@ -114,7 +110,8 @@ impl PopulationMap {
// It's quite silly to produce triangles for the same circle over and over again. ;)
let circle = Circle::new(Pt2D::new(0.0, 0.0), Distance::meters(10.0)).to_polygon();
for pt in pts {
batch.push(Color::RED.alpha(0.8), circle.translate(pt.x(), pt.y()));
draw.unzoomed
.push(Color::RED.alpha(0.8), circle.translate(pt.x(), pt.y()));
}
None
};
@ -122,7 +119,7 @@ impl PopulationMap {
PopulationMap {
time: app.primary.sim.time(),
opts,
draw: ctx.upload(batch),
draw: draw.build(ctx),
panel: controls,
}
}

View File

@ -2,11 +2,10 @@ use std::collections::BTreeSet;
use abstutil::prettyprint_usize;
use geom::{Circle, Distance, Pt2D, Time};
use map_gui::tools::{make_heatmap, HeatmapOptions};
use map_gui::tools::{make_heatmap, HeatmapOptions, ToggleZoomed};
use sim::{Problem, TripInfo, TripMode};
use widgetry::{
Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, Outcome, Panel, Slider, Text, TextExt,
Toggle, Widget,
Color, EventCtx, GfxCtx, Line, Outcome, Panel, Slider, Text, TextExt, Toggle, Widget,
};
use crate::app::App;
@ -16,7 +15,7 @@ use crate::layer::{header, Layer, LayerOutcome, PANEL_PLACEMENT};
pub struct ProblemMap {
time: Time,
opts: Options,
draw: Drawable,
draw: ToggleZoomed,
panel: Panel,
}
@ -49,12 +48,10 @@ impl Layer for ProblemMap {
}
fn draw(&self, g: &mut GfxCtx, app: &App) {
self.panel.draw(g);
if g.canvas.cam_zoom < app.opts.min_zoom_for_detail {
g.redraw(&self.draw);
}
self.draw.draw(g, app);
}
fn draw_minimap(&self, g: &mut GfxCtx) {
g.redraw(&self.draw);
g.redraw(&self.draw.unzoomed);
}
}
@ -79,11 +76,11 @@ impl ProblemMap {
}
let num_pts = pts.len();
let mut batch = GeomBatch::new();
let mut draw = ToggleZoomed::builder();
let legend = if let Some(ref o) = opts.heatmap {
Some(make_heatmap(
ctx,
&mut batch,
&mut draw.unzoomed,
app.primary.map.get_bounds(),
pts,
o,
@ -92,7 +89,8 @@ impl ProblemMap {
let circle = Circle::new(Pt2D::new(0.0, 0.0), Distance::meters(10.0)).to_polygon();
// TODO Different colors per problem type
for pt in pts {
batch.push(Color::PURPLE.alpha(0.8), circle.translate(pt.x(), pt.y()));
draw.unzoomed
.push(Color::PURPLE.alpha(0.8), circle.translate(pt.x(), pt.y()));
}
None
};
@ -100,7 +98,7 @@ impl ProblemMap {
ProblemMap {
time: app.primary.sim.time(),
opts,
draw: ctx.upload(batch),
draw: draw.build(ctx),
panel: controls,
}
}

View File

@ -222,7 +222,7 @@ impl Layers {
if self.elevation {
if let Some((_, ref draw)) = app.session.elevation_contours.value() {
g.redraw(draw);
draw.draw(g, app);
}
}
if let Some(ref draw) = self.steep_streets {

View File

@ -7,7 +7,7 @@ use widgetry::{lctrl, EventCtx, GfxCtx, Key, Line, Text, Widget};
pub use self::camera::{CameraState, DefaultMap};
pub use self::city_picker::CityPicker;
pub use self::colors::{ColorDiscrete, ColorLegend, ColorNetwork, ColorScale, DivergingScale};
pub use self::draw::ToggleZoomed;
pub use self::draw::{ToggleZoomed, ToggleZoomedBuilder};
pub use self::heatmap::{draw_isochrone, make_heatmap, Grid, HeatmapOptions};
pub use self::icons::{goal_marker, start_marker};
pub use self::minimap::{Minimap, MinimapControls};