mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-20 12:51:57 +03:00
use info panel for finished trips
This commit is contained in:
parent
b6d7acd385
commit
d5653e42ab
@ -98,14 +98,16 @@ impl InfoPanel {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let trip_details =
|
||||
if let Some(trip) = id.agent_id().and_then(|a| ui.primary.sim.agent_to_trip(a)) {
|
||||
let (rows, unzoomed, zoomed) = trip_details(trip, ctx, ui);
|
||||
col.push(rows);
|
||||
Some((unzoomed, zoomed))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let trip_details = if let Some(trip) = match id {
|
||||
ID::Trip(t) => Some(t),
|
||||
_ => id.agent_id().and_then(|a| ui.primary.sim.agent_to_trip(a)),
|
||||
} {
|
||||
let (rows, unzoomed, zoomed) = trip_details(trip, ctx, ui);
|
||||
col.push(rows);
|
||||
Some((unzoomed, zoomed))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Follow the agent. When the sim is paused, this lets the player naturally pan away,
|
||||
// because the InfoPanel isn't being updated.
|
||||
@ -374,6 +376,8 @@ fn info_for(id: ID, ui: &UI) -> Text {
|
||||
let a = map.get_a(id);
|
||||
styled_kv(&mut txt, &a.osm_tags);
|
||||
}
|
||||
// No info here, trip_details will be used
|
||||
ID::Trip(_) => {}
|
||||
};
|
||||
txt
|
||||
}
|
||||
|
@ -4,14 +4,12 @@ mod minimap;
|
||||
mod navigate;
|
||||
mod panels;
|
||||
mod shortcuts;
|
||||
mod trip_explorer;
|
||||
mod turn_cycler;
|
||||
mod warp;
|
||||
|
||||
pub use self::colors::{ColorLegend, Colorer, ColorerBuilder};
|
||||
pub use self::minimap::Minimap;
|
||||
pub use self::panels::{edit_map_panel, tool_panel};
|
||||
pub use self::trip_explorer::TripExplorer;
|
||||
pub use self::warp::Warping;
|
||||
use crate::game::Transition;
|
||||
use crate::helpers::{list_names, ID};
|
||||
@ -182,6 +180,9 @@ impl CommonState {
|
||||
.collect();
|
||||
list_names(&mut osd, |l| l.fg(name_color), routes);
|
||||
}
|
||||
ID::Trip(t) => {
|
||||
osd.append(Line(t.to_string()).fg(id_color));
|
||||
}
|
||||
ID::ExtraShape(es) => {
|
||||
// Only selectable in dev mode anyway
|
||||
osd.append(Line(es.to_string()).fg(id_color));
|
||||
@ -238,4 +239,10 @@ impl CommonState {
|
||||
.suppress_traffic_signal_details(&ui.primary.map);
|
||||
opts
|
||||
}
|
||||
|
||||
// Meant to be used for launching from other states
|
||||
pub fn launch_info_panel(&mut self, id: ID, ctx: &mut EventCtx, ui: &mut UI) {
|
||||
self.info_panel = Some(info::InfoPanel::new(id, ctx, ui, Vec::new()));
|
||||
ui.per_obj.info_panel_open = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,134 +0,0 @@
|
||||
use crate::common::ColorLegend;
|
||||
use crate::game::{State, Transition};
|
||||
use crate::helpers::rotating_color_map;
|
||||
use crate::render::MIN_ZOOM_FOR_DETAIL;
|
||||
use crate::ui::UI;
|
||||
use ezgui::{hotkey, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, ModalMenu, Text};
|
||||
use geom::{Circle, Distance};
|
||||
use sim::{TripEnd, TripID, TripStart};
|
||||
|
||||
pub struct TripExplorer {
|
||||
menu: ModalMenu,
|
||||
unzoomed: Drawable,
|
||||
zoomed: Drawable,
|
||||
legend: ColorLegend,
|
||||
}
|
||||
|
||||
impl TripExplorer {
|
||||
pub fn new(trip: TripID, ctx: &mut EventCtx, ui: &UI) -> TripExplorer {
|
||||
let map = &ui.primary.map;
|
||||
let phases = ui.primary.sim.get_analytics().get_trip_phases(trip, map);
|
||||
// TODO Hack because ColorLegend only takes &str
|
||||
let mut rows = Vec::new();
|
||||
for (idx, p) in phases.iter().enumerate() {
|
||||
rows.push((
|
||||
p.describe(ui.primary.sim.time()),
|
||||
rotating_color_map(idx + 1),
|
||||
));
|
||||
}
|
||||
let mut unzoomed = GeomBatch::new();
|
||||
let mut zoomed = GeomBatch::new();
|
||||
for (p, (_, color)) in phases.iter().zip(rows.iter()) {
|
||||
if let Some((dist, ref path)) = p.path {
|
||||
if let Some(t) = path.trace(map, dist, None) {
|
||||
unzoomed.push(*color, t.make_polygons(Distance::meters(10.0)));
|
||||
zoomed.push(*color, t.make_polygons(Distance::meters(1.0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle endpoints
|
||||
let (trip_start, trip_end) = ui.primary.sim.trip_endpoints(trip);
|
||||
let start_color = rotating_color_map(0);
|
||||
match trip_start {
|
||||
TripStart::Bldg(b) => {
|
||||
let bldg = map.get_b(b);
|
||||
rows.insert(0, (format!("start at {}", bldg.get_name(map)), start_color));
|
||||
unzoomed.push(start_color, bldg.polygon.clone());
|
||||
zoomed.push(start_color, bldg.polygon.clone());
|
||||
}
|
||||
TripStart::Border(i) => {
|
||||
let i = map.get_i(i);
|
||||
rows.insert(0, (format!("enter map via {}", i.id), start_color));
|
||||
unzoomed.push(start_color, i.polygon.clone());
|
||||
zoomed.push(start_color, i.polygon.clone());
|
||||
}
|
||||
};
|
||||
|
||||
// Is the trip ongoing?
|
||||
if let Some(pt) = ui.primary.sim.get_canonical_pt_per_trip(trip, map).ok() {
|
||||
let color = rotating_color_map(rows.len());
|
||||
unzoomed.push(color, Circle::new(pt, Distance::meters(10.0)).to_polygon());
|
||||
zoomed.push(
|
||||
color.alpha(0.7),
|
||||
Circle::new(pt, Distance::meters(5.0)).to_polygon(),
|
||||
);
|
||||
rows.push((format!("currently here"), color));
|
||||
}
|
||||
|
||||
let end_color = rotating_color_map(rows.len());
|
||||
match trip_end {
|
||||
TripEnd::Bldg(b) => {
|
||||
let bldg = map.get_b(b);
|
||||
rows.push((format!("end at {}", bldg.get_name(map)), end_color));
|
||||
unzoomed.push(end_color, bldg.polygon.clone());
|
||||
zoomed.push(end_color, bldg.polygon.clone());
|
||||
}
|
||||
TripEnd::Border(i) => {
|
||||
let i = map.get_i(i);
|
||||
rows.push((format!("leave map via {}", i.id), end_color));
|
||||
unzoomed.push(end_color, i.polygon.clone());
|
||||
zoomed.push(end_color, i.polygon.clone());
|
||||
}
|
||||
// TODO TripExplorer is pretty useless for buses; maybe ShowBusRoute or something
|
||||
// instead
|
||||
TripEnd::ServeBusRoute(br) => {
|
||||
rows.push((
|
||||
format!("serve route {} forever", map.get_br(br).name),
|
||||
end_color,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let legend = ColorLegend::new(
|
||||
ctx,
|
||||
Text::from(Line(&trip.to_string())),
|
||||
rows.iter()
|
||||
.map(|(label, color)| (label.as_str(), *color))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
TripExplorer {
|
||||
menu: ModalMenu::new(trip.to_string(), vec![(hotkey(Key::Escape), "quit")], ctx),
|
||||
legend,
|
||||
unzoomed: unzoomed.upload(ctx),
|
||||
zoomed: zoomed.upload(ctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl State for TripExplorer {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition {
|
||||
if ctx.redo_mouseover() {
|
||||
ui.recalculate_current_selection(ctx);
|
||||
}
|
||||
ctx.canvas_movement();
|
||||
|
||||
self.menu.event(ctx);
|
||||
if self.menu.action("quit") {
|
||||
return Transition::Pop;
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
if g.canvas.cam_zoom < MIN_ZOOM_FOR_DETAIL {
|
||||
g.redraw(&self.unzoomed);
|
||||
} else {
|
||||
g.redraw(&self.zoomed);
|
||||
}
|
||||
self.legend.draw(g);
|
||||
self.menu.draw(g);
|
||||
}
|
||||
}
|
@ -55,9 +55,6 @@ impl ObjectDebugger {
|
||||
|
||||
fn dump_debug(id: ID, map: &Map, sim: &Sim, draw_map: &DrawMap) {
|
||||
match id {
|
||||
ID::Road(id) => {
|
||||
println!("{}", abstutil::to_json(map.get_r(id)));
|
||||
}
|
||||
ID::Lane(id) => {
|
||||
let l = map.get_l(id);
|
||||
println!("{}", abstutil::to_json(l));
|
||||
@ -155,5 +152,6 @@ fn dump_debug(id: ID, map: &Map, sim: &Sim, draw_map: &DrawMap) {
|
||||
ID::Area(id) => {
|
||||
println!("{}", abstutil::to_json(map.get_a(id)));
|
||||
}
|
||||
ID::Road(_) | ID::Trip(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,11 @@ use ezgui::{Color, Line, Text, TextSpan};
|
||||
use geom::Pt2D;
|
||||
use map_model::{AreaID, BuildingID, BusStopID, IntersectionID, LaneID, RoadID, TurnID};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sim::{AgentID, CarID, PedestrianID};
|
||||
use sim::{AgentID, CarID, PedestrianID, TripID};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||
use std::fmt::Write;
|
||||
|
||||
// Aside from Road, everything here can actually be selected.
|
||||
// Aside from Road and Trip, everything here can actually be selected.
|
||||
#[derive(Clone, Hash, PartialEq, Eq, Debug, PartialOrd, Ord)]
|
||||
pub enum ID {
|
||||
Road(RoadID),
|
||||
@ -23,6 +23,7 @@ pub enum ID {
|
||||
ExtraShape(ExtraShapeID),
|
||||
BusStop(BusStopID),
|
||||
Area(AreaID),
|
||||
Trip(TripID),
|
||||
}
|
||||
|
||||
impl abstutil::Cloneable for ID {}
|
||||
@ -70,6 +71,7 @@ impl ID {
|
||||
.maybe_get_bs(id)
|
||||
.map(|bs| bs.sidewalk_pos.pt(&primary.map)),
|
||||
ID::Area(id) => primary.map.maybe_get_a(id).map(|a| a.polygon.center()),
|
||||
ID::Trip(id) => primary.sim.get_canonical_pt_per_trip(id, &primary.map).ok(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::common::TripExplorer;
|
||||
use crate::game::{State, Transition};
|
||||
use crate::helpers::ID;
|
||||
use crate::managed::{Callback, Composite, ManagedGUIState};
|
||||
use crate::sandbox::bus_explorer;
|
||||
use crate::sandbox::gameplay::{cmp_count_fewer, cmp_count_more, cmp_duration_shorter};
|
||||
use crate::sandbox::{bus_explorer, SandboxMode};
|
||||
use crate::ui::UI;
|
||||
use abstutil::prettyprint_usize;
|
||||
use abstutil::Counter;
|
||||
@ -262,8 +262,14 @@ fn pick_finished_trips(
|
||||
let trip = *id;
|
||||
cbs.push((
|
||||
label,
|
||||
Box::new(move |ctx, ui| {
|
||||
Some(Transition::Push(Box::new(TripExplorer::new(trip, ctx, ui))))
|
||||
Box::new(move |_, _| {
|
||||
Some(Transition::PopWithData(Box::new(move |state, ui, ctx| {
|
||||
state
|
||||
.downcast_mut::<SandboxMode>()
|
||||
.unwrap()
|
||||
.common
|
||||
.launch_info_panel(ID::Trip(trip), ctx, ui);
|
||||
})))
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ pub struct SandboxMode {
|
||||
agent_meter: AgentMeter,
|
||||
overlay: Overlays,
|
||||
gameplay: gameplay::GameplayRunner,
|
||||
common: CommonState,
|
||||
pub common: CommonState,
|
||||
tool_panel: crate::managed::Composite,
|
||||
minimap: Option<Minimap>,
|
||||
}
|
||||
|
@ -323,9 +323,12 @@ impl UI {
|
||||
ID::Building(id) => buildings.push(draw_map.get_b(id)),
|
||||
ID::ExtraShape(id) => extra_shapes.push(draw_map.get_es(id)),
|
||||
|
||||
ID::BusStop(_) | ID::Turn(_) | ID::Car(_) | ID::Pedestrian(_) | ID::PedCrowd(_) => {
|
||||
panic!("{:?} shouldn't be in the quadtree", id)
|
||||
}
|
||||
ID::BusStop(_)
|
||||
| ID::Turn(_)
|
||||
| ID::Car(_)
|
||||
| ID::Pedestrian(_)
|
||||
| ID::PedCrowd(_)
|
||||
| ID::Trip(_) => panic!("{:?} shouldn't be in the quadtree", id),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user