From d5653e42abfe5e01946d94ae6f47832422ea0946 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Fri, 17 Jan 2020 10:53:09 -0800 Subject: [PATCH] use info panel for finished trips --- game/src/common/info.rs | 20 +++-- game/src/common/mod.rs | 11 ++- game/src/common/trip_explorer.rs | 134 ------------------------------- game/src/debug/objects.rs | 4 +- game/src/helpers.rs | 6 +- game/src/sandbox/dashboards.rs | 14 +++- game/src/sandbox/mod.rs | 2 +- game/src/ui.rs | 9 ++- 8 files changed, 43 insertions(+), 157 deletions(-) delete mode 100644 game/src/common/trip_explorer.rs diff --git a/game/src/common/info.rs b/game/src/common/info.rs index ea6380703b..536c76ff1d 100644 --- a/game/src/common/info.rs +++ b/game/src/common/info.rs @@ -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 } diff --git a/game/src/common/mod.rs b/game/src/common/mod.rs index 54e62faa81..71c574291c 100644 --- a/game/src/common/mod.rs +++ b/game/src/common/mod.rs @@ -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; + } } diff --git a/game/src/common/trip_explorer.rs b/game/src/common/trip_explorer.rs deleted file mode 100644 index bbaaa68c83..0000000000 --- a/game/src/common/trip_explorer.rs +++ /dev/null @@ -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); - } -} diff --git a/game/src/debug/objects.rs b/game/src/debug/objects.rs index 479fcb9367..aec7de01eb 100644 --- a/game/src/debug/objects.rs +++ b/game/src/debug/objects.rs @@ -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!(), } } diff --git a/game/src/helpers.rs b/game/src/helpers.rs index 974a83a7df..044129618b 100644 --- a/game/src/helpers.rs +++ b/game/src/helpers.rs @@ -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(), } } } diff --git a/game/src/sandbox/dashboards.rs b/game/src/sandbox/dashboards.rs index 32dda6b441..73a563409a 100644 --- a/game/src/sandbox/dashboards.rs +++ b/game/src/sandbox/dashboards.rs @@ -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::() + .unwrap() + .common + .launch_info_panel(ID::Trip(trip), ctx, ui); + }))) }), )); } diff --git a/game/src/sandbox/mod.rs b/game/src/sandbox/mod.rs index 0631707309..8ad73f92ad 100644 --- a/game/src/sandbox/mod.rs +++ b/game/src/sandbox/mod.rs @@ -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, } diff --git a/game/src/ui.rs b/game/src/ui.rs index 6bb2c2b401..70123f6976 100644 --- a/game/src/ui.rs +++ b/game/src/ui.rs @@ -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), } }