ltn/pages/design_ltn/
one_ways.rs1use osm2streets::LaneSpec;
2use widgetry::mapspace::{World, WorldOutcome};
3use widgetry::{EventCtx, Text};
4
5use super::{road_name, EditOutcome, Obj};
6use crate::render::colors;
7use crate::{App, Neighbourhood};
8
9pub fn make_world(ctx: &mut EventCtx, app: &App, neighbourhood: &Neighbourhood) -> World<Obj> {
10 let map = &app.per_map.map;
11 let mut world = World::new();
12
13 for r in &neighbourhood.interior_roads {
14 let road = map.get_r(*r);
15 world
16 .add(Obj::Road(*r))
17 .hitbox(road.get_thick_polygon())
18 .drawn_in_master_batch()
19 .hover_color(colors::HOVER)
20 .tooltip(Text::from(format!(
21 "Click to flip direction of {}",
22 road_name(app, road)
23 )))
24 .clickable()
25 .build(ctx);
26 }
27
28 world.initialize_hover(ctx);
29 world
30}
31
32pub fn handle_world_outcome(
33 ctx: &mut EventCtx,
34 app: &mut App,
35 outcome: WorldOutcome<Obj>,
36) -> EditOutcome {
37 match outcome {
38 WorldOutcome::ClickedObject(Obj::Road(r)) => {
39 if app.per_map.map.get_r(r).modal_filter.is_some() {
40 return EditOutcome::error(ctx, "A one-way street can't have a filter");
41 }
42 if app
43 .per_map
44 .map
45 .get_r(r)
46 .is_deadend_for_driving(&app.per_map.map)
47 {
48 return EditOutcome::error(ctx, "A dead-end street can't be one-way");
49 }
50
51 let driving_side = app.per_map.map.get_config().driving_side;
52 let mut edits = app.per_map.map.get_edits().clone();
53 edits.commands.push(app.per_map.map.edit_road_cmd(r, |new| {
54 LaneSpec::toggle_road_direction(&mut new.lanes_ltr, driving_side);
55 }));
56 app.apply_edits(edits);
57
58 EditOutcome::UpdateAll
59 }
60 _ => EditOutcome::Nothing,
61 }
62}