slowly whittle down public surface of ezgui

- stop referencing Prerender when easy
- default_font_size hasn't been used since the great typography refactor

some of this harms the usability of map_editor, but that's fine, because
the UX is awful anyway, and nobody should be using this except for me
very occasionally. long-term fate of it is to go away.
This commit is contained in:
Dustin Carlino 2020-08-04 11:36:47 -07:00
parent 75179f1400
commit 5fe3cc5f8a
18 changed files with 130 additions and 184 deletions

View File

@ -9,7 +9,6 @@ use usvg::{fontdb, Options};
// TODO We don't need refcell maybe? Can we take &mut Assets?
pub struct Assets {
pub default_line_height: RefCell<f64>,
pub default_font_size: RefCell<usize>,
pub scale_factor: RefCell<f64>,
text_cache: RefCell<LruCache<String, GeomBatch>>,
line_height_cache: RefCell<HashMap<(Font, usize), f64>>,
@ -21,10 +20,9 @@ pub struct Assets {
}
impl Assets {
pub fn new(default_font_size: usize, font_dir: String, scale_factor: f64) -> Assets {
pub fn new(font_dir: String, scale_factor: f64) -> Assets {
let mut a = Assets {
default_line_height: RefCell::new(0.0),
default_font_size: RefCell::new(default_font_size),
scale_factor: RefCell::new(scale_factor),
text_cache: RefCell::new(LruCache::new(500)),
line_height_cache: RefCell::new(HashMap::new()),
@ -60,7 +58,7 @@ impl Assets {
);
}
*a.default_line_height.borrow_mut() =
a.line_height(text::DEFAULT_FONT, *a.default_font_size.borrow());
a.line_height(text::DEFAULT_FONT, text::DEFAULT_FONT_SIZE);
a
}
@ -127,7 +125,7 @@ impl Assets {
self.text_cache.borrow_mut().clear();
self.line_height_cache.borrow_mut().clear();
*self.default_line_height.borrow_mut() =
self.line_height(text::DEFAULT_FONT, *self.default_font_size.borrow());
self.line_height(text::DEFAULT_FONT, text::DEFAULT_FONT_SIZE);
}
}

View File

@ -48,8 +48,8 @@ pub struct GfxCtx<'a> {
pub prerender: &'a Prerender,
style: &'a Style,
pub num_draw_calls: usize,
pub num_forks: usize,
pub(crate) num_draw_calls: usize,
pub(crate) num_forks: usize,
}
impl<'a> GfxCtx<'a> {

View File

@ -138,17 +138,6 @@ impl<'a> EventCtx<'a> {
pub fn set_style(&mut self, style: Style) {
*self.style = style;
}
pub fn populate_osd(&mut self, txt: &mut Text) {
let color = self.style().hotkey_color;
for (key, a) in self.input.important_actions.drain(..) {
txt.add_appended(vec![
Line("Press "),
Line(key.describe()).fg(color),
Line(format!(" to {}", a)),
]);
}
}
}
pub struct LoadingScreen<'a> {

View File

@ -1,15 +1,11 @@
use crate::{Canvas, Event, Key, MultiKey, ScreenPt};
use geom::Duration;
use std::collections::HashMap;
// As we check for user input, record the input and the thing that would happen. This will let us
// build up some kind of OSD of possible actions.
pub struct UserInput {
pub(crate) event: Event,
pub(crate) event_consumed: bool,
pub(crate) important_actions: Vec<(Key, String)>,
// If two different callers both expect the same key, there's likely an unintentional conflict.
reserved_keys: HashMap<Key, String>,
lctrl_held: bool,
}
@ -19,17 +15,11 @@ impl UserInput {
UserInput {
event,
event_consumed: false,
important_actions: Vec::new(),
reserved_keys: HashMap::new(),
lctrl_held: canvas.lctrl_held,
}
}
pub fn key_pressed(&mut self, key: Key, action: &str) -> bool {
self.reserve_key(key, action);
self.important_actions.push((key, action.to_string()));
pub fn key_pressed(&mut self, key: Key, _action: &str) -> bool {
if self.event_consumed {
return false;
}
@ -53,9 +43,7 @@ impl UserInput {
None
}
pub fn unimportant_key_pressed(&mut self, key: Key, action: &str) -> bool {
self.reserve_key(key, action);
pub fn unimportant_key_pressed(&mut self, key: Key, _action: &str) -> bool {
if self.event_consumed {
return false;
}
@ -68,8 +56,6 @@ impl UserInput {
}
pub fn new_was_pressed(&mut self, multikey: &MultiKey) -> bool {
// TODO Reserve?
if self.event_consumed {
return false;
}
@ -178,11 +164,4 @@ impl UserInput {
pub(crate) fn has_been_consumed(&self) -> bool {
self.event_consumed
}
fn reserve_key(&mut self, key: Key, action: &str) {
if let Some(prev_action) = self.reserved_keys.get(&key) {
println!("both {} and {} read key {:?}", prev_action, action, key);
}
self.reserved_keys.insert(key, action.to_string());
}
}

View File

@ -1,6 +1,6 @@
use crate::assets::Assets;
use crate::tools::screenshot::screenshot_everything;
use crate::{text, Canvas, Event, EventCtx, GfxCtx, Key, Prerender, Style, UpdateType, UserInput};
use crate::{Canvas, Event, EventCtx, GfxCtx, Key, Prerender, Style, UpdateType, UserInput};
use geom::Duration;
use image::{GenericImageView, Pixel};
use instant::Instant;
@ -161,7 +161,6 @@ impl<G: GUI> State<G> {
pub struct Settings {
window_title: String,
profiling_enabled: bool,
default_font_size: usize,
dump_raw_events: bool,
scale_factor: Option<f64>,
window_icon: Option<String>,
@ -172,7 +171,6 @@ impl Settings {
Settings {
window_title: window_title.to_string(),
profiling_enabled: false,
default_font_size: text::DEFAULT_FONT_SIZE,
dump_raw_events: false,
scale_factor: None,
window_icon: None,
@ -189,10 +187,6 @@ impl Settings {
self.dump_raw_events = true;
}
pub fn default_font_size(&mut self, size: usize) {
self.default_font_size = size;
}
pub fn scale_factor(&mut self, scale_factor: f64) {
self.scale_factor = Some(scale_factor);
}
@ -220,7 +214,6 @@ pub fn run<G: 'static + GUI, F: FnOnce(&mut EventCtx) -> G>(settings: Settings,
}
let prerender = Prerender {
assets: Assets::new(
settings.default_font_size,
abstutil::path("system/fonts"),
settings
.scale_factor

View File

@ -256,10 +256,10 @@ impl State for DebugMode {
};
for a in agents {
if let Some(obj) = app.primary.draw_map.get_obj(
ctx,
ID::from_agent(a),
app,
&mut app.primary.draw_map.agents.borrow_mut(),
ctx.prerender,
) {
batch.push(Color::PURPLE, obj.get_outline(&app.primary.map));
} else {

View File

@ -549,8 +549,7 @@ pub fn apply_map_edits(ctx: &mut EventCtx, app: &mut App, edits: MapEdits) {
for r in roads_changed {
let road = app.primary.map.get_r(r);
app.primary.draw_map.roads[r.0] =
DrawRoad::new(road, &app.primary.map, &app.cs, ctx.prerender);
app.primary.draw_map.roads[r.0] = DrawRoad::new(ctx, road, &app.primary.map, &app.cs);
// An edit to one lane potentially affects markings in all lanes in the same road, because
// of one-way markings, driving lines, etc.
@ -570,12 +569,8 @@ pub fn apply_map_edits(ctx: &mut EventCtx, app: &mut App, edits: MapEdits) {
}
for i in modified_intersections {
app.primary.draw_map.intersections[i.0] = DrawIntersection::new(
app.primary.map.get_i(i),
&app.primary.map,
&app.cs,
ctx.prerender,
);
app.primary.draw_map.intersections[i.0] =
DrawIntersection::new(ctx, app.primary.map.get_i(i), &app.primary.map, &app.cs);
}
if app.layer.as_ref().and_then(|l| l.name()) == Some("map edits") {

View File

@ -363,10 +363,10 @@ impl InfoPanel {
app.primary
.draw_map
.get_obj(
ctx,
id.clone(),
app,
&mut app.primary.draw_map.agents.borrow_mut(),
ctx.prerender,
)
.map(|obj| (id, obj.get_outline(&app.primary.map)))
}) {

View File

@ -70,9 +70,6 @@ fn main() {
if args.enabled("--dump_raw_events") {
settings.dump_raw_events();
}
if let Some(n) = args.optional_parse("--font_size", |s| s.parse::<usize>()) {
settings.default_font_size(n);
}
if let Some(s) = args.optional_parse("--scale_factor", |s| s.parse::<f64>()) {
settings.scale_factor(s);
}

View File

@ -2,7 +2,7 @@ use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text};
use ezgui::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, Text};
use geom::{Distance, Polygon, Pt2D};
use map_model::{Building, BuildingID, Map, OffstreetParking, NORMAL_LANE_THICKNESS};
use std::cell::RefCell;
@ -14,13 +14,13 @@ pub struct DrawBuilding {
impl DrawBuilding {
pub fn new(
ctx: &EventCtx,
bldg: &Building,
map: &Map,
cs: &ColorScheme,
bldg_batch: &mut GeomBatch,
paths_batch: &mut GeomBatch,
outlines_batch: &mut GeomBatch,
prerender: &Prerender,
) -> DrawBuilding {
// Trim the driveway away from the sidewalk's center line, so that it doesn't overlap. For
// now, this cleanup is visual; it doesn't belong in the map_model layer.
@ -46,7 +46,7 @@ impl DrawBuilding {
if let OffstreetParking::PublicGarage(_, _) = bldg.parking {
// Might need to scale down more for some buildings, but so far, this works everywhere.
bldg_batch.append(
GeomBatch::mapspace_svg(prerender, "system/assets/map/parking.svg")
GeomBatch::mapspace_svg(ctx.prerender, "system/assets/map/parking.svg")
.scale(0.1)
.centered_on(bldg.label_center),
);

View File

@ -2,7 +2,7 @@ use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
use ezgui::{Drawable, GeomBatch, GfxCtx, Prerender};
use ezgui::{Drawable, EventCtx, GeomBatch, GfxCtx};
use geom::{Angle, Circle, Distance, Line, Polygon, Pt2D};
use map_model::{BusStop, BusStopID, Map};
@ -17,7 +17,7 @@ pub struct DrawBusStop {
}
impl DrawBusStop {
pub fn new(stop: &BusStop, map: &Map, cs: &ColorScheme, prerender: &Prerender) -> DrawBusStop {
pub fn new(ctx: &EventCtx, stop: &BusStop, map: &Map, cs: &ColorScheme) -> DrawBusStop {
let (pt, angle) = stop.sidewalk_pos.pt_and_angle(map);
let center = pt.project_away(
map.get_l(stop.sidewalk_pos.lane()).width / 2.0,
@ -27,7 +27,7 @@ impl DrawBusStop {
let mut icon = GeomBatch::new();
icon.append(
GeomBatch::mapspace_svg(
prerender,
ctx.prerender,
if stop.is_train_stop {
"system/assets/map/light_rail.svg"
} else {
@ -57,7 +57,7 @@ impl DrawBusStop {
id: stop.id,
center,
zorder: map.get_parent(stop.sidewalk_pos.lane()).zorder,
draw_default: prerender.upload(batch),
draw_default: ctx.upload(batch),
}
}
}

View File

@ -5,7 +5,7 @@ use crate::options::TrafficSignalStyle;
use crate::render::{
draw_signal_phase, DrawOptions, Renderable, CROSSWALK_LINE_THICKNESS, OUTLINE_THICKNESS,
};
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, RewriteColor, Text};
use ezgui::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, RewriteColor, Text};
use geom::{Angle, ArrowCap, Distance, Line, PolyLine, Polygon, Pt2D, Ring, Time, EPSILON_DIST};
use map_model::{
Intersection, IntersectionID, IntersectionType, Map, Road, RoadWithStopSign, Turn, TurnType,
@ -23,12 +23,7 @@ pub struct DrawIntersection {
}
impl DrawIntersection {
pub fn new(
i: &Intersection,
map: &Map,
cs: &ColorScheme,
prerender: &Prerender,
) -> DrawIntersection {
pub fn new(ctx: &EventCtx, i: &Intersection, map: &Map, cs: &ColorScheme) -> DrawIntersection {
// Order matters... main polygon first, then sidewalk corners.
let mut default_geom = GeomBatch::new();
default_geom.push(cs.normal_intersection, i.polygon.clone());
@ -65,9 +60,12 @@ impl DrawIntersection {
IntersectionType::Construction => {
// TODO Centering seems weird
default_geom.append(
GeomBatch::mapspace_svg(prerender, "system/assets/map/under_construction.svg")
.scale(0.08)
.centered_on(i.polygon.center()),
GeomBatch::mapspace_svg(
ctx.prerender,
"system/assets/map/under_construction.svg",
)
.scale(0.08)
.centered_on(i.polygon.center()),
);
}
IntersectionType::TrafficSignal => {}
@ -82,7 +80,7 @@ impl DrawIntersection {
id: i.id,
intersection_type: i.intersection_type,
zorder,
draw_default: prerender.upload(default_geom),
draw_default: ctx.upload(default_geom),
draw_traffic_signal: RefCell::new(None),
}
}

View File

@ -50,7 +50,7 @@ impl DrawMap {
timer.start_iter("make DrawRoads", map.all_roads().len());
for r in map.all_roads() {
timer.next();
roads.push(DrawRoad::new(r, map, cs, ctx.prerender));
roads.push(DrawRoad::new(ctx, r, map, cs));
}
let mut lanes: Vec<DrawLane> = Vec::new();
@ -64,7 +64,7 @@ impl DrawMap {
timer.start_iter("make DrawIntersections", map.all_intersections().len());
for i in map.all_intersections() {
timer.next();
intersections.push(DrawIntersection::new(i, map, cs, ctx.prerender));
intersections.push(DrawIntersection::new(ctx, i, map, cs));
}
let draw_all_unzoomed_roads_and_intersections =
@ -78,13 +78,13 @@ impl DrawMap {
for b in map.all_buildings() {
timer.next();
buildings.push(DrawBuilding::new(
ctx,
b,
map,
cs,
&mut all_buildings,
&mut all_building_paths,
&mut all_building_outlines,
ctx.prerender,
));
}
timer.start("upload all buildings");
@ -98,11 +98,11 @@ impl DrawMap {
let mut all_unzoomed_parking_lots = GeomBatch::new();
for pl in map.all_parking_lots() {
parking_lots.push(DrawParkingLot::new(
ctx,
pl,
map,
cs,
&mut all_unzoomed_parking_lots,
ctx.prerender,
));
}
let draw_all_unzoomed_parking_lots = all_unzoomed_parking_lots.upload(ctx);
@ -112,7 +112,7 @@ impl DrawMap {
let mut bus_stops: HashMap<BusStopID, DrawBusStop> = HashMap::new();
for s in map.all_bus_stops().values() {
timer.next();
bus_stops.insert(s.id, DrawBusStop::new(s, map, cs, ctx.prerender));
bus_stops.insert(s.id, DrawBusStop::new(ctx, s, map, cs));
}
let mut areas: Vec<DrawArea> = Vec::new();
@ -126,7 +126,7 @@ impl DrawMap {
let draw_all_areas = all_areas.upload(ctx);
timer.stop("upload all areas");
let boundary_polygon = ctx.prerender.upload(GeomBatch::from(vec![(
let boundary_polygon = ctx.upload(GeomBatch::from(vec![(
cs.map_background,
map.get_boundary_polygon().clone(),
)]));
@ -265,10 +265,10 @@ impl DrawMap {
pub fn get_obj<'a>(
&'a self,
ctx: &EventCtx,
id: ID,
app: &App,
agents: &'a mut AgentCache,
prerender: &Prerender,
) -> Option<&'a dyn Renderable> {
let on = match id {
ID::Road(id) => {
@ -312,7 +312,13 @@ impl DrawMap {
}
};
agents.populate_if_needed(on, &app.primary.map, &app.primary.sim, &app.cs, prerender);
agents.populate_if_needed(
on,
&app.primary.map,
&app.primary.sim,
&app.cs,
ctx.prerender,
);
// Why might this fail? Pedestrians merge into crowds, and crowds dissipate into
// individuals

View File

@ -2,7 +2,7 @@ use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
use ezgui::{Drawable, GeomBatch, GfxCtx, Prerender};
use ezgui::{Drawable, EventCtx, GeomBatch, GfxCtx};
use geom::{Distance, PolyLine, Polygon, Pt2D};
use map_model::{Map, ParkingLot, ParkingLotID, NORMAL_LANE_THICKNESS, PARKING_LOT_SPOT_LENGTH};
@ -13,11 +13,11 @@ pub struct DrawParkingLot {
impl DrawParkingLot {
pub fn new(
ctx: &EventCtx,
lot: &ParkingLot,
map: &Map,
cs: &ColorScheme,
unzoomed_batch: &mut GeomBatch,
prerender: &Prerender,
) -> DrawParkingLot {
unzoomed_batch.push(cs.parking_lot, lot.polygon.clone());
for aisle in &lot.aisles {
@ -28,7 +28,7 @@ impl DrawParkingLot {
);
}
unzoomed_batch.append(
GeomBatch::mapspace_svg(prerender, "system/assets/map/parking.svg")
GeomBatch::mapspace_svg(ctx.prerender, "system/assets/map/parking.svg")
.scale(0.05)
.centered_on(lot.polygon.polylabel()),
);
@ -78,7 +78,7 @@ impl DrawParkingLot {
DrawParkingLot {
id: lot.id,
draw: prerender.upload(batch),
draw: ctx.upload(batch),
}
}
}

View File

@ -2,7 +2,7 @@ use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{DrawOptions, Renderable};
use ezgui::{Drawable, GeomBatch, GfxCtx, Line, Prerender, Text};
use ezgui::{Drawable, EventCtx, GeomBatch, GfxCtx, Line, Text};
use geom::{Distance, Polygon, Pt2D};
use map_model::{Map, Road, RoadID};
use std::cell::RefCell;
@ -16,7 +16,7 @@ pub struct DrawRoad {
}
impl DrawRoad {
pub fn new(r: &Road, map: &Map, cs: &ColorScheme, prerender: &Prerender) -> DrawRoad {
pub fn new(ctx: &EventCtx, r: &Road, map: &Map, cs: &ColorScheme) -> DrawRoad {
let mut draw = GeomBatch::new();
// Only draw a center line if it straddles two driving/bike/bus lanes of opposite
@ -45,7 +45,7 @@ impl DrawRoad {
DrawRoad {
id: r.id,
zorder: r.zorder,
draw_center_line: prerender.upload(draw),
draw_center_line: ctx.upload(draw),
label: RefCell::new(None),
}
}

View File

@ -59,7 +59,7 @@ impl UI {
args.done();
let model = if let Some(path) = load {
Model::import(path, include_bldgs, intersection_geom, ctx.prerender)
Model::import(path, include_bldgs, intersection_geom, ctx)
} else {
Model::blank()
};
@ -141,7 +141,7 @@ impl GUI for UI {
self.model.stop_showing_pts(id);
}
if let Some(r) = after {
self.model.show_r_points(r, ctx.prerender);
self.model.show_r_points(r, ctx);
self.model.world.handle_mouseover(ctx);
}
}
@ -157,7 +157,7 @@ impl GUI for UI {
self.model.delete_i(i);
self.model.world.handle_mouseover(ctx);
} else if ctx.input.key_pressed(Key::T, "toggle intersection type") {
self.model.toggle_i_type(i, ctx.prerender);
self.model.toggle_i_type(i, ctx);
} else if !self.model.intersection_geom
&& ctx
.input
@ -189,10 +189,10 @@ impl GUI for UI {
} else if ctx.input.key_pressed(Key::N, "edit name/speed") {
self.state = State::EditingRoadAttribs(r, Wizard::new());
} else if could_swap && ctx.input.key_pressed(Key::S, "swap lanes") {
self.model.swap_lanes(r, ctx.prerender);
self.model.swap_lanes(r, ctx);
self.model.world.handle_mouseover(ctx);
} else if ctx.input.key_pressed(Key::F, "toggle sidewalks") {
self.model.toggle_r_sidewalks(r, ctx.prerender);
self.model.toggle_r_sidewalks(r, ctx);
self.model.world.handle_mouseover(ctx);
} else if ctx
.input
@ -222,20 +222,18 @@ impl GUI for UI {
} else if cursor.is_some()
&& ctx.input.key_pressed(Key::P, "create new point")
{
if let Some(id) =
self.model.insert_r_pt(r, cursor.unwrap(), ctx.prerender)
{
if let Some(id) = self.model.insert_r_pt(r, cursor.unwrap(), ctx) {
self.model.world.force_set_selection(id);
}
} else if ctx.input.key_pressed(Key::X, "clear interior points") {
self.model.clear_r_pts(r, ctx.prerender);
self.model.clear_r_pts(r, ctx);
}
}
Some(ID::RoadPoint(r, idx)) => {
if ctx.input.key_pressed(Key::LeftControl, "move point") {
self.state = State::MovingRoadPoint(r, idx);
} else if ctx.input.key_pressed(Key::Backspace, "delete point") {
self.model.delete_r_pt(r, idx, ctx.prerender);
self.model.delete_r_pt(r, idx, ctx);
self.model.world.handle_mouseover(ctx);
}
}
@ -288,7 +286,7 @@ impl GUI for UI {
_ => {
if ctx.input.key_pressed(Key::I, "create intersection") {
if let Some(pt) = cursor {
self.model.create_i(pt, ctx.prerender);
self.model.create_i(pt, ctx);
self.model.world.handle_mouseover(ctx);
}
// TODO Silly bug: Mouseover doesn't actually work! I think the
@ -296,7 +294,7 @@ impl GUI for UI {
// up the precomputed triangles.
} else if ctx.input.key_pressed(Key::B, "create building") {
if let Some(pt) = cursor {
let id = self.model.create_b(pt, ctx.prerender);
let id = self.model.create_b(pt, ctx);
self.model.world.force_set_selection(id);
}
} else if ctx.input.key_pressed(Key::LeftShift, "select area") {
@ -311,7 +309,7 @@ impl GUI for UI {
}
State::MovingIntersection(id) => {
if let Some(pt) = cursor {
self.model.move_i(id, pt, ctx.prerender);
self.model.move_i(id, pt, ctx);
if ctx.input.key_released(Key::LeftControl) {
self.state = State::viewing();
}
@ -319,7 +317,7 @@ impl GUI for UI {
}
State::MovingBuilding(id) => {
if let Some(pt) = cursor {
self.model.move_b(id, pt, ctx.prerender);
self.model.move_b(id, pt, ctx);
if ctx.input.key_released(Key::LeftControl) {
self.state = State::viewing();
}
@ -327,7 +325,7 @@ impl GUI for UI {
}
State::MovingRoadPoint(r, idx) => {
if let Some(pt) = cursor {
self.model.move_r_pt(r, idx, pt, ctx.prerender);
self.model.move_r_pt(r, idx, pt, ctx);
if ctx.input.key_released(Key::LeftControl) {
self.state = State::viewing();
}
@ -339,7 +337,7 @@ impl GUI for UI {
self.model.world.handle_mouseover(ctx);
} else if let Some(ID::Intersection(i2)) = self.model.world.get_selection() {
if i1 != i2 && ctx.input.key_pressed(Key::R, "finalize road") {
self.model.create_r(i1, i2, ctx.prerender);
self.model.create_r(i1, i2, ctx);
self.state = State::viewing();
self.model.world.handle_mouseover(ctx);
}
@ -350,7 +348,7 @@ impl GUI for UI {
"Specify the lanes",
self.model.map.roads[&id].get_spec().to_string(),
) {
self.model.edit_lanes(id, s, ctx.prerender);
self.model.edit_lanes(id, s, ctx);
self.state = State::viewing();
self.model.world.handle_mouseover(ctx);
} else if wizard.aborted() {
@ -382,7 +380,7 @@ impl GUI for UI {
vec!["motorway", "primary", "residential"]
})
{
self.model.set_r_name_and_speed(id, n, s, h, ctx.prerender);
self.model.set_r_name_and_speed(id, n, s, h, ctx);
done = true;
}
}
@ -458,7 +456,7 @@ impl GUI for UI {
]
})
{
self.model.add_tr(from, restriction, to, ctx.prerender);
self.model.add_tr(from, restriction, to, ctx);
self.state = State::viewing();
self.model.world.handle_mouseover(ctx);
} else if wizard.aborted() {
@ -523,10 +521,9 @@ impl GUI for UI {
name.to_string(),
speed.to_string(),
highway.to_string(),
ctx.prerender,
ctx,
);
self.model
.edit_lanes(id, lanespec.to_string(), ctx.prerender);
self.model.edit_lanes(id, lanespec.to_string(), ctx);
}
}
}
@ -535,9 +532,8 @@ impl GUI for UI {
self.popup = None;
if self.info_key_held {
if let Some(id) = self.model.world.get_selection() {
let mut txt = self.model.describe_obj(id);
txt.add(Line(""));
ctx.populate_osd(&mut txt);
let txt = self.model.describe_obj(id);
// TODO We used to display actions and hotkeys here
self.popup = Some(ctx.upload(txt.render_to_batch(ctx.prerender)));
}
}

View File

@ -1,6 +1,6 @@
use crate::world::{Object, ObjectID, World};
use abstutil::{Tags, Timer};
use ezgui::{Color, Line, Prerender, Text};
use ezgui::{Color, EventCtx, Line, Text};
use geom::{
ArrowCap, Bounds, Circle, Distance, FindClosest, GPSBounds, LonLat, PolyLine, Polygon, Pt2D,
};
@ -46,7 +46,7 @@ impl Model {
path: String,
include_bldgs: bool,
intersection_geom: bool,
prerender: &Prerender,
ctx: &EventCtx,
) -> Model {
let mut timer = Timer::new("import map");
let mut model = Model::blank();
@ -61,7 +61,7 @@ impl Model {
if model.include_bldgs {
for id in model.map.buildings.keys().cloned().collect::<Vec<_>>() {
model.bldg_added(id, prerender);
model.bldg_added(id, ctx);
}
}
timer.start_iter(
@ -70,12 +70,12 @@ impl Model {
);
for id in model.map.intersections.keys().cloned().collect::<Vec<_>>() {
timer.next();
model.intersection_added(id, prerender);
model.intersection_added(id, ctx);
}
timer.start_iter("fill out world with roads", model.map.roads.len());
for id in model.map.roads.keys().cloned().collect::<Vec<_>>() {
timer.next();
model.road_added(id, prerender);
model.road_added(id, ctx);
}
model
@ -237,7 +237,7 @@ impl Model {
// Intersections
impl Model {
fn intersection_added(&mut self, id: OriginalIntersection, prerender: &Prerender) {
fn intersection_added(&mut self, id: OriginalIntersection, ctx: &EventCtx) {
let i = &self.map.intersections[&id];
let color = match i.intersection_type {
IntersectionType::TrafficSignal => Color::GREEN,
@ -254,10 +254,10 @@ impl Model {
};
self.world
.add(prerender, Object::new(ID::Intersection(id), color, poly));
.add(ctx, Object::new(ID::Intersection(id), color, poly));
}
pub fn create_i(&mut self, point: Pt2D, prerender: &Prerender) {
pub fn create_i(&mut self, point: Pt2D, ctx: &EventCtx) {
let id = OriginalIntersection {
osm_node_id: self.map.new_osm_node_id(time_to_id()),
};
@ -271,19 +271,19 @@ impl Model {
elevation: Distance::ZERO,
},
);
self.intersection_added(id, prerender);
self.intersection_added(id, ctx);
}
pub fn move_i(&mut self, id: OriginalIntersection, point: Pt2D, prerender: &Prerender) {
pub fn move_i(&mut self, id: OriginalIntersection, point: Pt2D, ctx: &EventCtx) {
self.world.delete(ID::Intersection(id));
for r in self.map.move_intersection(id, point).unwrap() {
self.road_deleted(r);
self.road_added(r, prerender);
self.road_added(r, ctx);
}
self.intersection_added(id, prerender);
self.intersection_added(id, ctx);
}
pub fn toggle_i_type(&mut self, id: OriginalIntersection, prerender: &Prerender) {
pub fn toggle_i_type(&mut self, id: OriginalIntersection, ctx: &EventCtx) {
self.world.delete(ID::Intersection(id));
let it = match self.map.intersections[&id].intersection_type {
IntersectionType::StopSign => IntersectionType::TrafficSignal,
@ -303,7 +303,7 @@ impl Model {
.get_mut(&id)
.unwrap()
.intersection_type = it;
self.intersection_added(id, prerender);
self.intersection_added(id, ctx);
}
pub fn delete_i(&mut self, id: OriginalIntersection) {
@ -318,9 +318,9 @@ impl Model {
// Roads
impl Model {
fn road_added(&mut self, id: OriginalRoad, prerender: &Prerender) {
fn road_added(&mut self, id: OriginalRoad, ctx: &EventCtx) {
for obj in self.road_objects(id) {
self.world.add(prerender, obj);
self.world.add(ctx, obj);
}
}
@ -330,12 +330,7 @@ impl Model {
}
}
pub fn create_r(
&mut self,
i1: OriginalIntersection,
i2: OriginalIntersection,
prerender: &Prerender,
) {
pub fn create_r(&mut self, i1: OriginalIntersection, i2: OriginalIntersection, ctx: &EventCtx) {
// Ban cul-de-sacs, since they get stripped out later anyway.
if self
.map
@ -381,10 +376,10 @@ impl Model {
complicated_turn_restrictions: Vec::new(),
},
);
self.road_added(id, prerender);
self.road_added(id, ctx);
}
pub fn edit_lanes(&mut self, id: OriginalRoad, spec: String, prerender: &Prerender) {
pub fn edit_lanes(&mut self, id: OriginalRoad, spec: String, ctx: &EventCtx) {
self.road_deleted(id);
if let Some(s) = RoadSpec::parse(spec.clone()) {
@ -398,10 +393,10 @@ impl Model {
println!("Bad RoadSpec: {}", spec);
}
self.road_added(id, prerender);
self.road_added(id, ctx);
}
pub fn swap_lanes(&mut self, id: OriginalRoad, prerender: &Prerender) {
pub fn swap_lanes(&mut self, id: OriginalRoad, ctx: &EventCtx) {
self.road_deleted(id);
let (mut lanes, osm_tags) = {
@ -411,7 +406,7 @@ impl Model {
mem::swap(&mut lanes.fwd, &mut lanes.back);
osm_tags.insert(osm::SYNTHETIC_LANES, lanes.to_string());
self.road_added(id, prerender);
self.road_added(id, ctx);
}
pub fn set_r_name_and_speed(
@ -420,7 +415,7 @@ impl Model {
name: String,
speed: String,
highway: String,
prerender: &Prerender,
ctx: &EventCtx,
) {
self.road_deleted(id);
@ -429,10 +424,10 @@ impl Model {
osm_tags.insert(osm::MAXSPEED, speed);
osm_tags.insert(osm::HIGHWAY, highway);
self.road_added(id, prerender);
self.road_added(id, ctx);
}
pub fn toggle_r_sidewalks(&mut self, some_id: OriginalRoad, prerender: &Prerender) {
pub fn toggle_r_sidewalks(&mut self, some_id: OriginalRoad, ctx: &EventCtx) {
// Update every road belonging to the way.
let osm_id = self.map.roads[&some_id]
.osm_tags
@ -481,7 +476,7 @@ impl Model {
osm_tags.insert(osm::SIDEWALK, "both");
}
self.road_added(id, prerender);
self.road_added(id, ctx);
}
}
@ -596,7 +591,7 @@ impl Model {
}
}
pub fn show_r_points(&mut self, id: OriginalRoad, prerender: &Prerender) {
pub fn show_r_points(&mut self, id: OriginalRoad, ctx: &EventCtx) {
if self.showing_pts == Some(id) {
return;
}
@ -610,7 +605,7 @@ impl Model {
// Don't show handles for the intersections
if idx != 0 && idx != r.center_points.len() - 1 {
self.world.add(
prerender,
ctx,
Object::new(
ID::RoadPoint(id, idx),
Color::GREEN,
@ -632,7 +627,7 @@ impl Model {
}
}
pub fn move_r_pt(&mut self, id: OriginalRoad, idx: usize, point: Pt2D, prerender: &Prerender) {
pub fn move_r_pt(&mut self, id: OriginalRoad, idx: usize, point: Pt2D, ctx: &EventCtx) {
assert_eq!(self.showing_pts, Some(id));
self.stop_showing_pts(id);
@ -643,13 +638,13 @@ impl Model {
let pts = &mut self.map.roads.get_mut(&id).unwrap().center_points;
pts[idx] = point;
self.road_added(id, prerender);
self.intersection_added(id.i1, prerender);
self.intersection_added(id.i2, prerender);
self.show_r_points(id, prerender);
self.road_added(id, ctx);
self.intersection_added(id.i1, ctx);
self.intersection_added(id.i2, ctx);
self.show_r_points(id, ctx);
}
pub fn delete_r_pt(&mut self, id: OriginalRoad, idx: usize, prerender: &Prerender) {
pub fn delete_r_pt(&mut self, id: OriginalRoad, idx: usize, ctx: &EventCtx) {
assert_eq!(self.showing_pts, Some(id));
self.stop_showing_pts(id);
@ -660,13 +655,13 @@ impl Model {
let pts = &mut self.map.roads.get_mut(&id).unwrap().center_points;
pts.remove(idx);
self.road_added(id, prerender);
self.intersection_added(id.i1, prerender);
self.intersection_added(id.i2, prerender);
self.show_r_points(id, prerender);
self.road_added(id, ctx);
self.intersection_added(id.i1, ctx);
self.intersection_added(id.i2, ctx);
self.show_r_points(id, ctx);
}
pub fn insert_r_pt(&mut self, id: OriginalRoad, pt: Pt2D, prerender: &Prerender) -> Option<ID> {
pub fn insert_r_pt(&mut self, id: OriginalRoad, pt: Pt2D, ctx: &EventCtx) -> Option<ID> {
assert_eq!(self.showing_pts, Some(id));
self.stop_showing_pts(id);
@ -687,15 +682,15 @@ impl Model {
None
};
self.road_added(id, prerender);
self.intersection_added(id.i1, prerender);
self.intersection_added(id.i2, prerender);
self.show_r_points(id, prerender);
self.road_added(id, ctx);
self.intersection_added(id.i1, ctx);
self.intersection_added(id.i2, ctx);
self.show_r_points(id, ctx);
new_id
}
pub fn clear_r_pts(&mut self, id: OriginalRoad, prerender: &Prerender) {
pub fn clear_r_pts(&mut self, id: OriginalRoad, ctx: &EventCtx) {
assert_eq!(self.showing_pts, Some(id));
self.stop_showing_pts(id);
@ -706,10 +701,10 @@ impl Model {
let r = &mut self.map.roads.get_mut(&id).unwrap();
r.center_points = vec![r.center_points[0], *r.center_points.last().unwrap()];
self.road_added(id, prerender);
self.intersection_added(id.i1, prerender);
self.intersection_added(id.i2, prerender);
self.show_r_points(id, prerender);
self.road_added(id, ctx);
self.intersection_added(id.i1, ctx);
self.intersection_added(id.i2, ctx);
self.show_r_points(id, ctx);
}
pub fn get_r_center(&self, id: OriginalRoad) -> Pt2D {
@ -724,7 +719,7 @@ impl Model {
from: OriginalRoad,
restriction: RestrictionType,
to: OriginalRoad,
prerender: &Prerender,
ctx: &EventCtx,
) {
self.road_deleted(from);
@ -737,7 +732,7 @@ impl Model {
.turn_restrictions
.push((restriction, to));
self.road_added(from, prerender);
self.road_added(from, ctx);
}
pub fn delete_tr(&mut self, tr: TurnRestriction) {
@ -748,15 +743,15 @@ impl Model {
// Buildings
impl Model {
fn bldg_added(&mut self, id: OriginalBuilding, prerender: &Prerender) {
fn bldg_added(&mut self, id: OriginalBuilding, ctx: &EventCtx) {
let b = &self.map.buildings[&id];
self.world.add(
prerender,
ctx,
Object::new(ID::Building(id), Color::BLUE, b.polygon.clone()),
);
}
pub fn create_b(&mut self, center: Pt2D, prerender: &Prerender) -> ID {
pub fn create_b(&mut self, center: Pt2D, ctx: &EventCtx) -> ID {
let id = OriginalBuilding {
osm_way_id: self.map.new_osm_way_id(time_to_id()),
};
@ -770,11 +765,11 @@ impl Model {
amenities: BTreeSet::new(),
},
);
self.bldg_added(id, prerender);
self.bldg_added(id, ctx);
ID::Building(id)
}
pub fn move_b(&mut self, id: OriginalBuilding, new_center: Pt2D, prerender: &Prerender) {
pub fn move_b(&mut self, id: OriginalBuilding, new_center: Pt2D, ctx: &EventCtx) {
self.world.delete(ID::Building(id));
let b = self.map.buildings.get_mut(&id).unwrap();
@ -784,7 +779,7 @@ impl Model {
new_center.y() - old_center.y(),
);
self.bldg_added(id, prerender);
self.bldg_added(id, ctx);
}
pub fn delete_b(&mut self, id: OriginalBuilding) {

View File

@ -1,5 +1,5 @@
use aabb_quadtree::{ItemId, QuadTree};
use ezgui::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, Prerender};
use ezgui::{Color, Drawable, EventCtx, GeomBatch, GfxCtx};
use geom::{Bounds, Circle, Distance, Polygon, Pt2D};
use std::collections::HashMap;
use std::fmt::Debug;
@ -126,7 +126,7 @@ impl<ID: ObjectID> World<ID> {
}
// TODO This and delete assume the original bounds passed to the quadtree are still valid.
pub fn add(&mut self, prerender: &Prerender, obj: Object<ID>) {
pub fn add(&mut self, ctx: &EventCtx, obj: Object<ID>) {
let unioned_polygon =
Polygon::union_all(obj.geometry.iter().map(|(_, p)| p.clone()).collect());
@ -139,7 +139,7 @@ impl<ID: ObjectID> World<ID> {
);
}
let quadtree_id = self.quadtree.insert_with_box(obj.id, bounds.as_bbox());
let draw = prerender.upload(GeomBatch::from(obj.geometry));
let draw = ctx.upload(GeomBatch::from(obj.geometry));
self.objects.insert(
obj.id,
WorldObject {