ltn/pages/design_ltn/
speed_limits.rs

1use 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}