ltn/pages/design_ltn/
speed_limits.rs1use geom::{Speed, UnitFmt};
2use widgetry::mapspace::{World, WorldOutcome};
3use widgetry::tools::ColorLegend;
4use widgetry::{EventCtx, Text, Widget};
5
6use super::{EditOutcome, Obj};
7use crate::render::colors;
8use crate::{App, Neighbourhood};
9
10pub fn widget(ctx: &mut EventCtx) -> Widget {
11 ColorLegend::categories(
12 ctx,
13 vec![
14 (colors::SPEED_LIMITS[0], "0mph"),
15 (colors::SPEED_LIMITS[1], "10"),
16 (colors::SPEED_LIMITS[2], "20"),
17 (colors::SPEED_LIMITS[3], "30"),
18 ],
19 ">30",
20 )
21}
22
23pub fn make_world(ctx: &mut EventCtx, app: &App, neighbourhood: &Neighbourhood) -> World<Obj> {
24 let map = &app.per_map.map;
25 let mut world = World::new();
26
27 for r in neighbourhood
28 .interior_roads
29 .iter()
30 .chain(neighbourhood.perimeter_roads.iter())
31 {
32 let road = map.get_r(*r);
33 let s = road.speed_limit.to_miles_per_hour().round();
34
35 world
36 .add(Obj::Road(*r))
37 .hitbox(road.get_thick_polygon())
38 .draw_color(if s <= 10.0 {
39 colors::SPEED_LIMITS[0]
40 } else if s <= 20.0 {
41 colors::SPEED_LIMITS[1]
42 } else if s <= 30.0 {
43 colors::SPEED_LIMITS[2]
44 } else {
45 colors::SPEED_LIMITS[3]
46 })
47 .hover_color(colors::HOVER)
48 .tooltip(Text::from(format!(
49 "Current speed limit is {} ({})",
50 road.speed_limit.to_string(&UnitFmt::imperial()),
51 road.speed_limit.to_string(&UnitFmt::metric()),
52 )))
53 .clickable()
54 .build(ctx);
55 }
56
57 world.initialize_hover(ctx);
58 world
59}
60
61pub fn handle_world_outcome(app: &mut App, outcome: WorldOutcome<Obj>) -> EditOutcome {
62 match outcome {
63 WorldOutcome::ClickedObject(Obj::Road(r)) => {
64 if app.per_map.map.get_r(r).speed_limit == Speed::miles_per_hour(20.0) {
65 return EditOutcome::Nothing;
66 }
67
68 let mut edits = app.per_map.map.get_edits().clone();
69 edits.commands.push(app.per_map.map.edit_road_cmd(r, |new| {
70 new.speed_limit = Speed::miles_per_hour(20.0);
71 }));
72 app.apply_edits(edits);
73
74 EditOutcome::UpdateAll
75 }
76 _ => EditOutcome::Nothing,
77 }
78}