mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-05 04:52:16 +03:00
nicer API for appending bits of text
This commit is contained in:
parent
95545863fc
commit
1248dac270
@ -305,9 +305,11 @@ impl UserInput {
|
|||||||
|
|
||||||
pub fn populate_osd(&mut self, osd: &mut Text) {
|
pub fn populate_osd(&mut self, osd: &mut Text) {
|
||||||
for (key, a) in self.important_actions.drain(..) {
|
for (key, a) in self.important_actions.drain(..) {
|
||||||
osd.add(Line("Press "));
|
osd.add_appended(vec![
|
||||||
osd.append(Line(key.describe()).fg(text::HOTKEY_COLOR));
|
Line("Press "),
|
||||||
osd.append(Line(format!(" to {}", a)));
|
Line(key.describe()).fg(text::HOTKEY_COLOR),
|
||||||
|
Line(format!(" to {}", a)),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +120,23 @@ impl Text {
|
|||||||
self.lines.last_mut().unwrap().1.push(line);
|
self.lines.last_mut().unwrap().1.push(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_appended(&mut self, lines: Vec<TextSpan>) {
|
||||||
|
assert!(lines.len() > 1);
|
||||||
|
for (idx, l) in lines.into_iter().enumerate() {
|
||||||
|
if idx == 0 {
|
||||||
|
self.add(l);
|
||||||
|
} else {
|
||||||
|
self.append(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append_all(&mut self, lines: Vec<TextSpan>) {
|
||||||
|
for l in lines {
|
||||||
|
self.append(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Ideally we'd wrap last-minute when drawing, but eh, start somewhere.
|
// TODO Ideally we'd wrap last-minute when drawing, but eh, start somewhere.
|
||||||
pub fn add_wrapped_line(&mut self, canvas: &Canvas, line: String) {
|
pub fn add_wrapped_line(&mut self, canvas: &Canvas, line: String) {
|
||||||
let wrap_to = canvas.window_width / MAX_CHAR_WIDTH;
|
let wrap_to = canvas.window_width / MAX_CHAR_WIDTH;
|
||||||
|
@ -59,9 +59,11 @@ impl<T: Clone + Hash + Eq> Autocomplete<T> {
|
|||||||
txt.add(Line(&self.line[0..self.cursor_x]));
|
txt.add(Line(&self.line[0..self.cursor_x]));
|
||||||
if self.cursor_x < self.line.len() {
|
if self.cursor_x < self.line.len() {
|
||||||
// TODO This "cursor" looks awful!
|
// TODO This "cursor" looks awful!
|
||||||
txt.append(Line("|").fg(text::SELECTED_COLOR));
|
txt.append_all(vec![
|
||||||
txt.append(Line(&self.line[self.cursor_x..=self.cursor_x]));
|
Line("|").fg(text::SELECTED_COLOR),
|
||||||
txt.append(Line(&self.line[self.cursor_x + 1..]));
|
Line(&self.line[self.cursor_x..=self.cursor_x]),
|
||||||
|
Line(&self.line[self.cursor_x + 1..]),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
txt.append(Line("|").fg(text::SELECTED_COLOR));
|
txt.append(Line("|").fg(text::SELECTED_COLOR));
|
||||||
}
|
}
|
||||||
|
@ -338,8 +338,10 @@ impl<T: Clone> Menu<T> {
|
|||||||
txt.override_width = Some(self.total_width);
|
txt.override_width = Some(self.total_width);
|
||||||
if choice.active {
|
if choice.active {
|
||||||
if let Some(key) = choice.hotkey {
|
if let Some(key) = choice.hotkey {
|
||||||
txt.add(Line(key.describe()).fg(text::HOTKEY_COLOR));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(format!(" - {}", choice.label)));
|
Line(key.describe()).fg(text::HOTKEY_COLOR),
|
||||||
|
Line(format!(" - {}", choice.label)),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
txt.add(Line(&choice.label));
|
txt.add(Line(&choice.label));
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,11 @@ impl TextBox {
|
|||||||
txt.add(Line(&self.line[0..self.cursor_x]));
|
txt.add(Line(&self.line[0..self.cursor_x]));
|
||||||
if self.cursor_x < self.line.len() {
|
if self.cursor_x < self.line.len() {
|
||||||
// TODO This "cursor" looks awful!
|
// TODO This "cursor" looks awful!
|
||||||
txt.append(Line("|").fg(text::SELECTED_COLOR));
|
txt.append_all(vec![
|
||||||
txt.append(Line(&self.line[self.cursor_x..=self.cursor_x]));
|
Line("|").fg(text::SELECTED_COLOR),
|
||||||
txt.append(Line(&self.line[self.cursor_x + 1..]));
|
Line(&self.line[self.cursor_x..=self.cursor_x]),
|
||||||
|
Line(&self.line[self.cursor_x + 1..]),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
txt.append(Line("|").fg(text::SELECTED_COLOR));
|
txt.append(Line("|").fg(text::SELECTED_COLOR));
|
||||||
}
|
}
|
||||||
|
@ -82,32 +82,38 @@ impl GUI for UI {
|
|||||||
|
|
||||||
let len = self.hints.hints.len();
|
let len = self.hints.hints.len();
|
||||||
let mut txt = Text::prompt("Fix Map Geometry");
|
let mut txt = Text::prompt("Fix Map Geometry");
|
||||||
txt.add(Line(len.to_string()).fg(Color::CYAN));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" hints, "));
|
Line(len.to_string()).fg(Color::CYAN),
|
||||||
txt.append(
|
Line(" hints, "),
|
||||||
Line(self.hints.parking_overrides.len().to_string()).fg(Color::CYAN),
|
Line(self.hints.parking_overrides.len().to_string()).fg(Color::CYAN),
|
||||||
);
|
Line(" parking overrides"),
|
||||||
txt.append(Line(" parking overrides"));
|
]);
|
||||||
if let Some(ID::Road(r)) = self.world.get_selection() {
|
if let Some(ID::Road(r)) = self.world.get_selection() {
|
||||||
txt.add(Line(r.to_string()).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(format!(
|
Line(r.to_string()).fg(Color::RED),
|
||||||
" is {} long",
|
Line(format!(
|
||||||
self.data.roads[&r].trimmed_center_pts.length()
|
" is {} long",
|
||||||
)));
|
self.data.roads[&r].trimmed_center_pts.length()
|
||||||
|
)),
|
||||||
|
]);
|
||||||
if self.data.roads[&r].has_parking() {
|
if self.data.roads[&r].has_parking() {
|
||||||
txt.add(Line("Has parking"));
|
txt.add(Line("Has parking"));
|
||||||
} else {
|
} else {
|
||||||
txt.add(Line("No parking"));
|
txt.add(Line("No parking"));
|
||||||
}
|
}
|
||||||
for (k, v) in &self.raw.roads[&r].osm_tags {
|
for (k, v) in &self.raw.roads[&r].osm_tags {
|
||||||
txt.add(Line(k).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" = "));
|
Line(k).fg(Color::RED),
|
||||||
txt.append(Line(v).fg(Color::CYAN));
|
Line(" = "),
|
||||||
|
Line(v).fg(Color::CYAN),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ID::Intersection(i)) = self.world.get_selection() {
|
if let Some(ID::Intersection(i)) = self.world.get_selection() {
|
||||||
txt.add(Line(i.to_string()).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" OSM tag diffs:"));
|
Line(i.to_string()).fg(Color::RED),
|
||||||
|
Line(" OSM tag diffs:"),
|
||||||
|
]);
|
||||||
let roads = &self.data.intersections[&i].roads;
|
let roads = &self.data.intersections[&i].roads;
|
||||||
if roads.len() == 2 {
|
if roads.len() == 2 {
|
||||||
let mut iter = roads.iter();
|
let mut iter = roads.iter();
|
||||||
@ -117,27 +123,33 @@ impl GUI for UI {
|
|||||||
for (k, v1) in r1_tags {
|
for (k, v1) in r1_tags {
|
||||||
if let Some(v2) = r2_tags.get(k) {
|
if let Some(v2) = r2_tags.get(k) {
|
||||||
if v1 != v2 {
|
if v1 != v2 {
|
||||||
txt.add(Line(k).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" = "));
|
Line(k).fg(Color::RED),
|
||||||
txt.append(Line(v1).fg(Color::CYAN));
|
Line(" = "),
|
||||||
txt.append(Line(" / "));
|
Line(v1).fg(Color::CYAN),
|
||||||
txt.append(Line(v2).fg(Color::CYAN));
|
Line(" / "),
|
||||||
|
Line(v2).fg(Color::CYAN),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
txt.add(Line(k).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" = "));
|
Line(k).fg(Color::RED),
|
||||||
txt.append(Line(v1).fg(Color::CYAN));
|
Line(" = "),
|
||||||
txt.append(Line(" / "));
|
Line(v1).fg(Color::CYAN),
|
||||||
txt.append(Line("MISSING").fg(Color::CYAN));
|
Line(" / "),
|
||||||
|
Line("MISSING").fg(Color::CYAN),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (k, v2) in r2_tags {
|
for (k, v2) in r2_tags {
|
||||||
if !r1_tags.contains_key(k) {
|
if !r1_tags.contains_key(k) {
|
||||||
txt.add(Line(k).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" = "));
|
Line(k).fg(Color::RED),
|
||||||
txt.append(Line("MISSING").fg(Color::CYAN));
|
Line(" = "),
|
||||||
txt.append(Line(" / "));
|
Line("MISSING").fg(Color::CYAN),
|
||||||
txt.append(Line(v2).fg(Color::CYAN));
|
Line(" / "),
|
||||||
|
Line(v2).fg(Color::CYAN),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,17 +30,21 @@ impl Scoreboard {
|
|||||||
let t2 = secondary.sim.get_finished_trips();
|
let t2 = secondary.sim.get_finished_trips();
|
||||||
|
|
||||||
let mut summary = Text::new();
|
let mut summary = Text::new();
|
||||||
summary.add(Line("Score at "));
|
summary.add_appended(vec![
|
||||||
summary.append(Line(primary.sim.time().to_string()).fg(Color::RED));
|
Line("Score at "),
|
||||||
summary.append(Line(format!(
|
Line(primary.sim.time().to_string()).fg(Color::RED),
|
||||||
"... {} / {}",
|
Line(format!(
|
||||||
primary.map.get_edits().edits_name,
|
"... {} / {}",
|
||||||
secondary.map.get_edits().edits_name
|
primary.map.get_edits().edits_name,
|
||||||
)));
|
secondary.map.get_edits().edits_name
|
||||||
summary.add(Line(prettyprint_usize(t1.unfinished_trips)).fg(Color::CYAN));
|
)),
|
||||||
summary.append(Line(" | "));
|
]);
|
||||||
summary.append(Line(prettyprint_usize(t2.unfinished_trips)).fg(Color::RED));
|
summary.add_appended(vec![
|
||||||
summary.append(Line(" unfinished trips"));
|
Line(prettyprint_usize(t1.unfinished_trips)).fg(Color::CYAN),
|
||||||
|
Line(" | "),
|
||||||
|
Line(prettyprint_usize(t2.unfinished_trips)).fg(Color::RED),
|
||||||
|
Line(" unfinished trips"),
|
||||||
|
]);
|
||||||
|
|
||||||
let cmp = CompareTrips::new(t1, t2);
|
let cmp = CompareTrips::new(t1, t2);
|
||||||
for (mode, trips) in &cmp
|
for (mode, trips) in &cmp
|
||||||
@ -64,29 +68,33 @@ impl Scoreboard {
|
|||||||
deltas.sort();
|
deltas.sort();
|
||||||
let len = deltas.len() as f64;
|
let len = deltas.len() as f64;
|
||||||
|
|
||||||
summary.add(Line(format!("{:?}", mode)).fg(Color::CYAN));
|
summary.add_appended(vec![
|
||||||
summary.append(Line(format!(
|
Line(format!("{:?}", mode)).fg(Color::CYAN),
|
||||||
" trips: {} same, {} different",
|
Line(format!(
|
||||||
abstutil::prettyprint_usize(num_same),
|
" trips: {} same, {} different",
|
||||||
abstutil::prettyprint_usize(deltas.len())
|
abstutil::prettyprint_usize(num_same),
|
||||||
)));
|
abstutil::prettyprint_usize(deltas.len())
|
||||||
|
)),
|
||||||
|
]);
|
||||||
if !deltas.is_empty() {
|
if !deltas.is_empty() {
|
||||||
summary.add(Line(" deltas: "));
|
summary.add_appended(vec![
|
||||||
summary.append(Line("50%ile").fg(Color::RED));
|
Line(" deltas: "),
|
||||||
summary.append(Line(format!(
|
Line("50%ile").fg(Color::RED),
|
||||||
" {}, ",
|
Line(format!(
|
||||||
handle_negative(deltas[(0.5 * len).floor() as usize])
|
" {}, ",
|
||||||
)));
|
handle_negative(deltas[(0.5 * len).floor() as usize])
|
||||||
summary.append(Line("90%ile").fg(Color::RED));
|
)),
|
||||||
summary.append(Line(format!(
|
Line("90%ile").fg(Color::RED),
|
||||||
" {}, ",
|
Line(format!(
|
||||||
handle_negative(deltas[(0.9 * len).floor() as usize])
|
" {}, ",
|
||||||
)));
|
handle_negative(deltas[(0.9 * len).floor() as usize])
|
||||||
summary.append(Line("99%ile").fg(Color::RED));
|
)),
|
||||||
summary.append(Line(format!(
|
Line("99%ile").fg(Color::RED),
|
||||||
" {}",
|
Line(format!(
|
||||||
handle_negative(deltas[(0.99 * len).floor() as usize])
|
" {}",
|
||||||
)));
|
handle_negative(deltas[(0.99 * len).floor() as usize])
|
||||||
|
)),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,15 +88,19 @@ impl CommonState {
|
|||||||
osd.append(Line("..."));
|
osd.append(Line("..."));
|
||||||
}
|
}
|
||||||
Some(ID::Lane(l)) => {
|
Some(ID::Lane(l)) => {
|
||||||
osd.append(Line(l.to_string()).fg(id_color));
|
osd.append_all(vec![
|
||||||
osd.append(Line(" is "));
|
Line(l.to_string()).fg(id_color),
|
||||||
osd.append(Line(map.get_parent(*l).get_name()).fg(name_color));
|
Line(" is "),
|
||||||
|
Line(map.get_parent(*l).get_name()).fg(name_color),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
Some(ID::Building(b)) => {
|
Some(ID::Building(b)) => {
|
||||||
let bldg = map.get_b(*b);
|
let bldg = map.get_b(*b);
|
||||||
osd.append(Line(b.to_string()).fg(id_color));
|
osd.append_all(vec![
|
||||||
osd.append(Line(" is "));
|
Line(b.to_string()).fg(id_color),
|
||||||
osd.append(Line(bldg.get_name()).fg(name_color));
|
Line(" is "),
|
||||||
|
Line(bldg.get_name()).fg(name_color),
|
||||||
|
]);
|
||||||
if let Some(ref p) = bldg.parking {
|
if let Some(ref p) = bldg.parking {
|
||||||
osd.append(Line(format!(
|
osd.append(Line(format!(
|
||||||
" ({} parking spots via {})",
|
" ({} parking spots via {})",
|
||||||
@ -105,15 +109,16 @@ impl CommonState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ID::Turn(t)) => {
|
Some(ID::Turn(t)) => {
|
||||||
osd.append(Line(format!("TurnID({})", map.get_t(*t).lookup_idx)).fg(id_color));
|
osd.append_all(vec![
|
||||||
osd.append(Line(" between "));
|
Line(format!("TurnID({})", map.get_t(*t).lookup_idx)).fg(id_color),
|
||||||
osd.append(Line(map.get_parent(t.src).get_name()).fg(name_color));
|
Line(" between "),
|
||||||
osd.append(Line(" and "));
|
Line(map.get_parent(t.src).get_name()).fg(name_color),
|
||||||
osd.append(Line(map.get_parent(t.dst).get_name()).fg(name_color));
|
Line(" and "),
|
||||||
|
Line(map.get_parent(t.dst).get_name()).fg(name_color),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
Some(ID::Intersection(i)) => {
|
Some(ID::Intersection(i)) => {
|
||||||
osd.append(Line(i.to_string()).fg(id_color));
|
osd.append_all(vec![Line(i.to_string()).fg(id_color), Line(" of ")]);
|
||||||
osd.append(Line(" of "));
|
|
||||||
|
|
||||||
let mut road_names = BTreeSet::new();
|
let mut road_names = BTreeSet::new();
|
||||||
for r in &map.get_i(*i).roads {
|
for r in &map.get_i(*i).roads {
|
||||||
@ -130,13 +135,14 @@ impl CommonState {
|
|||||||
Some(ID::Car(c)) => {
|
Some(ID::Car(c)) => {
|
||||||
osd.append(Line(c.to_string()).fg(id_color));
|
osd.append(Line(c.to_string()).fg(id_color));
|
||||||
if let Some(r) = ui.primary.sim.bus_route_id(*c) {
|
if let Some(r) = ui.primary.sim.bus_route_id(*c) {
|
||||||
osd.append(Line(" serving "));
|
osd.append_all(vec![
|
||||||
osd.append(Line(&map.get_br(r).name).fg(name_color));
|
Line(" serving "),
|
||||||
|
Line(&map.get_br(r).name).fg(name_color),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ID::BusStop(bs)) => {
|
Some(ID::BusStop(bs)) => {
|
||||||
osd.append(Line(bs.to_string()).fg(id_color));
|
osd.append_all(vec![Line(bs.to_string()).fg(id_color), Line(" serving ")]);
|
||||||
osd.append(Line(" serving "));
|
|
||||||
|
|
||||||
let routes = map.get_routes_serving_stop(*bs);
|
let routes = map.get_routes_serving_stop(*bs);
|
||||||
let len = routes.len();
|
let len = routes.len();
|
||||||
|
@ -149,16 +149,20 @@ fn tooltip_lines(id: ID, g: &mut GfxCtx, ctx: &PerMapUI) -> Text {
|
|||||||
match id {
|
match id {
|
||||||
ID::Road(id) => {
|
ID::Road(id) => {
|
||||||
let r = map.get_r(id);
|
let r = map.get_r(id);
|
||||||
txt.add(Line(format!("{} (originally {}) is ", r.id, r.stable_id)));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(r.get_name()).fg(Color::CYAN));
|
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)));
|
txt.add(Line(format!("From OSM way {}", r.osm_way_id)));
|
||||||
}
|
}
|
||||||
ID::Lane(id) => {
|
ID::Lane(id) => {
|
||||||
let l = map.get_l(id);
|
let l = map.get_l(id);
|
||||||
let r = map.get_r(l.parent);
|
let r = map.get_r(l.parent);
|
||||||
|
|
||||||
txt.add(Line(format!("{} is ", l.id)));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(r.get_name()).fg(Color::CYAN));
|
Line(format!("{} is ", l.id)),
|
||||||
|
Line(r.get_name()).fg(Color::CYAN),
|
||||||
|
]);
|
||||||
txt.add(Line(format!("From OSM way {}", r.osm_way_id)));
|
txt.add(Line(format!("From OSM way {}", r.osm_way_id)));
|
||||||
txt.add(Line(format!(
|
txt.add(Line(format!(
|
||||||
"Parent {} (originally {}) points to {}",
|
"Parent {} (originally {}) points to {}",
|
||||||
@ -258,8 +262,10 @@ fn tooltip_lines(id: ID, g: &mut GfxCtx, ctx: &PerMapUI) -> Text {
|
|||||||
|
|
||||||
fn styled_kv(txt: &mut Text, tags: &BTreeMap<String, String>) {
|
fn styled_kv(txt: &mut Text, tags: &BTreeMap<String, String>) {
|
||||||
for (k, v) in tags {
|
for (k, v) in tags {
|
||||||
txt.add(Line(k).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" = "));
|
Line(k).fg(Color::RED),
|
||||||
txt.append(Line(v).fg(Color::CYAN));
|
Line(" = "),
|
||||||
|
Line(v).fg(Color::CYAN),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,8 +120,10 @@ impl State for StopSignEditor {
|
|||||||
self.menu.draw(g);
|
self.menu.draw(g);
|
||||||
if let Some(r) = self.selected_sign {
|
if let Some(r) = self.selected_sign {
|
||||||
let mut osd = Text::new();
|
let mut osd = Text::new();
|
||||||
osd.add(Line("Stop sign for "));
|
osd.add_appended(vec![
|
||||||
osd.append(Line(ui.primary.map.get_r(r).get_name()).fg(ui.cs.get("OSD name color")));
|
Line("Stop sign for "),
|
||||||
|
Line(ui.primary.map.get_r(r).get_name()).fg(ui.cs.get("OSD name color")),
|
||||||
|
]);
|
||||||
CommonState::draw_custom_osd(g, osd);
|
CommonState::draw_custom_osd(g, osd);
|
||||||
} else {
|
} else {
|
||||||
CommonState::draw_osd(g, ui, &None);
|
CommonState::draw_osd(g, ui, &None);
|
||||||
|
@ -66,8 +66,10 @@ impl State for DataVisualizer {
|
|||||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition {
|
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition {
|
||||||
let mut txt = Text::prompt("Data Visualizer");
|
let mut txt = Text::prompt("Data Visualizer");
|
||||||
if let Some(ref name) = self.current_tract {
|
if let Some(ref name) = self.current_tract {
|
||||||
txt.add(Line("Census "));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(name).fg(ui.cs.get("OSD name color")));
|
Line("Census "),
|
||||||
|
Line(name).fg(ui.cs.get("OSD name color")),
|
||||||
|
]);
|
||||||
let tract = &self.tracts[name];
|
let tract = &self.tracts[name];
|
||||||
txt.add(Line(format!(
|
txt.add(Line(format!(
|
||||||
"{} buildings",
|
"{} buildings",
|
||||||
@ -126,8 +128,10 @@ impl State for DataVisualizer {
|
|||||||
self.menu.draw(g);
|
self.menu.draw(g);
|
||||||
if let Some(ref name) = self.current_tract {
|
if let Some(ref name) = self.current_tract {
|
||||||
let mut osd = Text::new();
|
let mut osd = Text::new();
|
||||||
osd.add(Line("Census "));
|
osd.add_appended(vec![
|
||||||
osd.append(Line(name).fg(ui.cs.get("OSD name color")));
|
Line("Census "),
|
||||||
|
Line(name).fg(ui.cs.get("OSD name color")),
|
||||||
|
]);
|
||||||
CommonState::draw_custom_osd(g, osd);
|
CommonState::draw_custom_osd(g, osd);
|
||||||
} else {
|
} else {
|
||||||
CommonState::draw_osd(g, ui, &None);
|
CommonState::draw_osd(g, ui, &None);
|
||||||
@ -150,9 +154,11 @@ impl State for DataVisualizer {
|
|||||||
} else {
|
} else {
|
||||||
let mut txt = Text::new();
|
let mut txt = Text::new();
|
||||||
for (k, v) in kv {
|
for (k, v) in kv {
|
||||||
txt.add(Line(k).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" = "));
|
Line(k).fg(Color::RED),
|
||||||
txt.append(Line(v.to_string()).fg(Color::CYAN));
|
Line(" = "),
|
||||||
|
Line(v.to_string()).fg(Color::CYAN),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
g.draw_blocking_text(&txt, (HorizontalAlignment::Left, VerticalAlignment::Top));
|
g.draw_blocking_text(&txt, (HorizontalAlignment::Left, VerticalAlignment::Top));
|
||||||
}
|
}
|
||||||
@ -236,15 +242,15 @@ fn bar_chart(g: &mut GfxCtx, data: &BTreeMap<String, Estimate>) {
|
|||||||
if name == "Total:" {
|
if name == "Total:" {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
labels.add(Line(format!("{} (", name)).size(40));
|
labels.add_appended(vec![
|
||||||
labels.append(
|
Line(format!("{} (", name)).size(40),
|
||||||
Line(format!(
|
Line(format!(
|
||||||
"{}%",
|
"{}%",
|
||||||
((est.value as f64) / (sum as f64) * 100.0) as usize
|
((est.value as f64) / (sum as f64) * 100.0) as usize
|
||||||
))
|
))
|
||||||
.fg(Color::RED),
|
.fg(Color::RED),
|
||||||
);
|
Line(")"),
|
||||||
labels.append(Line(")"));
|
]);
|
||||||
}
|
}
|
||||||
let (txt_width, total_height) = g.text_dims(&labels);
|
let (txt_width, total_height) = g.text_dims(&labels);
|
||||||
let line_height = total_height / ((data.len() as f64) - 1.0);
|
let line_height = total_height / ((data.len() as f64) - 1.0);
|
||||||
|
@ -108,9 +108,11 @@ impl State for TripsVisualizer {
|
|||||||
self.slider.draw(g);
|
self.slider.draw(g);
|
||||||
if let Some(ID::Building(b)) = ui.primary.current_selection {
|
if let Some(ID::Building(b)) = ui.primary.current_selection {
|
||||||
let mut osd = Text::new();
|
let mut osd = Text::new();
|
||||||
osd.add(Line(b.to_string()).fg(ui.cs.get("OSD ID color")));
|
osd.add_appended(vec![
|
||||||
osd.append(Line(" is "));
|
Line(b.to_string()).fg(ui.cs.get("OSD ID color")),
|
||||||
osd.append(Line(ui.primary.map.get_b(b).get_name()).fg(ui.cs.get("OSD name color")));
|
Line(" is "),
|
||||||
|
Line(ui.primary.map.get_b(b).get_name()).fg(ui.cs.get("OSD name color")),
|
||||||
|
]);
|
||||||
if let Some(md) = self.bldgs.get(&b) {
|
if let Some(md) = self.bldgs.get(&b) {
|
||||||
osd.append(Line(format!(
|
osd.append(Line(format!(
|
||||||
". {} households, {} employees, {} offstreet parking spaces",
|
". {} households, {} employees, {} offstreet parking spaces",
|
||||||
|
@ -213,17 +213,19 @@ impl State for ScenarioManager {
|
|||||||
|
|
||||||
if let Some(ID::Building(b)) = ui.primary.current_selection {
|
if let Some(ID::Building(b)) = ui.primary.current_selection {
|
||||||
let mut osd = Text::new();
|
let mut osd = Text::new();
|
||||||
osd.add(Line(b.to_string()).fg(ui.cs.get("OSD ID color")));
|
|
||||||
osd.append(Line(" is "));
|
|
||||||
osd.append(Line(ui.primary.map.get_b(b).get_name()).fg(ui.cs.get("OSD name color")));
|
|
||||||
let from = self.trips_from_bldg.get(b);
|
let from = self.trips_from_bldg.get(b);
|
||||||
let to = self.trips_to_bldg.get(b);
|
let to = self.trips_to_bldg.get(b);
|
||||||
osd.append(Line(format!(
|
osd.add_appended(vec![
|
||||||
". {} trips from here, {} trips to here, {} parked cars needed",
|
Line(b.to_string()).fg(ui.cs.get("OSD ID color")),
|
||||||
from.len(),
|
Line(" is "),
|
||||||
to.len(),
|
Line(ui.primary.map.get_b(b).get_name()).fg(ui.cs.get("OSD name color")),
|
||||||
self.cars_needed_per_bldg[&b]
|
Line(format!(
|
||||||
)));
|
". {} trips from here, {} trips to here, {} parked cars needed",
|
||||||
|
from.len(),
|
||||||
|
to.len(),
|
||||||
|
self.cars_needed_per_bldg[&b]
|
||||||
|
)),
|
||||||
|
]);
|
||||||
CommonState::draw_custom_osd(g, osd);
|
CommonState::draw_custom_osd(g, osd);
|
||||||
} else {
|
} else {
|
||||||
CommonState::draw_osd(g, ui, &ui.primary.current_selection);
|
CommonState::draw_osd(g, ui, &ui.primary.current_selection);
|
||||||
|
@ -28,10 +28,14 @@ impl Scoreboard {
|
|||||||
let t = ui.primary.sim.get_finished_trips();
|
let t = ui.primary.sim.get_finished_trips();
|
||||||
|
|
||||||
let mut summary = Text::new();
|
let mut summary = Text::new();
|
||||||
summary.add(Line("Score at "));
|
summary.add_appended(vec![
|
||||||
summary.append(Line(ui.primary.sim.time().to_string()).fg(Color::RED));
|
Line("Score at "),
|
||||||
summary.add(Line(prettyprint_usize(t.unfinished_trips)).fg(Color::CYAN));
|
Line(ui.primary.sim.time().to_string()).fg(Color::RED),
|
||||||
summary.append(Line(" unfinished trips"));
|
]);
|
||||||
|
summary.add_appended(vec![
|
||||||
|
Line(prettyprint_usize(t.unfinished_trips)).fg(Color::CYAN),
|
||||||
|
Line(" unfinished trips"),
|
||||||
|
]);
|
||||||
|
|
||||||
for (mode, trips) in &t
|
for (mode, trips) in &t
|
||||||
.finished_trips
|
.finished_trips
|
||||||
@ -43,8 +47,10 @@ impl Scoreboard {
|
|||||||
for (_, _, dt) in trips {
|
for (_, _, dt) in trips {
|
||||||
distrib.add(dt);
|
distrib.add(dt);
|
||||||
}
|
}
|
||||||
summary.add(Line(format!("{:?}", mode)).fg(Color::CYAN));
|
summary.add_appended(vec![
|
||||||
summary.append(Line(format!(" trips: {}", distrib.describe())));
|
Line(format!("{:?}", mode)).fg(Color::CYAN),
|
||||||
|
Line(format!(" trips: {}", distrib.describe())),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scoreboard { menu, summary }
|
Scoreboard { menu, summary }
|
||||||
|
@ -213,9 +213,11 @@ impl GUI for UI {
|
|||||||
if let Some(ID::Lane(id, _, _)) = self.model.get_selection() {
|
if let Some(ID::Lane(id, _, _)) = self.model.get_selection() {
|
||||||
let mut txt = Text::new();
|
let mut txt = Text::new();
|
||||||
for (k, v) in self.model.get_tags(id) {
|
for (k, v) in self.model.get_tags(id) {
|
||||||
txt.add(Line(k).fg(Color::RED));
|
txt.add_appended(vec![
|
||||||
txt.append(Line(" = "));
|
Line(k).fg(Color::RED),
|
||||||
txt.append(Line(v).fg(Color::CYAN));
|
Line(" = "),
|
||||||
|
Line(v).fg(Color::CYAN),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
g.draw_blocking_text(
|
g.draw_blocking_text(
|
||||||
&txt,
|
&txt,
|
||||||
|
Loading…
Reference in New Issue
Block a user