From 4df994a6c91321d7f4949a391dd942b7eaaec36f Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Mon, 14 Oct 2019 13:42:22 -0700 Subject: [PATCH] moving debug mode's tooltips into a popup info panel, hopefully the precursor to a sidebar --- game/src/common/info.rs | 166 ++++++++++++++++++++++++++++++ game/src/common/mod.rs | 13 ++- game/src/debug/objects.rs | 151 +-------------------------- game/src/render/traffic_signal.rs | 4 +- 4 files changed, 182 insertions(+), 152 deletions(-) create mode 100644 game/src/common/info.rs diff --git a/game/src/common/info.rs b/game/src/common/info.rs new file mode 100644 index 0000000000..f0a75fe0a9 --- /dev/null +++ b/game/src/common/info.rs @@ -0,0 +1,166 @@ +use crate::common::CommonState; +use crate::game::{State, Transition}; +use crate::helpers::ID; +use crate::ui::UI; +use ezgui::{hotkey, Color, EventCtx, GfxCtx, Key, Line, ModalMenu, Text}; +use std::collections::BTreeMap; + +pub struct InfoPanel { + txt: Text, + menu: ModalMenu, +} + +impl InfoPanel { + pub fn new(id: ID, ui: &UI, ctx: &EventCtx) -> InfoPanel { + InfoPanel { + txt: info_for(id, ui, ctx), + menu: ModalMenu::new("Info Panel", vec![vec![(hotkey(Key::Escape), "quit")]], ctx), + } + } +} + +impl State for InfoPanel { + fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> Transition { + self.menu.event(ctx); + if self.menu.action("quit") { + Transition::Pop + } else { + Transition::Keep + } + } + + fn draw(&self, g: &mut GfxCtx, _: &UI) { + g.draw_blocking_text( + &self.txt, + ( + ezgui::HorizontalAlignment::Center, + ezgui::VerticalAlignment::Center, + ), + ); + self.menu.draw(g); + } +} + +fn info_for(id: ID, ui: &UI, ctx: &EventCtx) -> Text { + let (map, sim, draw_map) = (&ui.primary.map, &ui.primary.sim, &ui.primary.draw_map); + let mut txt = Text::new(); + // TODO Technically we should recalculate all of this as the window resizes, then. + txt.override_width = Some(0.7 * ctx.canvas.window_width); + txt.override_height = Some(0.7 * ctx.canvas.window_height); + + txt.extend(&CommonState::default_osd(id.clone(), ui)); + + match id { + ID::Road(_) => unreachable!(), + ID::Trip(_) => {} + ID::Lane(id) => { + let l = map.get_l(id); + let r = map.get_r(l.parent); + + txt.add_appended(vec![ + Line(format!("{} is ", l.id)), + Line(r.get_name()).fg(Color::CYAN), + ]); + txt.add(Line(format!( + "Parent {} (originally {}) points to {}", + r.id, r.stable_id, r.dst_i + ))); + txt.add(Line(format!( + "Lane is {} long, parent {} is {} long", + l.length(), + r.id, + r.center_pts.length() + ))); + styled_kv(&mut txt, &r.osm_tags); + if l.is_parking() { + txt.add(Line(format!( + "Has {} parking spots", + l.number_parking_spots() + ))); + } else if l.is_driving() { + txt.add(Line(format!( + "Parking blackhole redirect? {:?}", + l.parking_blackhole + ))); + } + if let Some(types) = l.get_turn_restrictions(r) { + txt.add(Line(format!("Turn restriction for this lane: {:?}", types))); + } + for (restriction, to) in &r.turn_restrictions { + txt.add(Line(format!( + "Restriction from this road to {}: {:?}", + to, restriction + ))); + } + } + ID::Intersection(id) => { + txt.add(Line(id.to_string())); + let i = map.get_i(id); + txt.add(Line(format!("Roads: {:?}", i.roads))); + txt.add(Line(format!( + "Orig roads: {:?}", + i.roads + .iter() + .map(|r| map.get_r(*r).stable_id) + .collect::>() + ))); + txt.add(Line(format!("Originally {}", i.stable_id))); + } + ID::Turn(id) => { + let t = map.get_t(id); + txt.add(Line(format!("{}", id))); + txt.add(Line(format!("{:?}", t.turn_type))); + } + ID::Building(id) => { + let b = map.get_b(id); + txt.add(Line(format!("Building #{:?}", id))); + txt.add(Line(format!( + "Dist along sidewalk: {}", + b.front_path.sidewalk.dist_along() + ))); + styled_kv(&mut txt, &b.osm_tags); + } + ID::Car(id) => { + for line in sim.car_tooltip(id) { + // TODO Wrap + txt.add(Line(line)); + } + } + ID::Pedestrian(id) => { + for line in sim.ped_tooltip(id) { + // TODO Wrap + txt.add(Line(line)); + } + } + ID::PedCrowd(members) => { + txt.add(Line(format!("Crowd of {}", members.len()))); + } + ID::ExtraShape(id) => { + styled_kv(&mut txt, &draw_map.get_es(id).attributes); + } + ID::BusStop(id) => { + txt.add(Line(id.to_string())); + for r in map.get_all_bus_routes() { + if r.stops.contains(&id) { + txt.add(Line(format!("- Route {}", r.name))); + } + } + } + ID::Area(id) => { + let a = map.get_a(id); + txt.add(Line(format!("{}", id))); + styled_kv(&mut txt, &a.osm_tags); + } + }; + txt +} + +fn styled_kv(txt: &mut Text, tags: &BTreeMap) { + for (k, v) in tags { + txt.add_appended(vec![ + Line(k).fg(Color::RED), + Line(" = "), + Line(v).fg(Color::CYAN), + ]); + } +} diff --git a/game/src/common/mod.rs b/game/src/common/mod.rs index 2bbec46c3a..46a9c5603b 100644 --- a/game/src/common/mod.rs +++ b/game/src/common/mod.rs @@ -1,6 +1,7 @@ mod agent; mod associated; mod colors; +mod info; mod navigate; mod route_explorer; mod route_viewer; @@ -25,7 +26,7 @@ use crate::helpers::ID; use crate::render::DrawOptions; use crate::ui::UI; use ezgui::{ - Color, EventCtx, EventLoopMode, GfxCtx, HorizontalAlignment, Line, ModalMenu, Text, + Color, EventCtx, EventLoopMode, GfxCtx, HorizontalAlignment, Key, Line, ModalMenu, Text, VerticalAlignment, }; use std::collections::BTreeSet; @@ -69,6 +70,16 @@ impl CommonState { )); } + if let Some(ref id) = ui.primary.current_selection { + if ctx.input.contextual_action(Key::I, "info") { + return Some(Transition::Push(Box::new(info::InfoPanel::new( + id.clone(), + ui, + ctx, + )))); + } + } + None } diff --git a/game/src/debug/objects.rs b/game/src/debug/objects.rs index 6b83185021..69434860e5 100644 --- a/game/src/debug/objects.rs +++ b/game/src/debug/objects.rs @@ -1,39 +1,22 @@ use crate::helpers::ID; use crate::render::DrawMap; -use crate::ui::PerMapUI; use crate::ui::UI; -use ezgui::{Color, EventCtx, GfxCtx, Key, Line, Text}; -use map_model::raw::StableRoadID; +use ezgui::{EventCtx, GfxCtx, Key, Line, Text}; use map_model::Map; use sim::{CarID, Sim}; -use std::collections::BTreeMap; pub struct ObjectDebugger { - tooltip_key_held: bool, debug_tooltip_key_held: bool, - selected: Option, } impl ObjectDebugger { pub fn new() -> ObjectDebugger { ObjectDebugger { - tooltip_key_held: false, debug_tooltip_key_held: false, - selected: None, } } pub fn event(&mut self, ctx: &mut EventCtx, ui: &UI) { - self.selected = ui.primary.current_selection.clone(); - if self.tooltip_key_held { - self.tooltip_key_held = !ctx.input.key_released(Key::LeftControl); - } else { - // TODO Can't really display an OSD action if we're not currently selecting something. - // Could only activate sometimes, but that seems a bit harder to use. - self.tooltip_key_held = ctx - .input - .unimportant_key_pressed(Key::LeftControl, "hold to show tooltips"); - } if self.debug_tooltip_key_held { self.debug_tooltip_key_held = !ctx.input.key_released(Key::RightControl); } else { @@ -42,7 +25,7 @@ impl ObjectDebugger { .unimportant_key_pressed(Key::RightControl, "hold to show debug tooltips"); } - if let Some(ref id) = self.selected { + if let Some(ref id) = ui.primary.current_selection { if ctx.input.contextual_action(Key::D, "debug") { dump_debug( id.clone(), @@ -55,13 +38,6 @@ impl ObjectDebugger { } pub fn draw(&self, g: &mut GfxCtx, ui: &UI) { - if self.tooltip_key_held { - if let Some(ref id) = self.selected { - let txt = tooltip_lines(id.clone(), g, &ui.primary); - g.draw_mouse_tooltip(&txt); - } - } - if self.debug_tooltip_key_held { if let Some(pt) = g.canvas.get_cursor_in_map_space() { if let Some(gps) = pt.to_gps(ui.primary.map.get_gps_bounds()) { @@ -142,126 +118,3 @@ fn dump_debug(id: ID, map: &Map, sim: &Sim, draw_map: &DrawMap) { } } } - -fn tooltip_lines(id: ID, g: &mut GfxCtx, ctx: &PerMapUI) -> Text { - let (map, sim, draw_map) = (&ctx.map, &ctx.sim, &ctx.draw_map); - let mut txt = Text::new(); - match id { - ID::Road(id) => { - let r = map.get_r(id); - txt.add_appended(vec![ - Line(format!("{} (originally {}) is ", r.id, r.stable_id)), - Line(r.get_name()).fg(Color::CYAN), - ]); - txt.add(Line(format!("From OSM way {}", r.osm_way_id))); - } - ID::Lane(id) => { - let l = map.get_l(id); - let r = map.get_r(l.parent); - - txt.add_appended(vec![ - Line(format!("{} is ", l.id)), - Line(r.get_name()).fg(Color::CYAN), - ]); - txt.add(Line(format!( - "Parent {} (originally {}) points to {}", - r.id, r.stable_id, r.dst_i - ))); - txt.add(Line(format!( - "Lane is {} long, parent {} is {} long", - l.length(), - r.id, - r.center_pts.length() - ))); - styled_kv(&mut txt, &r.osm_tags); - if l.is_parking() { - txt.add(Line(format!( - "Has {} parking spots", - l.number_parking_spots() - ))); - } else if l.is_driving() { - txt.add(Line(format!( - "Parking blackhole redirect? {:?}", - l.parking_blackhole - ))); - } - if let Some(types) = l.get_turn_restrictions(r) { - txt.add(Line(format!("Turn restriction for this lane: {:?}", types))); - } - for (restriction, to) in &r.turn_restrictions { - txt.add(Line(format!( - "Restriction from this road to {}: {:?}", - to, restriction - ))); - } - } - ID::Intersection(id) => { - txt.add(Line(id.to_string())); - let i = map.get_i(id); - txt.add(Line(format!("Roads: {:?}", i.roads))); - txt.add(Line(format!( - "Orig roads: {:?}", - i.roads - .iter() - .map(|r| map.get_r(*r).stable_id) - .collect::>() - ))); - txt.add(Line(format!("Originally {}", i.stable_id))); - } - ID::Turn(id) => { - let t = map.get_t(id); - txt.add(Line(format!("{}", id))); - txt.add(Line(format!("{:?}", t.turn_type))); - } - ID::Building(id) => { - let b = map.get_b(id); - txt.add(Line(format!("Building #{:?}", id))); - txt.add(Line(format!( - "Dist along sidewalk: {}", - b.front_path.sidewalk.dist_along() - ))); - styled_kv(&mut txt, &b.osm_tags); - } - ID::Car(id) => { - for line in sim.car_tooltip(id) { - txt.add_wrapped_line(&g.canvas, line); - } - } - ID::Pedestrian(id) => { - for line in sim.ped_tooltip(id) { - txt.add_wrapped_line(&g.canvas, line); - } - } - ID::PedCrowd(members) => { - txt.add(Line(format!("Crowd of {}", members.len()))); - } - ID::ExtraShape(id) => { - styled_kv(&mut txt, &draw_map.get_es(id).attributes); - } - ID::BusStop(id) => { - txt.add(Line(id.to_string())); - for r in map.get_all_bus_routes() { - if r.stops.contains(&id) { - txt.add(Line(format!("- Route {}", r.name))); - } - } - } - ID::Area(id) => { - let a = map.get_a(id); - txt.add(Line(format!("{}", id))); - styled_kv(&mut txt, &a.osm_tags); - } - ID::Trip(_) => {} - }; - txt -} - -fn styled_kv(txt: &mut Text, tags: &BTreeMap) { - for (k, v) in tags { - txt.add_appended(vec![ - Line(k).fg(Color::RED), - Line(" = "), - Line(v).fg(Color::CYAN), - ]); - } -} diff --git a/game/src/render/traffic_signal.rs b/game/src/render/traffic_signal.rs index 7b57ba64da..a5b0bf8cd6 100644 --- a/game/src/render/traffic_signal.rs +++ b/game/src/render/traffic_signal.rs @@ -233,7 +233,7 @@ pub struct TrafficSignalDiagram { // The usizes are phase indices scroller: Scroller, - new_scroller: NewScroller, + _new_scroller: NewScroller, } impl TrafficSignalDiagram { @@ -290,7 +290,7 @@ impl TrafficSignalDiagram { intersection_width, scroller, - new_scroller: make_new_scroller(i, &ui.draw_ctx(), ctx), + _new_scroller: make_new_scroller(i, &ui.draw_ctx(), ctx), } }