typography overhaul... [rebuild]

This commit is contained in:
Dustin Carlino 2020-03-26 15:42:37 -07:00
parent 3ba43cbd23
commit 69dab9e27d
42 changed files with 224 additions and 197 deletions

View File

@ -202,8 +202,9 @@ e761e1d1f6c9b8befe53296e0411cef2 data/system/assets/minimap/zoom_out_fully.svg
9caf97939884d4859accca34265f45fb data/system/assets/minimap/up.svg 9caf97939884d4859accca34265f45fb data/system/assets/minimap/up.svg
a5e849fa8883569519976ebfef3ae269 data/system/night_colors.json a5e849fa8883569519976ebfef3ae269 data/system/night_colors.json
1909af5ebfefe7ad4102335c9e789d24 data/system/override_colors.json 1909af5ebfefe7ad4102335c9e789d24 data/system/override_colors.json
517a360397bbb5a7573c2558e78fa4ea data/system/fonts/DejaVuSans.ttf
e07df86cef2e721115583d61d1fb68a6 data/system/fonts/Roboto-Bold.ttf e07df86cef2e721115583d61d1fb68a6 data/system/fonts/Roboto-Bold.ttf
2a13391023ce8787887331530cac35a7 data/system/fonts/BungeeInline-Regular.ttf
259d4afad7edca07e727ef80f5bbce07 data/system/fonts/Bungee-Regular.ttf
11eabca2251325cfc5589c9c6fb57b46 data/system/fonts/Roboto-Regular.ttf 11eabca2251325cfc5589c9c6fb57b46 data/system/fonts/Roboto-Regular.ttf
b38a9172d4a3c5521c1bde089b87a4b5 data/system/maps/huge_seattle.bin b38a9172d4a3c5521c1bde089b87a4b5 data/system/maps/huge_seattle.bin
06e7705be021d6b236b4c90e9a8f4d35 data/system/maps/ballard.bin 06e7705be021d6b236b4c90e9a8f4d35 data/system/maps/ballard.bin

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -65,5 +65,5 @@ A/B Street binary releases contain pre-built maps that combine data from:
Other binary data bundled in: Other binary data bundled in:
- DejaVuSans.ttf (https://dejavu-fonts.github.io/License.html) - Roboto font (https://fonts.google.com/specimen/Roboto, Apache license)
- Roboto-Regular.ttf (https://fonts.google.com/specimen/Roboto, Apache license) - Bungee fonts (https://fonts.google.com/specimen/Bungee, Open Font License)

View File

@ -43,20 +43,24 @@ impl App {
fn make_timeseries_panel(&self, ctx: &mut EventCtx) -> Composite { fn make_timeseries_panel(&self, ctx: &mut EventCtx) -> Composite {
// Make a table with 3 columns. // Make a table with 3 columns.
let mut col1 = vec![Line("Time").roboto_bold().draw(ctx)]; let mut col1 = vec![Line("Time").draw(ctx)];
let mut col2 = vec![Line("Linear").roboto_bold().draw(ctx)]; let mut col2 = vec![Line("Linear").draw(ctx)];
let mut col3 = vec![Line("Quadratic").roboto_bold().draw(ctx)]; let mut col3 = vec![Line("Quadratic").draw(ctx)];
for s in 0..(self.elapsed.inner_seconds() as usize) { for s in 0..(self.elapsed.inner_seconds() as usize) {
col1.push(Duration::seconds(s as f64).to_string().draw_text(ctx)); col1.push(
col2.push(s.to_string().draw_text(ctx)); Line(Duration::seconds(s as f64).to_string())
col3.push(s.pow(2).to_string().draw_text(ctx)); .secondary()
.draw(ctx),
);
col2.push(Line(s.to_string()).secondary().draw(ctx));
col3.push(Line(s.pow(2).to_string()).secondary().draw(ctx));
} }
let mut c = Composite::new( let mut c = Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![{ Widget::row(vec![{
let mut txt = Text::from( let mut txt = Text::from(
Line("Here's a bunch of text to force some scrolling.").roboto_bold(), Line("Here's a bunch of text to force some scrolling.").small_heading(),
); );
txt.add( txt.add(
Line( Line(
@ -247,7 +251,7 @@ fn make_controls(ctx: &mut EventCtx) -> Composite {
Composite::new( Composite::new(
Widget::col(vec![ Widget::col(vec![
{ {
let mut txt = Text::from(Line("ezgui demo").roboto_bold()); let mut txt = Text::from(Line("ezgui demo").small_heading());
txt.add(Line( txt.add(Line(
"Click and drag to pan, use touchpad or scroll wheel to zoom", "Click and drag to pan, use touchpad or scroll wheel to zoom",
)); ));

View File

@ -29,7 +29,7 @@ impl Assets {
text_opts: Options::default(), text_opts: Options::default(),
}; };
*a.default_line_height.borrow_mut() = *a.default_line_height.borrow_mut() =
a.line_height(Font::DejaVu, *a.default_font_size.borrow()); a.line_height(Font::Roboto, *a.default_font_size.borrow());
a.text_opts.font_directories.push(font_dir); a.text_opts.font_directories.push(font_dir);
a a
} }
@ -48,9 +48,10 @@ impl Assets {
let height = text::SCALE_LINE_HEIGHT let height = text::SCALE_LINE_HEIGHT
* *self.scale_factor.borrow() * *self.scale_factor.borrow()
* db.load_font_idx(match font { * db.load_font_idx(match font {
Font::DejaVu => 0, Font::BungeeInline => 0,
Font::RobotoBold => 1, Font::Bungee => 1,
Font::Roboto => 2, Font::RobotoBold => 2,
Font::Roboto => 3,
}) })
.unwrap() .unwrap()
.height(font_size as f64); .height(font_size as f64);
@ -90,6 +91,6 @@ impl Assets {
self.line_height_cache.borrow_mut().clear(); self.line_height_cache.borrow_mut().clear();
self.svg_cache.borrow_mut().clear(); self.svg_cache.borrow_mut().clear();
*self.default_line_height.borrow_mut() = *self.default_line_height.borrow_mut() =
self.line_height(Font::DejaVu, *self.default_font_size.borrow()); self.line_height(Font::Roboto, *self.default_font_size.borrow());
} }
} }

View File

@ -139,7 +139,7 @@ impl<'a> LoadingScreen<'a> {
} }
self.last_drawn = Instant::now(); self.last_drawn = Instant::now();
let mut txt = Text::from(Line(&self.title).roboto_bold()); let mut txt = Text::from(Line(&self.title).small_heading());
for l in &self.lines { for l in &self.lines {
txt.add(Line(l)); txt.add(Line(l));
} }

View File

@ -150,7 +150,7 @@ impl Settings {
window_title: window_title.to_string(), window_title: window_title.to_string(),
font_dir: font_dir.to_string(), font_dir: font_dir.to_string(),
profiling_enabled: false, profiling_enabled: false,
default_font_size: 30, default_font_size: 21,
dump_raw_events: false, dump_raw_events: false,
scale_factor: 1.0, scale_factor: 1.0,
} }

View File

@ -20,9 +20,10 @@ pub const MAX_CHAR_WIDTH: f64 = 25.0;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Font { pub enum Font {
DejaVu,
Roboto, Roboto,
RobotoBold, RobotoBold,
Bungee,
BungeeInline,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -40,27 +41,50 @@ impl TextSpan {
self self
} }
pub fn size(mut self, size: usize) -> TextSpan {
assert_eq!(self.size, None);
self.size = Some(size);
self
}
pub fn roboto(mut self) -> TextSpan {
assert_eq!(self.font, Font::DejaVu);
self.font = Font::Roboto;
self
}
pub fn roboto_bold(mut self) -> TextSpan {
assert_eq!(self.font, Font::DejaVu);
self.font = Font::RobotoBold;
self
}
pub fn draw(self, ctx: &EventCtx) -> Widget { pub fn draw(self, ctx: &EventCtx) -> Widget {
Text::from(self).draw(ctx) Text::from(self).draw(ctx)
} }
// Yuwen's new styles, defined in Figma. Should document them in Github better.
pub fn display_title(mut self) -> TextSpan {
self.font = Font::BungeeInline;
self.size = Some(64);
self
}
pub fn big_heading_styled(mut self) -> TextSpan {
self.font = Font::Bungee;
self.size = Some(32);
self
}
pub fn big_heading_plain(mut self) -> TextSpan {
self.font = Font::RobotoBold;
self.size = Some(32);
self
}
pub fn small_heading(mut self) -> TextSpan {
// TODO Roboto medium?
self.font = Font::RobotoBold;
self.size = Some(26);
self
}
// The default
pub fn body(mut self) -> TextSpan {
self.font = Font::Roboto;
self.size = Some(21);
self
}
pub fn secondary(mut self) -> TextSpan {
self.font = Font::Roboto;
self.size = Some(21);
self.fg_color = Color::hex("#A3A3A3");
self
}
pub fn small(mut self) -> TextSpan {
self.font = Font::Roboto;
self.size = Some(16);
self
}
} }
// TODO What's the better way of doing this? Also "Line" is a bit of a misnomer // TODO What's the better way of doing this? Also "Line" is a bit of a misnomer
@ -70,7 +94,7 @@ pub fn Line<S: Into<String>>(text: S) -> TextSpan {
text: text.into(), text: text.into(),
fg_color: FG_COLOR, fg_color: FG_COLOR,
size: None, size: None,
font: Font::DejaVu, font: Font::Roboto,
} }
} }
@ -111,11 +135,11 @@ impl Text {
// TODO Not exactly sure this is the right place for this, but better than code duplication // TODO Not exactly sure this is the right place for this, but better than code duplication
pub fn tooltip(hotkey: Option<MultiKey>, action: &str) -> Text { pub fn tooltip(hotkey: Option<MultiKey>, action: &str) -> Text {
if let Some(ref key) = hotkey { if let Some(ref key) = hotkey {
let mut txt = Text::from(Line(key.describe()).fg(HOTKEY_COLOR).size(20)); let mut txt = Text::from(Line(key.describe()).fg(HOTKEY_COLOR).small());
txt.append(Line(format!(" - {}", action))); txt.append(Line(format!(" - {}", action)));
txt txt
} else { } else {
Text::from(Line(action).size(20)) Text::from(Line(action).small())
} }
} }
@ -291,7 +315,8 @@ fn render_text(spans: Vec<TextSpan>, tolerance: f32, assets: &Assets) -> GeomBat
r##"<svg width="9999" height="9999" viewBox="0 0 9999 9999" xmlns="http://www.w3.org/2000/svg"><text x="0" y="0" font-size="{}" {}>"##, r##"<svg width="9999" height="9999" viewBox="0 0 9999 9999" xmlns="http://www.w3.org/2000/svg"><text x="0" y="0" font-size="{}" {}>"##,
spans[0].size.unwrap_or(*assets.default_font_size.borrow()), spans[0].size.unwrap_or(*assets.default_font_size.borrow()),
match spans[0].font { match spans[0].font {
Font::DejaVu => "font-family=\"DejaVu Sans\"", Font::BungeeInline => "font-family=\"Bungee Inline\"",
Font::Bungee => "font-family=\"Bungee\"",
Font::Roboto => "font-family=\"Roboto\"", Font::Roboto => "font-family=\"Roboto\"",
Font::RobotoBold => "font-family=\"Roboto\" font-weight=\"bold\"", Font::RobotoBold => "font-family=\"Roboto\" font-weight=\"bold\"",
} }

View File

@ -85,7 +85,7 @@ impl Wizard {
Composite::new( Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line(query).roboto_bold().draw(ctx), Line(query).small_heading().draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build(ctx, "quit", hotkey(Key::Escape)) .build(ctx, "quit", hotkey(Key::Escape))
.margin(5) .margin(5)
@ -240,7 +240,7 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
let choices: Vec<Choice<R>> = choices_generator(); let choices: Vec<Choice<R>> = choices_generator();
if choices.is_empty() { if choices.is_empty() {
let mut txt = if let Some(l) = query { let mut txt = if let Some(l) = query {
Text::from(Line(l).roboto_bold()) Text::from(Line(l).small_heading())
} else { } else {
Text::new() Text::new()
}; };
@ -250,7 +250,7 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
} }
let mut col = Vec::new(); let mut col = Vec::new();
if let Some(l) = query { if let Some(l) = query {
col.push(Line(l).roboto_bold().draw(self.ctx)); col.push(Line(l).small_heading().draw(self.ctx));
} }
col.push( col.push(
Menu::new( Menu::new(
@ -367,7 +367,7 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
} }
if self.wizard.ack.is_none() { if self.wizard.ack.is_none() {
let mut txt = Text::from(Line(title).roboto_bold()); let mut txt = Text::from(Line(title).small_heading());
for l in make_lines() { for l in make_lines() {
txt.add(Line(l)); txt.add(Line(l));
} }

View File

@ -57,7 +57,7 @@ impl<T: Clone + Hash + Eq> Autocomplete<T> {
} }
pub fn draw(&self, g: &mut GfxCtx) { pub fn draw(&self, g: &mut GfxCtx) {
let mut txt = Text::from(Line(&self.prompt).roboto_bold()).with_bg(); let mut txt = Text::from(Line(&self.prompt).small_heading()).with_bg();
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() {

View File

@ -144,8 +144,8 @@ impl Tab {
.align_left(), .align_left(),
); );
master_col.push({ master_col.push({
let mut txt = Text::from(Line("A/B STREET").size(100)); let mut txt = Text::from(Line("A/B STREET").display_title());
txt.add(Line("CHALLENGES").size(50)); txt.add(Line("CHALLENGES").big_heading_styled());
txt.draw(ctx).centered_horiz() txt.draw(ctx).centered_horiz()
}); });

View File

@ -6,7 +6,7 @@ use crate::render::MIN_ZOOM_FOR_DETAIL;
use abstutil::clamp; use abstutil::clamp;
use ezgui::{ use ezgui::{
hotkey, Btn, Color, Composite, EventCtx, Filler, GeomBatch, GfxCtx, HorizontalAlignment, Key, hotkey, Btn, Color, Composite, EventCtx, Filler, GeomBatch, GfxCtx, HorizontalAlignment, Key,
Line, Outcome, RewriteColor, ScreenDims, ScreenPt, Text, TextExt, VerticalAlignment, Widget, Line, Outcome, RewriteColor, ScreenDims, ScreenPt, Text, VerticalAlignment, Widget,
}; };
use geom::{Circle, Distance, Polygon, Pt2D, Ring}; use geom::{Circle, Distance, Polygon, Pt2D, Ring};
@ -368,9 +368,9 @@ fn make_viz_panel(ctx: &mut EventCtx, app: &App) -> Widget {
) )
.margin(3), .margin(3),
Text::from(if *enabled { Text::from(if *enabled {
Line(label) Line(label).small()
} else { } else {
Line(label).fg(Color::WHITE.alpha(0.5)) Line(label).small().fg(Color::WHITE.alpha(0.5))
}) })
.draw(ctx) .draw(ctx)
.margin(3), .margin(3),
@ -391,7 +391,7 @@ fn make_viz_panel(ctx: &mut EventCtx, app: &App) -> Widget {
RewriteColor::ChangeAll(Color::BLUE), RewriteColor::ChangeAll(Color::BLUE),
) )
.margin(5), .margin(5),
name.draw_text(ctx), Line(name).small().draw(ctx),
]), ]),
); );
} }

View File

@ -838,7 +838,7 @@ impl Overlays {
let route = app.primary.map.get_br(id); let route = app.primary.map.get_br(id);
let mut master_col = vec![Widget::row(vec![ let mut master_col = vec![Widget::row(vec![
Line(format!("Passengers for {}", route.name)) Line(format!("Passengers for {}", route.name))
.roboto_bold() .small_heading()
.draw(ctx), .draw(ctx),
Btn::text_fg("X").build_def(ctx, None).align_right(), Btn::text_fg("X").build_def(ctx, None).align_right(),
])]; ])];
@ -1056,7 +1056,7 @@ fn population_controls(ctx: &mut EventCtx, app: &App, opts: Option<&HeatmapOptio
Widget::row(vec![ Widget::row(vec![
// TODO Only bold the first part // TODO Only bold the first part
Line(format!("Population: {}", prettyprint_usize(total_ppl))) Line(format!("Population: {}", prettyprint_usize(total_ppl)))
.roboto_bold() .small_heading()
.draw(ctx), .draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build(ctx, "close", hotkey(Key::Escape)) .build(ctx, "close", hotkey(Key::Escape))

View File

@ -253,7 +253,7 @@ impl TurnExplorer {
"Turns from {}", "Turns from {}",
app.primary.map.get_parent(l).get_name() app.primary.map.get_parent(l).get_name()
)) ))
.size(26), .small_heading(),
) )
.draw(ctx) .draw(ctx)
.margin(5), .margin(5),
@ -268,7 +268,7 @@ impl TurnExplorer {
Btn::text_fg("<").build(ctx, "previous turn", hotkey(Key::LeftArrow)) Btn::text_fg("<").build(ctx, "previous turn", hotkey(Key::LeftArrow))
} }
.margin(5), .margin(5),
Text::from(Line(format!("{}/{}", idx, num_turns)).size(20)) Text::from(Line(format!("{}/{}", idx, num_turns)).secondary())
.draw(ctx) .draw(ctx)
.margin(5) .margin(5)
.centered_vert(), .centered_vert(),

View File

@ -38,7 +38,7 @@ impl DebugMode {
composite: Composite::new( composite: Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line("Debug Mode").roboto_bold().draw(ctx), Line("Debug Mode").small_heading().draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build_def(ctx, hotkey(Key::Escape)) .build_def(ctx, hotkey(Key::Escape))
.align_right(), .align_right(),

View File

@ -207,7 +207,10 @@ fn make_panel(ctx: &mut EventCtx) -> Composite {
Composite::new( Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line("Geometry debugger").roboto_bold().draw(ctx).margin(5), Line("Geometry debugger")
.small_heading()
.draw(ctx)
.margin(5),
Btn::text_fg("X") Btn::text_fg("X")
.build(ctx, "close", hotkey(Key::Escape)) .build(ctx, "close", hotkey(Key::Escape))
.align_right(), .align_right(),

View File

@ -554,7 +554,7 @@ impl DotMap {
composite: Composite::new( composite: Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line("Dot map of all trips").roboto_bold().draw(ctx), Line("Dot map of all trips").small_heading().draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build_def(ctx, hotkey(Key::Escape)) .build_def(ctx, hotkey(Key::Escape))
.align_right(), .align_right(),

View File

@ -340,19 +340,15 @@ fn make_topcenter(ctx: &mut EventCtx, app: &App) -> Composite {
Composite::new( Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line("Editing map").size(26).draw(ctx).margin(5), Line("Editing map").small_heading().draw(ctx).margin(5),
Widget::draw_batch( Widget::draw_batch(
ctx, ctx,
GeomBatch::from(vec![(Color::WHITE, Polygon::rectangle(2.0, 30.0))]), GeomBatch::from(vec![(Color::WHITE, Polygon::rectangle(2.0, 30.0))]),
) )
.margin(5), .margin(5),
Btn::custom_text_fg(Text::from( Btn::text_fg(format!("{}", &app.primary.map.get_edits().edits_name))
Line(format!("{}", &app.primary.map.get_edits().edits_name)) .build(ctx, "load edits", lctrl(Key::L))
.size(18) .margin(5),
.roboto(),
))
.build(ctx, "load edits", lctrl(Key::L))
.margin(5),
Btn::svg_def("../data/system/assets/tools/save.svg") Btn::svg_def("../data/system/assets/tools/save.svg")
.build(ctx, "save edits as", lctrl(Key::S)) .build(ctx, "save edits as", lctrl(Key::S))
.margin(5), .margin(5),

View File

@ -44,7 +44,9 @@ pub fn car_info(
VehicleType::Bus => "Bus", VehicleType::Bus => "Bus",
}; };
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("{} #{}", label, id.0)).roboto_bold().draw(ctx), Line(format!("{} #{}", label, id.0))
.small_heading()
.draw(ctx),
header_btns, header_btns,
])); ]));
@ -134,7 +136,7 @@ pub fn ped_info(
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("Pedestrian #{}", id.0)) Line(format!("Pedestrian #{}", id.0))
.roboto_bold() .small_heading()
.draw(ctx), .draw(ctx),
header_btns, header_btns,
])); ]));
@ -217,7 +219,7 @@ pub fn crowd_info(
let mut rows = vec![]; let mut rows = vec![];
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line("Pedestrian crowd").roboto_bold().draw(ctx), Line("Pedestrian crowd").small_heading().draw(ctx),
header_btns, header_btns,
])); ]));

View File

@ -29,7 +29,9 @@ pub fn info(
let ppl = app.primary.sim.bldg_to_people(id); let ppl = app.primary.sim.bldg_to_people(id);
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("Building #{}", id.0)).roboto_bold().draw(ctx), Line(format!("Building #{}", id.0))
.small_heading()
.draw(ctx),
header_btns, header_btns,
])); ]));

View File

@ -16,7 +16,7 @@ pub fn info(
let sim = &app.primary.sim; let sim = &app.primary.sim;
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line("Bus stop").roboto_bold().draw(ctx), Line("Bus stop").small_heading().draw(ctx),
header_btns, header_btns,
])); ]));
rows.extend(action_btns); rows.extend(action_btns);
@ -28,7 +28,7 @@ pub fn info(
))); )));
let all_arrivals = &sim.get_analytics().bus_arrivals; let all_arrivals = &sim.get_analytics().bus_arrivals;
for r in app.primary.map.get_routes_serving_stop(id) { for r in app.primary.map.get_routes_serving_stop(id) {
txt.add(Line(format!("- Route {}", r.name)).roboto_bold()); txt.add(Line(format!("- Route {}", r.name)));
let arrivals: Vec<(Time, CarID)> = all_arrivals let arrivals: Vec<(Time, CarID)> = all_arrivals
.iter() .iter()
.filter(|(_, _, route, stop)| r.id == *route && id == *stop) .filter(|(_, _, route, stop)| r.id == *route && id == *stop)
@ -36,9 +36,9 @@ pub fn info(
.collect(); .collect();
if let Some((t, _)) = arrivals.last() { if let Some((t, _)) = arrivals.last() {
// TODO Button to jump to the bus // TODO Button to jump to the bus
txt.add(Line(format!(" Last bus arrived {} ago", sim.time() - *t))); txt.add(Line(format!(" Last bus arrived {} ago", sim.time() - *t)).secondary());
} else { } else {
txt.add(Line(" No arrivals yet")); txt.add(Line(" No arrivals yet").secondary());
} }
// TODO Kind of inefficient... // TODO Kind of inefficient...
if let Some(hgram) = sim if let Some(hgram) = sim
@ -46,7 +46,7 @@ pub fn info(
.bus_passenger_delays(sim.time(), r.id) .bus_passenger_delays(sim.time(), r.id)
.remove(&id) .remove(&id)
{ {
txt.add(Line(format!(" Waiting: {}", hgram.describe()))); txt.add(Line(format!(" Waiting: {}", hgram.describe())).secondary());
} }
} }
rows.push(txt.draw(ctx)); rows.push(txt.draw(ctx));

View File

@ -14,7 +14,7 @@ pub fn area(
let mut rows = vec![]; let mut rows = vec![];
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("Area #{}", id.0)).roboto_bold().draw(ctx), Line(format!("Area #{}", id.0)).small_heading().draw(ctx),
header_btns, header_btns,
])); ]));
rows.extend(action_btns); rows.extend(action_btns);
@ -40,7 +40,7 @@ pub fn extra_shape(
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("Extra GIS shape #{}", id.0)) Line(format!("Extra GIS shape #{}", id.0))
.roboto_bold() .small_heading()
.draw(ctx), .draw(ctx),
header_btns, header_btns,
])); ]));

View File

@ -34,7 +34,7 @@ pub fn info(
IntersectionType::Construction => format!("Intersection #{} (under construction)", id.0), IntersectionType::Construction => format!("Intersection #{} (under construction)", id.0),
}; };
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(label).roboto_bold().draw(ctx), Line(label).small_heading().draw(ctx),
header_btns, header_btns,
])); ]));
@ -87,19 +87,22 @@ pub fn info(
InfoTab::Intersection(Tab::Throughput) => { InfoTab::Intersection(Tab::Throughput) => {
let mut txt = Text::new(); let mut txt = Text::new();
txt.add(Line("Throughput").roboto_bold()); txt.add(Line("Throughput"));
txt.add(Line(format!( txt.add(
"Since midnight: {} agents crossed", Line(format!(
prettyprint_usize( "Since midnight: {} agents crossed",
app.primary prettyprint_usize(
.sim app.primary
.get_analytics() .sim
.thruput_stats .get_analytics()
.count_per_intersection .thruput_stats
.get(id) .count_per_intersection
) .get(id)
))); )
txt.add(Line(format!("In 20 minute buckets:"))); ))
.secondary(),
);
txt.add(Line(format!("In 20 minute buckets:")).secondary());
rows.push(txt.draw(ctx)); rows.push(txt.draw(ctx));
rows.push( rows.push(
@ -111,8 +114,8 @@ pub fn info(
} }
InfoTab::Intersection(Tab::Delay) => { InfoTab::Intersection(Tab::Delay) => {
assert!(app.primary.map.get_i(id).is_traffic_signal()); assert!(app.primary.map.get_i(id).is_traffic_signal());
let mut txt = Text::from(Line("Delay").roboto_bold()); let mut txt = Text::from(Line("Delay"));
txt.add(Line(format!("In 20 minute buckets:"))); txt.add(Line(format!("In 20 minute buckets:")).secondary());
rows.push(txt.draw(ctx)); rows.push(txt.draw(ctx));
rows.push(delay(ctx, app, id, Duration::minutes(20)).margin(10)); rows.push(delay(ctx, app, id, Duration::minutes(20)).margin(10));

View File

@ -30,7 +30,9 @@ pub fn info(
let label = if l.is_sidewalk() { "Sidewalk" } else { "Lane" }; let label = if l.is_sidewalk() { "Sidewalk" } else { "Lane" };
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("{} #{}", label, id.0)).roboto_bold().draw(ctx), Line(format!("{} #{}", label, id.0))
.small_heading()
.draw(ctx),
header_btns, header_btns,
])); ]));
rows.push(format!("@ {}", r.get_name()).draw_text(ctx)); rows.push(format!("@ {}", r.get_name()).draw_text(ctx));
@ -125,19 +127,22 @@ pub fn info(
InfoTab::Lane(Tab::Throughput) => { InfoTab::Lane(Tab::Throughput) => {
// Since this applies to the entire road, ignore lane type. // Since this applies to the entire road, ignore lane type.
let mut txt = Text::from(Line("")); let mut txt = Text::from(Line(""));
txt.add(Line("Throughput (entire road)").roboto_bold()); txt.add(Line("Throughput (entire road)"));
txt.add(Line(format!( txt.add(
"Since midnight: {} agents crossed", Line(format!(
prettyprint_usize( "Since midnight: {} agents crossed",
app.primary prettyprint_usize(
.sim app.primary
.get_analytics() .sim
.thruput_stats .get_analytics()
.count_per_road .thruput_stats
.get(r.id) .count_per_road
) .get(r.id)
))); )
txt.add(Line(format!("In 20 minute buckets:"))); ))
.secondary(),
);
txt.add(Line(format!("In 20 minute buckets:")).secondary());
rows.push(txt.draw(ctx)); rows.push(txt.draw(ctx));
let r = app.primary.map.get_l(id).parent; let r = app.primary.map.get_l(id).parent;

View File

@ -469,7 +469,7 @@ fn make_table<I: Into<String>>(ctx: &EventCtx, rows: Vec<(I, String)>) -> Vec<Wi
rows.into_iter() rows.into_iter()
.map(|(k, v)| { .map(|(k, v)| {
Widget::row(vec![ Widget::row(vec![
Line(k).roboto_bold().draw(ctx), Line(k).draw(ctx),
// TODO not quite... // TODO not quite...
v.draw_text(ctx).centered_vert().align_right(), v.draw_text(ctx).centered_vert().align_right(),
]) ])
@ -480,7 +480,7 @@ fn make_table<I: Into<String>>(ctx: &EventCtx, rows: Vec<(I, String)>) -> Vec<Wi
/*let mut keys = Text::new(); /*let mut keys = Text::new();
let mut values = Text::new(); let mut values = Text::new();
for (k, v) in rows { for (k, v) in rows {
keys.add(Line(k).roboto_bold()); keys.add(Line(k));
values.add(Line(v)); values.add(Line(v));
} }
vec![Widget::row(vec![ vec![Widget::row(vec![

View File

@ -3,10 +3,10 @@ use crate::colors;
use crate::helpers::ID; use crate::helpers::ID;
use crate::info::trip::trip_details; use crate::info::trip::trip_details;
use crate::info::InfoTab; use crate::info::InfoTab;
use ezgui::{EventCtx, Btn, Line, TextExt, Widget}; use ezgui::{Btn, EventCtx, Line, TextExt, Widget};
use map_model::Map;
use sim::{Person, TripMode, PersonID, PersonState, TripResult};
use geom::Time; use geom::Time;
use map_model::Map;
use sim::{Person, PersonID, PersonState, TripMode, TripResult};
use std::collections::HashMap; use std::collections::HashMap;
pub fn info( pub fn info(
@ -24,11 +24,11 @@ pub fn info(
// Header // Header
if let Some(btns) = header_btns { if let Some(btns) = header_btns {
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("Person #{}", id.0)).roboto_bold().draw(ctx), Line(format!("Person #{}", id.0)).small_heading().draw(ctx),
btns, btns,
])); ]));
} else { } else {
rows.push(Line(format!("Person #{}", id.0)).roboto_bold().draw(ctx)); rows.push(Line(format!("Person #{}", id.0)).small_heading().draw(ctx));
} }
// TODO None of these right now // TODO None of these right now
rows.extend(action_btns); rows.extend(action_btns);
@ -59,7 +59,7 @@ pub fn info(
} }
rows.push( rows.push(
Widget::col(vec![ Widget::col(vec![
Line(format!("Trip #{}", t.0)).roboto_bold().draw(ctx), Line(format!("Trip #{}", t.0)).small_heading().draw(ctx),
trip_details(ctx, app, *t, None, warpers).0, trip_details(ctx, app, *t, None, warpers).0,
]) ])
.bg(colors::SECTION_BG) .bg(colors::SECTION_BG)
@ -89,7 +89,12 @@ fn current_status(ctx: &EventCtx, person: &Person, map: &Map) -> Widget {
} }
} }
pub fn summary(ctx: &EventCtx, app: &App, id: PersonID, hyperlinks: &mut HashMap<String, (ID, InfoTab)>) -> Widget { pub fn summary(
ctx: &EventCtx,
app: &App,
id: PersonID,
hyperlinks: &mut HashMap<String, (ID, InfoTab)>,
) -> Widget {
let person = app.primary.sim.get_person(id); let person = app.primary.sim.get_person(id);
let mut next_trip: Option<(Time, TripMode)> = None; let mut next_trip: Option<(Time, TripMode)> = None;

View File

@ -29,7 +29,7 @@ pub fn inactive_info(
let mut rows = vec![]; let mut rows = vec![];
rows.push(Widget::row(vec![ rows.push(Widget::row(vec![
Line(format!("Trip #{}", id.0)).roboto_bold().draw(ctx), Line(format!("Trip #{}", id.0)).small_heading().draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build(ctx, "close info", hotkey(Key::Escape)) .build(ctx, "close info", hotkey(Key::Escape))
.align_right(), .align_right(),

View File

@ -68,7 +68,7 @@ impl WrappedComposite {
Composite::new( Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line(title.into()).roboto_bold().draw(ctx), Line(title.into()).small_heading().draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build_def(ctx, hotkey(Key::Escape)) .build_def(ctx, hotkey(Key::Escape))
.align_right(), .align_right(),

View File

@ -41,7 +41,7 @@ impl OptionsPanel {
composite: Composite::new( composite: Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line("Settings").roboto_bold().draw(ctx), Line("Settings").small_heading().draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build_def(ctx, hotkey(Key::Escape)) .build_def(ctx, hotkey(Key::Escape))
.align_right(), .align_right(),

View File

@ -76,7 +76,7 @@ pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
.build(ctx, "quit", hotkey(Key::Escape)) .build(ctx, "quit", hotkey(Key::Escape))
.align_left(), .align_left(),
{ {
let mut txt = Text::from(Line("A/B STREET").size(100)); let mut txt = Text::from(Line("A/B STREET").display_title());
txt.add(Line("Created by Dustin Carlino")); txt.add(Line("Created by Dustin Carlino"));
txt.draw(ctx).centered_horiz() txt.draw(ctx).centered_horiz()
}, },
@ -87,7 +87,7 @@ pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
) )
.tooltip({ .tooltip({
let mut txt = Text::tooltip(hotkey(Key::T), "Tutorial"); let mut txt = Text::tooltip(hotkey(Key::T), "Tutorial");
txt.add(Line("Learn how to play the game")); txt.add(Line("Learn how to play the game").small());
txt txt
}) })
.build(ctx, "Tutorial", hotkey(Key::T)), .build(ctx, "Tutorial", hotkey(Key::T)),
@ -97,7 +97,7 @@ pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
) )
.tooltip({ .tooltip({
let mut txt = Text::tooltip(hotkey(Key::S), "Sandbox"); let mut txt = Text::tooltip(hotkey(Key::S), "Sandbox");
txt.add(Line("No goals, try out any idea here")); txt.add(Line("No goals, try out any idea here").small());
txt txt
}) })
.build(ctx, "Sandbox mode", hotkey(Key::S)), .build(ctx, "Sandbox mode", hotkey(Key::S)),
@ -107,14 +107,14 @@ pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
) )
.tooltip({ .tooltip({
let mut txt = Text::tooltip(hotkey(Key::C), "Challenges"); let mut txt = Text::tooltip(hotkey(Key::C), "Challenges");
txt.add(Line("Fix specific problems")); txt.add(Line("Fix specific problems").small());
txt txt
}) })
.build(ctx, "Challenges", hotkey(Key::C)), .build(ctx, "Challenges", hotkey(Key::C)),
Btn::text_bg2("Community Proposals") Btn::text_bg2("Community Proposals")
.tooltip({ .tooltip({
let mut txt = Text::tooltip(hotkey(Key::P), "Community Proposals"); let mut txt = Text::tooltip(hotkey(Key::P), "Community Proposals");
txt.add(Line("See existing ideas for improving traffic")); txt.add(Line("See existing ideas for improving traffic").small());
txt txt
}) })
.build_def(ctx, hotkey(Key::P)), .build_def(ctx, hotkey(Key::P)),
@ -223,7 +223,7 @@ fn about(ctx: &mut EventCtx) -> Box<dyn State> {
.align_left(), .align_left(),
{ {
let mut txt = Text::new(); let mut txt = Text::new();
txt.add(Line("A/B STREET").size(50)); txt.add(Line("A/B STREET").display_title());
txt.add(Line("Created by Dustin Carlino, UX by Yuwen Li")); txt.add(Line("Created by Dustin Carlino, UX by Yuwen Li"));
txt.add(Line("")); txt.add(Line(""));
txt.add(Line("Contact: dabreegster@gmail.com")); txt.add(Line("Contact: dabreegster@gmail.com"));
@ -312,8 +312,8 @@ fn proposals_picker(ctx: &mut EventCtx) -> Box<dyn State> {
.build(ctx, "back", hotkey(Key::Escape)) .build(ctx, "back", hotkey(Key::Escape))
.align_left(), .align_left(),
{ {
let mut txt = Text::from(Line("A/B STREET").size(100)); let mut txt = Text::from(Line("A/B STREET").display_title());
txt.add(Line("PROPOSALS").size(50)); txt.add(Line("PROPOSALS").big_heading_styled());
txt.add(Line("")); txt.add(Line(""));
txt.add(Line( txt.add(Line(
"These are proposed changes to Seattle made by community members.", "These are proposed changes to Seattle made by community members.",

View File

@ -149,7 +149,7 @@ impl Renderable for DrawIntersection {
app.opts.traffic_signal_style.clone(), app.opts.traffic_signal_style.clone(),
); );
batch.add_transformed( batch.add_transformed(
Text::from(Line(format!("{}", idx + 1)).roboto()).render_to_batch(g.prerender), Text::from(Line(format!("{}", idx + 1))).render_to_batch(g.prerender),
app.primary.map.get_i(self.id).polygon.center(), app.primary.map.get_i(self.id).polygon.center(),
0.1, 0.1,
Angle::ZERO, Angle::ZERO,

View File

@ -221,7 +221,7 @@ pub fn make_signal_diagram(
let signal = app.primary.map.get_traffic_signal(i); let signal = app.primary.map.get_traffic_signal(i);
let txt_widget = { let txt_widget = {
let mut txt = Text::from(Line(format!("Intersection #{}", i.0)).roboto_bold()); let mut txt = Text::from(Line(format!("Intersection #{}", i.0)).big_heading_plain());
let mut road_names = BTreeSet::new(); let mut road_names = BTreeSet::new();
for r in &app.primary.map.get_i(i).roads { for r in &app.primary.map.get_i(i).roads {
@ -233,7 +233,7 @@ pub fn make_signal_diagram(
} }
txt.add(Line("")); txt.add(Line(""));
txt.add(Line(format!("{} phases", signal.phases.len())).roboto_bold()); txt.add(Line(format!("{} phases", signal.phases.len())).small_heading());
txt.add(Line(format!("Signal offset: {}", signal.offset))); txt.add(Line(format!("Signal offset: {}", signal.offset)));
txt.add(Line(format!("One cycle lasts {}", signal.cycle_length()))); txt.add(Line(format!("One cycle lasts {}", signal.cycle_length())));
txt.draw(ctx) txt.draw(ctx)

View File

@ -86,6 +86,7 @@ pub fn make(ctx: &mut EventCtx, app: &App, tab: Tab) -> Box<dyn State> {
ManagedGUIState::fullscreen(c) ManagedGUIState::fullscreen(c)
} }
// TODO Overhaul typography.
fn trips_summary_prebaked(ctx: &EventCtx, app: &App) -> Widget { fn trips_summary_prebaked(ctx: &EventCtx, app: &App) -> Widget {
if app.has_prebaked().is_none() { if app.has_prebaked().is_none() {
return trips_summary_not_prebaked(ctx, app); return trips_summary_not_prebaked(ctx, app);
@ -101,11 +102,10 @@ fn trips_summary_prebaked(ctx: &EventCtx, app: &App) -> Widget {
// TODO Include unfinished count // TODO Include unfinished count
let mut txt = Text::new(); let mut txt = Text::new();
txt.add_appended(vec![ txt.add(Line(format!(
Line("Trips as of "), "Trips as of {}",
Line(app.primary.sim.time().ampm_tostring()).roboto_bold(), app.primary.sim.time().ampm_tostring()
]); )));
txt.highlight_last_line(Color::BLUE);
txt.add_appended(vec![ txt.add_appended(vec![
Line(format!( Line(format!(
"{} aborted trips (", "{} aborted trips (",
@ -143,7 +143,6 @@ fn trips_summary_prebaked(ctx: &EventCtx, app: &App) -> Widget {
cmp_count_more(a.count(), b.count()), cmp_count_more(a.count(), b.count()),
Line(")"), Line(")"),
]); ]);
txt.highlight_last_line(Color::BLUE);
if a.count() > 0 && b.count() > 0 { if a.count() > 0 && b.count() > 0 {
for stat in Statistic::all() { for stat in Statistic::all() {
txt.add(Line(format!("{}: {} (", stat, a.select(stat)))); txt.add(Line(format!("{}: {} (", stat, a.select(stat))));
@ -165,7 +164,7 @@ fn trips_summary_prebaked(ctx: &EventCtx, app: &App) -> Widget {
ctx, ctx,
) )
.bg(colors::SECTION_BG), .bg(colors::SECTION_BG),
Line("Active agents").roboto_bold().draw(ctx), Line("Active agents").small_heading().draw(ctx),
Plot::new_usize( Plot::new_usize(
ctx, ctx,
vec![ vec![
@ -198,11 +197,10 @@ fn trips_summary_not_prebaked(ctx: &EventCtx, app: &App) -> Widget {
// TODO Include unfinished count // TODO Include unfinished count
let mut txt = Text::new(); let mut txt = Text::new();
txt.add_appended(vec![ txt.add(Line(format!(
Line("Trips as of "), "Trips as of {}",
Line(app.primary.sim.time().ampm_tostring()).roboto_bold(), app.primary.sim.time().ampm_tostring()
]); )));
txt.highlight_last_line(Color::BLUE);
txt.add(Line(format!( txt.add(Line(format!(
"{} aborted trips", "{} aborted trips",
prettyprint_usize(aborted) prettyprint_usize(aborted)
@ -224,7 +222,6 @@ fn trips_summary_not_prebaked(ctx: &EventCtx, app: &App) -> Widget {
prettyprint_usize(a.count()), prettyprint_usize(a.count()),
mode mode
))); )));
txt.highlight_last_line(Color::BLUE);
if a.count() > 0 { if a.count() > 0 {
for stat in Statistic::all() { for stat in Statistic::all() {
txt.add(Line(format!("{}: {}", stat, a.select(stat)))); txt.add(Line(format!("{}: {}", stat, a.select(stat))));
@ -235,7 +232,7 @@ fn trips_summary_not_prebaked(ctx: &EventCtx, app: &App) -> Widget {
Widget::col(vec![ Widget::col(vec![
txt.draw(ctx), txt.draw(ctx),
finished_trips_plot(ctx, app).bg(colors::SECTION_BG), finished_trips_plot(ctx, app).bg(colors::SECTION_BG),
Line("Active agents").roboto_bold().draw(ctx), Line("Active agents").small_heading().draw(ctx),
Plot::new_usize( Plot::new_usize(
ctx, ctx,
vec![Series { vec![Series {

View File

@ -9,7 +9,7 @@ use crate::sandbox::SandboxControls;
use crate::sandbox::SandboxMode; use crate::sandbox::SandboxMode;
use ezgui::{ use ezgui::{
hotkey, lctrl, Btn, Choice, Color, Composite, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, hotkey, lctrl, Btn, Choice, Color, Composite, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment,
Key, Line, ScreenRectangle, Text, VerticalAlignment, Widget, Key, Line, ScreenRectangle, Text, TextExt, VerticalAlignment, Widget,
}; };
use geom::Polygon; use geom::Polygon;
use map_model::IntersectionID; use map_model::IntersectionID;
@ -90,30 +90,20 @@ pub fn freeform_controller(
) -> WrappedComposite { ) -> WrappedComposite {
let c = Composite::new( let c = Composite::new(
Widget::row(vec![ Widget::row(vec![
Line("Sandbox").size(26).draw(ctx).margin(5), Line("Sandbox").small_heading().draw(ctx).margin(5),
Widget::draw_batch( Widget::draw_batch(
ctx, ctx,
GeomBatch::from(vec![(Color::WHITE, Polygon::rectangle(2.0, 50.0))]), GeomBatch::from(vec![(Color::WHITE, Polygon::rectangle(2.0, 50.0))]),
) )
.margin(5), .margin(5),
Text::from(Line("Map:").size(18).roboto_bold()) "Map:".draw_text(ctx).margin(5),
.draw(ctx) Btn::text_fg(format!("{}", nice_map_name(app.primary.map.get_name())))
.build(ctx, "change map", lctrl(Key::L))
.margin(5), .margin(5),
Btn::custom_text_fg(Text::from( "Traffic:".draw_text(ctx).margin(5),
Line(format!("{}", nice_map_name(app.primary.map.get_name()))) Btn::text_fg(format!("{}", scenario_name))
.size(18) .build(ctx, "change traffic", hotkey(Key::S))
.roboto(),
))
.build(ctx, "change map", lctrl(Key::L))
.margin(5),
Text::from(Line("Traffic:").size(18).roboto_bold())
.draw(ctx)
.margin(5), .margin(5),
Btn::custom_text_fg(Text::from(
Line(format!("{}", scenario_name)).size(18).roboto(),
))
.build(ctx, "change traffic", hotkey(Key::S))
.margin(5),
Btn::svg_def("../data/system/assets/tools/edit_map.svg") Btn::svg_def("../data/system/assets/tools/edit_map.svg")
.build(ctx, "edit map", lctrl(Key::E)) .build(ctx, "edit map", lctrl(Key::E))
.margin(5), .margin(5),

View File

@ -268,7 +268,7 @@ fn challenge_controller(
} }
let mut rows = vec![Widget::row(vec![ let mut rows = vec![Widget::row(vec![
Line(title).size(26).draw(ctx).margin(5), Line(title).small_heading().draw(ctx).margin(5),
Btn::svg_def("../data/system/assets/tools/info.svg") Btn::svg_def("../data/system/assets/tools/info.svg")
.build(ctx, "instructions", None) .build(ctx, "instructions", None)
.margin(5), .margin(5),
@ -319,7 +319,7 @@ impl FinalScore {
mode: GameplayMode, mode: GameplayMode,
next: Option<GameplayMode>, next: Option<GameplayMode>,
) -> Box<dyn State> { ) -> Box<dyn State> {
let mut txt = Text::from(Line("Final score").roboto_bold()); let mut txt = Text::from(Line("Final score").small_heading());
txt.add(Line(verdict)); txt.add(Line(verdict));
let row = vec![ let row = vec![

View File

@ -706,7 +706,7 @@ fn make_top_bar(ctx: &mut EventCtx, title: &str, howto: &str) -> Composite {
Composite::new( Composite::new(
Widget::col(vec![ Widget::col(vec![
Widget::row(vec![ Widget::row(vec![
Line(title).roboto_bold().draw(ctx), Line(title).small_heading().draw(ctx),
Btn::text_fg("X") Btn::text_fg("X")
.build_def(ctx, hotkey(Key::Escape)) .build_def(ctx, hotkey(Key::Escape))
.align_right(), .align_right(),

View File

@ -887,7 +887,7 @@ impl TutorialState {
fn make_top_center(&self, ctx: &mut EventCtx, edit_map: bool) -> Composite { fn make_top_center(&self, ctx: &mut EventCtx, edit_map: bool) -> Composite {
let mut col = vec![Widget::row(vec![ let mut col = vec![Widget::row(vec![
Line("Tutorial").size(26).draw(ctx).margin(5), Line("Tutorial").small_heading().draw(ctx).margin(5),
Widget::draw_batch( Widget::draw_batch(
ctx, ctx,
GeomBatch::from(vec![(Color::WHITE, Polygon::rectangle(2.0, 50.0))]), GeomBatch::from(vec![(Color::WHITE, Polygon::rectangle(2.0, 50.0))]),
@ -924,7 +924,7 @@ impl TutorialState {
self.current.stage + 1, self.current.stage + 1,
self.stage().task.label() self.stage().task.label()
)) ))
.roboto_bold(), .small_heading(),
) )
.draw(ctx), .draw(ctx),
// TODO also text saying "instructions"... can we layout two things easily to // TODO also text saying "instructions"... can we layout two things easily to
@ -981,7 +981,7 @@ impl TutorialState {
let mut col = vec![ let mut col = vec![
{ {
let mut txt = Text::new(); let mut txt = Text::new();
txt.add(Line(self.stage().task.label()).roboto_bold()); txt.add(Line(self.stage().task.label()).small_heading());
txt.add(Line("")); txt.add(Line(""));
for l in lines { for l in lines {

View File

@ -433,7 +433,7 @@ impl AgentMeter {
.get_analytics() .get_analytics()
.trip_times(app.primary.sim.time()); .trip_times(app.primary.sim.time());
let (baseline, _, _) = app.prebaked().trip_times(app.primary.sim.time()); let (baseline, _, _) = app.prebaked().trip_times(app.primary.sim.time());
let mut txt = Text::from(Line(format!("{} trip time: ", stat)).size(20)); let mut txt = Text::from(Line(format!("{} trip time: ", stat)).secondary());
if now.count() > 0 && baseline.count() > 0 { if now.count() > 0 && baseline.count() > 0 {
txt.append_all(cmp_duration_shorter( txt.append_all(cmp_duration_shorter(
now.select(stat), now.select(stat),
@ -442,7 +442,7 @@ impl AgentMeter {
} else { } else {
txt.append(Line("same as baseline")); txt.append(Line("same as baseline"));
} }
txt.add(Line(format!("Goal: {} faster", goal)).size(20)); txt.add(Line(format!("Goal: {} faster", goal)).secondary());
rows.push(txt.draw(ctx)); rows.push(txt.draw(ctx));
} }
} }

View File

@ -65,7 +65,7 @@ impl SpeedControls {
] ]
.into_iter() .into_iter()
.map(|(s, label)| { .map(|(s, label)| {
let mut txt = Text::from(Line(label).size(20)); let mut txt = Text::from(Line(label).small());
txt.extend(Text::tooltip(hotkey(Key::LeftArrow), "slow down")); txt.extend(Text::tooltip(hotkey(Key::LeftArrow), "slow down"));
txt.extend(Text::tooltip(hotkey(Key::RightArrow), "speed up")); txt.extend(Text::tooltip(hotkey(Key::RightArrow), "speed up"));
@ -96,26 +96,19 @@ impl SpeedControls {
Widget::row( Widget::row(
vec![ vec![
Btn::custom( Btn::custom(
Text::from(Line("+1h").fg(Color::WHITE).size(21).roboto()).render_ctx(ctx), Text::from(Line("+1h").fg(Color::WHITE)).render_ctx(ctx),
Text::from(Line("+1h").fg(colors::HOVERING).size(21).roboto()) Text::from(Line("+1h").fg(colors::HOVERING)).render_ctx(ctx),
.render_ctx(ctx),
{ {
let dims = Text::from(Line("+1h").size(21).roboto()) let dims = Text::from(Line("+1h")).render_ctx(ctx).get_dims();
.render_ctx(ctx)
.get_dims();
Polygon::rectangle(dims.width, dims.height) Polygon::rectangle(dims.width, dims.height)
}, },
) )
.build(ctx, "step forwards 1 hour", hotkey(Key::N)), .build(ctx, "step forwards 1 hour", hotkey(Key::N)),
Btn::custom( Btn::custom(
Text::from(Line("+0.1s").fg(Color::WHITE).size(21).roboto()) Text::from(Line("+0.1s").fg(Color::WHITE)).render_ctx(ctx),
.render_ctx(ctx), Text::from(Line("+0.1s").fg(colors::HOVERING)).render_ctx(ctx),
Text::from(Line("+0.1s").fg(colors::HOVERING).size(21).roboto())
.render_ctx(ctx),
{ {
let dims = Text::from(Line("+0.1s").size(21).roboto()) let dims = Text::from(Line("+0.1s")).render_ctx(ctx).get_dims();
.render_ctx(ctx)
.get_dims();
Polygon::rectangle(dims.width, dims.height) Polygon::rectangle(dims.width, dims.height)
}, },
) )
@ -355,7 +348,7 @@ impl JumpToTime {
.build_def(ctx, hotkey(Key::Escape)) .build_def(ctx, hotkey(Key::Escape))
.align_right(), .align_right(),
{ {
let mut txt = Text::from(Line("Jump to what time?").roboto_bold()); let mut txt = Text::from(Line("Jump to what time?").small_heading());
txt.add(Line(target.ampm_tostring())); txt.add(Line(target.ampm_tostring()));
txt.draw(ctx) txt.draw(ctx)
} }
@ -370,11 +363,11 @@ impl JumpToTime {
.named("time slider") .named("time slider")
.margin(10), .margin(10),
Widget::row(vec![ Widget::row(vec![
Line("00:00").size(12).roboto().draw(ctx), Line("00:00").small().draw(ctx),
Widget::draw_svg(ctx, "../data/system/assets/speed/sunrise.svg"), Widget::draw_svg(ctx, "../data/system/assets/speed/sunrise.svg"),
Line("12:00").size(12).roboto().draw(ctx), Line("12:00").small().draw(ctx),
Widget::draw_svg(ctx, "../data/system/assets/speed/sunset.svg"), Widget::draw_svg(ctx, "../data/system/assets/speed/sunset.svg"),
Line("24:00").size(12).roboto().draw(ctx), Line("24:00").small().draw(ctx),
]) ])
.padding(10) .padding(10)
.evenly_spaced(), .evenly_spaced(),
@ -384,7 +377,7 @@ impl JumpToTime {
Btn::text_bg2("Go!") Btn::text_bg2("Go!")
.build_def(ctx, hotkey(Key::Enter)) .build_def(ctx, hotkey(Key::Enter))
.centered_horiz(), .centered_horiz(),
Line("Active agents").roboto_bold().draw(ctx), Line("Active agents").small_heading().draw(ctx),
// TODO Sync the slider / plot. // TODO Sync the slider / plot.
Plot::new_usize( Plot::new_usize(
ctx, ctx,
@ -459,7 +452,7 @@ impl State for JumpToTime {
ctx, ctx,
"target time", "target time",
{ {
let mut txt = Text::from(Line("Jump to what time?").roboto_bold()); let mut txt = Text::from(Line("Jump to what time?").small_heading());
txt.add(Line(target.ampm_tostring())); txt.add(Line(target.ampm_tostring()));
// TODO The panel jumps too much and the slider position changes place. // TODO The panel jumps too much and the slider position changes place.
/*if target < app.primary.sim.time() { /*if target < app.primary.sim.time() {
@ -540,7 +533,7 @@ impl State for TimeWarpScreen {
// TODO secondary for a/b test mode // TODO secondary for a/b test mode
// I'm covered in shame for not doing this from the start. // I'm covered in shame for not doing this from the start.
let mut txt = Text::from(Line("Let's do the time warp again!").roboto_bold()); let mut txt = Text::from(Line("Let's do the time warp again!").small_heading());
txt.add(Line(format!( txt.add(Line(format!(
"Simulating until it's {}", "Simulating until it's {}",
self.target.ampm_tostring() self.target.ampm_tostring()
@ -600,7 +593,7 @@ impl TimePanel {
time: app.primary.sim.time(), time: app.primary.sim.time(),
composite: Composite::new( composite: Composite::new(
Widget::col(vec![ Widget::col(vec![
Text::from(Line(app.primary.sim.time().ampm_tostring()).size(30)) Text::from(Line(app.primary.sim.time().ampm_tostring()).big_heading_styled())
.draw(ctx) .draw(ctx)
.margin(10) .margin(10)
.centered_horiz(), .centered_horiz(),
@ -633,11 +626,11 @@ impl TimePanel {
Widget::draw_batch(ctx, batch) Widget::draw_batch(ctx, batch)
}, },
Widget::row(vec![ Widget::row(vec![
Line("00:00").size(12).roboto().draw(ctx), Line("00:00").small().draw(ctx),
Widget::draw_svg(ctx, "../data/system/assets/speed/sunrise.svg"), Widget::draw_svg(ctx, "../data/system/assets/speed/sunrise.svg"),
Line("12:00").size(12).roboto().draw(ctx), Line("12:00").small().draw(ctx),
Widget::draw_svg(ctx, "../data/system/assets/speed/sunset.svg"), Widget::draw_svg(ctx, "../data/system/assets/speed/sunset.svg"),
Line("24:00").size(12).roboto().draw(ctx), Line("24:00").small().draw(ctx),
]) ])
.padding(10) .padding(10)
.evenly_spaced(), .evenly_spaced(),

View File

@ -81,7 +81,7 @@ impl UI {
state: State::viewing(), state: State::viewing(),
composite: Composite::new( composite: Composite::new(
Widget::col(vec![ Widget::col(vec![
Line("Map Editor").roboto_bold().draw(ctx), Line("Map Editor").small_heading().draw(ctx),
Text::new().draw(ctx).named("current info"), Text::new().draw(ctx).named("current info"),
Widget::col( Widget::col(
vec![ vec![