mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
moving debug mode's tooltips into a popup info panel, hopefully the precursor to a sidebar
This commit is contained in:
parent
430b1245c4
commit
4df994a6c9
166
game/src/common/info.rs
Normal file
166
game/src/common/info.rs
Normal file
@ -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::<Vec<_>>()
|
||||
)));
|
||||
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<String, String>) {
|
||||
for (k, v) in tags {
|
||||
txt.add_appended(vec![
|
||||
Line(k).fg(Color::RED),
|
||||
Line(" = "),
|
||||
Line(v).fg(Color::CYAN),
|
||||
]);
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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<ID>,
|
||||
}
|
||||
|
||||
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::<Vec<StableRoadID>>()
|
||||
)));
|
||||
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<String, String>) {
|
||||
for (k, v) in tags {
|
||||
txt.add_appended(vec![
|
||||
Line(k).fg(Color::RED),
|
||||
Line(" = "),
|
||||
Line(v).fg(Color::CYAN),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ pub struct TrafficSignalDiagram {
|
||||
// The usizes are phase indices
|
||||
scroller: Scroller<usize>,
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user