game/sandbox/dashboards/
generic_trip_table.rs
1use geom::{Distance, Pt2D};
2use sim::TripID;
3use synthpop::TripEndpoint;
4use widgetry::{Drawable, GeomBatch, GfxCtx, Panel, ScreenPt};
5
6use crate::app::{App, Transition};
7use crate::common::color_for_trip_phase;
8use crate::info::{OpenTrip, Tab};
9use crate::sandbox::SandboxMode;
10
11pub(crate) fn open_trip_transition(app: &App, idx: usize) -> Transition {
12 let trip = TripID(idx);
13 let person = app.primary.sim.trip_to_person(trip).unwrap();
14
15 Transition::Multi(vec![
16 Transition::Pop,
17 Transition::ModifyState(Box::new(move |state, ctx, app| {
18 let sandbox = state.downcast_mut::<SandboxMode>().unwrap();
19 let mut actions = sandbox.contextual_actions();
20 sandbox.controls.common.as_mut().unwrap().launch_info_panel(
21 ctx,
22 app,
23 Tab::PersonTrips(person, OpenTrip::single(trip)),
24 &mut actions,
25 );
26 })),
27 ])
28}
29
30pub(crate) fn preview_trip(
31 g: &mut GfxCtx,
32 app: &App,
33 panel: &Panel,
34 mut batch: GeomBatch,
35 draw_extra: Option<&Drawable>,
36) {
37 let inner_rect = panel.rect_of("preview").clone();
38 let map_bounds = *app.primary.map.get_bounds();
39 let zoom = 0.15 * g.canvas.window_width / map_bounds.width().max(map_bounds.height());
40 g.fork(
41 Pt2D::new(map_bounds.min_x, map_bounds.min_y),
42 ScreenPt::new(inner_rect.x1, inner_rect.y1),
43 zoom,
44 None,
45 );
46 g.enable_clipping(inner_rect);
47
48 g.redraw(&app.primary.draw_map.boundary_polygon);
49 g.redraw(&app.primary.draw_map.draw_all_areas);
50 g.redraw(
51 &app.primary
52 .draw_map
53 .draw_all_unzoomed_roads_and_intersections,
54 );
55
56 if let Some(x) = panel.currently_hovering() {
57 if let Ok(idx) = x.parse::<usize>() {
58 let trip = TripID(idx);
59 preview_route(g, app, trip, &mut batch);
60 }
61 }
62 batch.draw(g);
63 if let Some(draw) = draw_extra {
64 g.redraw(draw);
65 }
66
67 g.disable_clipping();
68 g.unfork();
69}
70
71fn preview_route(g: &mut GfxCtx, app: &App, id: TripID, batch: &mut GeomBatch) {
72 for p in app
73 .primary
74 .sim
75 .get_analytics()
76 .get_trip_phases(id, &app.primary.map)
77 {
78 if let Some(path) = &p.path {
79 if let Some(trace) = path.trace(&app.primary.map) {
80 batch.push(
81 color_for_trip_phase(app, p.phase_type),
82 trace.make_polygons(Distance::meters(20.0)),
83 );
84 }
85 }
86 }
87
88 let trip = app.primary.sim.trip_info(id);
89 batch.append(map_gui::tools::start_marker(
90 g,
91 match trip.start {
92 TripEndpoint::Building(b) => app.primary.map.get_b(b).label_center,
93 TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
94 TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
95 },
96 5.0,
97 ));
98 batch.append(map_gui::tools::goal_marker(
99 g,
100 match trip.end {
101 TripEndpoint::Building(b) => app.primary.map.get_b(b).label_center,
102 TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
103 TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
104 },
105 5.0,
106 ));
107}