clean up text_dims, then unplumb a BUNCH of stuff

This commit is contained in:
Dustin Carlino 2020-02-06 17:40:04 -08:00
parent 9355bcf5fd
commit 95c1f47047
21 changed files with 69 additions and 101 deletions

View File

@ -1,4 +1,3 @@
use crate::{ScreenDims, Text};
use glium_glyph::glyph_brush::FontId;
// TODO We don't need refcell maybe
@ -17,10 +16,6 @@ impl Assets {
a
}
pub fn text_dims(&self, txt: &Text) -> ScreenDims {
txt.dims(self)
}
// Don't call this while screenspace_glyphs is mutably borrowed.
pub fn line_height(&self, _: FontId, font_size: usize) -> f64 {
// TODO Ahhh this stops working.

View File

@ -232,7 +232,7 @@ impl<'a> GfxCtx<'a> {
txt: &Text,
(horiz, vert): (HorizontalAlignment, VerticalAlignment),
) {
let mut dims = self.text_dims(&txt);
let mut dims = txt.dims();
let top_left = self.canvas.align_window(dims, horiz, vert);
// TODO This doesn't take effect anymore
if let HorizontalAlignment::FillScreen = horiz {
@ -257,7 +257,7 @@ impl<'a> GfxCtx<'a> {
// TODO Rename these draw_nonblocking_text_*
pub fn draw_text_at(&mut self, txt: &Text, map_pt: Pt2D) {
let dims = self.text_dims(&txt);
let dims = txt.dims();
let pt = self.canvas.map_to_screen(map_pt);
let mut batch = GeomBatch::new();
txt.clone().render(
@ -270,7 +270,7 @@ impl<'a> GfxCtx<'a> {
}
pub fn draw_text_at_mapspace(&mut self, txt: &Text, map_pt: Pt2D) {
let dims = self.text_dims(&txt);
let dims = txt.dims();
let mut batch = GeomBatch::new();
txt.clone().render(
&mut batch,
@ -283,7 +283,7 @@ impl<'a> GfxCtx<'a> {
}
pub fn draw_mouse_tooltip(&mut self, txt: &Text) {
let dims = self.text_dims(&txt);
let dims = txt.dims();
// TODO Maybe also consider the cursor as a valid center
let pt = dims.top_left_for_corner(
ScreenPt::new(self.canvas.cursor_x, self.canvas.cursor_y),
@ -330,9 +330,6 @@ impl<'a> GfxCtx<'a> {
pub fn default_line_height(&self) -> f64 {
self.assets.default_line_height
}
pub fn text_dims(&self, txt: &Text) -> ScreenDims {
self.assets.text_dims(txt)
}
}
#[derive(Clone)]

View File

@ -160,9 +160,6 @@ impl<'a> EventCtx<'a> {
pub fn default_line_height(&self) -> f64 {
self.assets.default_line_height
}
pub fn text_dims(&self, txt: &Text) -> ScreenDims {
self.assets.text_dims(txt)
}
}
pub struct LoadingScreen<'a> {

View File

@ -1,4 +1,3 @@
use crate::assets::Assets;
use crate::{Color, GeomBatch, ScreenDims, ScreenPt, ScreenRectangle};
use geom::Polygon;
use glium_glyph::glyph_brush::FontId;
@ -182,7 +181,7 @@ impl Text {
self.lines.extend(other.lines.clone())
}
pub(crate) fn dims(&self, _: &Assets) -> ScreenDims {
pub(crate) fn dims(&self) -> ScreenDims {
// TODO Still pay attention to this hack, so the loading screen isn't dreadfully slow
if let Some(w) = self.override_width {
return ScreenDims::new(w, self.override_height.unwrap());

View File

@ -220,7 +220,7 @@ impl Button {
const HORIZ_PADDING: f64 = 30.0;
const VERT_PADDING: f64 = 10.0;
let dims = ctx.text_dims(&text);
let dims = text.dims();
let geom = Polygon::rounded_rectangle(
dims.width + 2.0 * HORIZ_PADDING,
dims.height + 2.0 * VERT_PADDING,
@ -255,8 +255,8 @@ impl Button {
let horiz_padding = if padding { 15.0 } else { 0.0 };
let vert_padding = if padding { 8.0 } else { 0.0 };
let dims = ctx.text_dims(&unselected_text);
assert_eq!(dims, ctx.text_dims(&selected_text));
let dims = unselected_text.dims();
assert_eq!(dims, selected_text.dims());
let geom = Polygon::rectangle(
dims.width + 2.0 * horiz_padding,
dims.height + 2.0 * vert_padding,
@ -281,7 +281,7 @@ impl Button {
let horiz_padding = 15.0;
let vert_padding = 8.0;
txt = txt.change_fg(Color::grey(0.5));
let dims = ctx.text_dims(&txt);
let dims = txt.dims();
let mut draw = DrawBoth::new(
ctx,
@ -306,7 +306,7 @@ impl Button {
const VERT_PADDING: f64 = 10.0;
let txt = Text::from(Line(label).fg(Color::BLACK));
let dims = ctx.text_dims(&txt);
let dims = txt.dims();
let geom = Polygon::rounded_rectangle(
dims.width + 2.0 * HORIZ_PADDING,
dims.height + 2.0 * VERT_PADDING,

View File

@ -26,7 +26,7 @@ impl ModalMenu {
pub fn new<S1: Into<String>, S2: Into<String>>(
title: S1,
raw_choices: Vec<(Option<MultiKey>, S2)>,
ctx: &EventCtx,
_: &EventCtx,
) -> ModalMenu {
let mut m = ModalMenu {
title: title.into(),
@ -46,7 +46,7 @@ impl ModalMenu {
top_left: ScreenPt::new(0.0, 0.0),
dims: ScreenDims::new(0.0, 0.0),
};
m.recalculate_dims(ctx);
m.dims = m.calculate_txt().dims();
m
}
@ -63,9 +63,9 @@ impl ModalMenu {
self
}
pub fn set_info(&mut self, ctx: &EventCtx, info: Text) {
pub fn set_info(&mut self, info: Text) {
self.info = info.with_bg();
self.recalculate_dims(ctx);
self.dims = self.calculate_txt().dims();
}
pub fn event(&mut self, ctx: &mut EventCtx) {
@ -75,7 +75,7 @@ impl ModalMenu {
if let Some(o) = self.standalone_layout {
layout::stack_vertically(o, ctx, vec![self]);
self.recalculate_dims(ctx);
self.dims = self.calculate_txt().dims();
}
// Handle the mouse
@ -83,7 +83,7 @@ impl ModalMenu {
self.hovering_idx = None;
if let Some(cursor) = ctx.canvas.get_cursor_in_screen_space() {
let mut top_left = self.top_left;
top_left.y += ctx.text_dims(&self.info).height;
top_left.y += self.info.dims().height;
if !self.title.is_empty() {
top_left.y += ctx.default_line_height();
}
@ -127,54 +127,54 @@ impl ModalMenu {
}
}
pub fn push_action(&mut self, hotkey: Option<MultiKey>, label: &str, ctx: &EventCtx) {
pub fn push_action(&mut self, hotkey: Option<MultiKey>, label: &str) {
self.choices.push(Choice {
hotkey,
label: label.to_string(),
active: false,
});
self.recalculate_dims(ctx);
self.dims = self.calculate_txt().dims();
}
pub fn remove_action(&mut self, label: &str, ctx: &EventCtx) {
pub fn remove_action(&mut self, label: &str) {
self.choices.retain(|c| c.label != label);
self.recalculate_dims(ctx);
self.dims = self.calculate_txt().dims();
}
pub fn change_action(&mut self, old_label: &str, new_label: &str, ctx: &EventCtx) {
pub fn change_action(&mut self, old_label: &str, new_label: &str) {
for c in self.choices.iter_mut() {
if c.label == old_label {
c.label = new_label.to_string();
self.recalculate_dims(ctx);
self.dims = self.calculate_txt().dims();
return;
}
}
panic!("Menu doesn't have {}", old_label);
}
pub fn maybe_change_action(&mut self, old_label: &str, new_label: &str, ctx: &EventCtx) {
pub fn maybe_change_action(&mut self, old_label: &str, new_label: &str) {
for c in self.choices.iter_mut() {
if c.label == old_label {
c.label = new_label.to_string();
self.recalculate_dims(ctx);
self.dims = self.calculate_txt().dims();
return;
}
}
// Don't panic
}
pub fn swap_action(&mut self, old_label: &str, new_label: &str, ctx: &EventCtx) -> bool {
pub fn swap_action(&mut self, old_label: &str, new_label: &str) -> bool {
if self.action(old_label) {
self.change_action(old_label, new_label, ctx);
self.change_action(old_label, new_label);
true
} else {
false
}
}
pub fn consume_action(&mut self, name: &str, ctx: &EventCtx) -> bool {
pub fn consume_action(&mut self, name: &str) -> bool {
if self.action(name) {
self.remove_action(name, ctx);
self.remove_action(name);
true
} else {
false
@ -203,10 +203,6 @@ impl ModalMenu {
g.draw_blocking_text_at_screenspace_topleft(&self.calculate_txt(), self.top_left);
}
fn recalculate_dims(&mut self, ctx: &EventCtx) {
self.dims = ctx.text_dims(&self.calculate_txt());
}
fn calculate_txt(&self) -> Text {
let mut txt = if self.title.is_empty() {
Text::new().with_bg()

View File

@ -18,7 +18,7 @@ pub struct PopupMenu<T: Clone> {
}
impl<T: Clone> PopupMenu<T> {
pub fn new(choices: Vec<Choice<T>>, ctx: &EventCtx) -> PopupMenu<T> {
pub fn new(choices: Vec<Choice<T>>) -> PopupMenu<T> {
let mut m = PopupMenu {
choices,
current_idx: 0,
@ -28,7 +28,7 @@ impl<T: Clone> PopupMenu<T> {
top_left: ScreenPt::new(0.0, 0.0),
dims: ScreenDims::new(0.0, 0.0),
};
m.recalculate_dims(ctx);
m.dims = m.calculate_txt().dims();
m
}
@ -126,10 +126,6 @@ impl<T: Clone> PopupMenu<T> {
&self.choices[self.current_idx].data
}
fn recalculate_dims(&mut self, ctx: &EventCtx) {
self.dims = ctx.text_dims(&self.calculate_txt());
}
fn calculate_txt(&self) -> Text {
let mut txt = Text::new();

View File

@ -294,7 +294,7 @@ impl<T> ItemSlider<T> {
abstutil::prettyprint_usize(self.items.len())
)));
txt.extend(&self.items[idx].1);
self.menu.set_info(ctx, txt);
self.menu.set_info(txt);
self.menu.event(ctx);
}
stack_vertically(
@ -432,8 +432,8 @@ impl SliderWithTextBox {
pub fn new(prompt: &str, low: Time, high: Time, ctx: &EventCtx) -> SliderWithTextBox {
SliderWithTextBox {
// TODO Some ratio based on low and high difference
slider: Slider::horizontal(ctx, ctx.text_dims(&Text::from(Line(prompt))).width, 25.0),
tb: TextBox::new(prompt, Some(low.to_string()), ctx),
slider: Slider::horizontal(ctx, Text::from(Line(prompt)).dims().width, 25.0),
tb: TextBox::new(prompt, Some(low.to_string())),
low,
high,
}

View File

@ -1,7 +1,5 @@
use crate::layout::Widget;
use crate::{
text, Event, EventCtx, GfxCtx, InputResult, Key, Line, ScreenDims, ScreenPt, Text, UserInput,
};
use crate::{text, Event, GfxCtx, InputResult, Key, Line, ScreenDims, ScreenPt, Text, UserInput};
// TODO right now, only a single line
@ -17,7 +15,7 @@ pub struct TextBox {
}
impl TextBox {
pub fn new(prompt: &str, prefilled: Option<String>, ctx: &EventCtx) -> TextBox {
pub fn new(prompt: &str, prefilled: Option<String>) -> TextBox {
let line = prefilled.unwrap_or_else(String::new);
let mut tb = TextBox {
prompt: prompt.to_string(),
@ -29,7 +27,7 @@ impl TextBox {
dims: ScreenDims::new(0.0, 0.0),
};
// TODO Assume the dims never exceed the prompt width?
tb.dims = ctx.text_dims(&tb.get_text());
tb.dims = tb.get_text().dims();
tb
}

View File

@ -89,7 +89,7 @@ impl Wizard {
}
if self.tb.is_none() {
self.tb = Some(TextBox::new(query, prefilled, ctx));
self.tb = Some(TextBox::new(query, prefilled));
}
layout::stack_vertically(
layout::ContainerOrientation::Centered,
@ -302,7 +302,6 @@ impl<'a, 'b> WrappedWizard<'a, 'b> {
active: c.active,
})
.collect(),
self.ctx,
),
)
.build(self.ctx),

View File

@ -82,7 +82,7 @@ impl State for ABTestMode {
by_mode[&TripMode::Drive],
by_mode[&TripMode::Transit]
)));
self.menu.set_info(ctx, txt);
self.menu.set_info(txt);
}
self.menu.event(ctx);

View File

@ -72,7 +72,7 @@ fn pick_ab_test(wiz: &mut Wizard, ctx: &mut EventCtx, ui: &mut UI) -> Option<Tra
for line in ab_test.describe() {
txt.add(Line(line));
}
menu.set_info(ctx, txt);
menu.set_info(txt);
Some(Transition::Replace(Box::new(ABTestSetup { menu, ab_test })))
}

View File

@ -60,10 +60,10 @@ impl Floodfiller {
}
let mut menu = ModalMenu::new(title, vec![(hotkey(Key::Escape), "quit")], ctx);
menu.set_info(
ctx,
Text::from(Line(format!("{} unreachable lanes", num_unreachable))),
);
menu.set_info(Text::from(Line(format!(
"{} unreachable lanes",
num_unreachable
))));
Some(Box::new(Floodfiller {
menu,

View File

@ -81,7 +81,7 @@ impl State for DebugMode {
if let routes::AllRoutesViewer::Active(_, ref traces) = self.all_routes {
txt.add(Line(format!("Showing {} routes", traces.len())));
}
self.menu.set_info(ctx, txt);
self.menu.set_info(txt);
}
self.menu.event(ctx);
@ -151,14 +151,13 @@ impl State for DebugMode {
println!("Hiding {:?}", id);
ui.primary.current_selection = None;
if self.hidden.is_empty() {
self.menu
.push_action(hotkey(Key::H), "unhide everything", ctx);
self.menu.push_action(hotkey(Key::H), "unhide everything");
}
self.hidden.insert(id);
}
}
None => {
if !self.hidden.is_empty() && self.menu.consume_action("unhide everything", ctx) {
if !self.hidden.is_empty() && self.menu.consume_action("unhide everything") {
self.hidden.clear();
ui.primary.current_selection =
ui.calculate_current_selection(ctx, &ui.primary.sim, self, true);
@ -206,10 +205,10 @@ impl State for DebugMode {
let show = format!("show {}", label);
let hide = format!("hide {}", label);
if *value && self.menu.swap_action(&hide, &show, ctx) {
if *value && self.menu.swap_action(&hide, &show) {
*value = false;
changed = true;
} else if !*value && self.menu.swap_action(&show, &hide, ctx) {
} else if !*value && self.menu.swap_action(&show, &hide) {
*value = true;
changed = true;
}
@ -235,13 +234,13 @@ impl State for DebugMode {
if self.search_results.is_some() {
if self
.menu
.swap_action("clear OSM search results", "search OSM metadata", ctx)
.swap_action("clear OSM search results", "search OSM metadata")
{
self.search_results = None;
}
} else if self
.menu
.swap_action("search OSM metadata", "clear OSM search results", ctx)
.swap_action("search OSM metadata", "clear OSM search results")
{
// TODO If the wizard aborts (pressing escape), this crashes.
return Transition::Push(WizardState::new(Box::new(search_osm)));

View File

@ -10,18 +10,18 @@ pub enum AllRoutesViewer {
}
impl AllRoutesViewer {
pub fn event(&mut self, ui: &mut UI, menu: &mut ModalMenu, ctx: &EventCtx) {
pub fn event(&mut self, ui: &mut UI, menu: &mut ModalMenu, _: &EventCtx) {
let show = "show route for all agents";
let hide = "hide route for all agents";
match self {
AllRoutesViewer::Inactive => {
if menu.swap_action(show, hide, ctx) {
if menu.swap_action(show, hide) {
*self = debug_all_routes(ui);
}
}
AllRoutesViewer::Active(time, _) => {
if menu.swap_action(hide, show, ctx) {
if menu.swap_action(hide, show) {
*self = AllRoutesViewer::Inactive;
} else if *time != ui.primary.sim.time() {
*self = debug_all_routes(ui);

View File

@ -101,7 +101,7 @@ impl State for TripsVisualizer {
"{} active trips",
prettyprint_usize(self.active_trips.len())
)));
self.menu.set_info(ctx, txt);
self.menu.set_info(txt);
}
self.menu.event(ctx);
ctx.canvas_movement();

View File

@ -159,7 +159,7 @@ impl State for ScenarioManager {
"{} parking spots",
prettyprint_usize(self.total_parking_spots),
)));
self.menu.set_info(ctx, txt);
self.menu.set_info(txt);
}
self.menu.event(ctx);
ctx.canvas_movement();
@ -183,7 +183,7 @@ impl State for ScenarioManager {
return Transition::Push(Box::new(DotMap::new(ctx, ui, &self.scenario)));
}
if self.demand.is_some() && self.menu.consume_action("stop showing paths", ctx) {
if self.demand.is_some() && self.menu.consume_action("stop showing paths") {
self.demand = None;
}
@ -206,8 +206,7 @@ impl State for ScenarioManager {
&& ui.per_obj.action(ctx, Key::P, "show trips to and from")
{
self.demand = Some(show_demand(&self.scenario, from, to, OD::Bldg(b), ui, ctx));
self.menu
.push_action(hotkey(Key::P), "stop showing paths", ctx);
self.menu.push_action(hotkey(Key::P), "stop showing paths");
}
}
} else if let Some(ID::Intersection(i)) = ui.primary.current_selection {
@ -236,8 +235,7 @@ impl State for ScenarioManager {
ui,
ctx,
));
self.menu
.push_action(hotkey(Key::P), "stop showing paths", ctx);
self.menu.push_action(hotkey(Key::P), "stop showing paths");
}
}
}

View File

@ -44,7 +44,6 @@ impl GameplayState for CreateGridlock {
self.menu.event(ctx);
manage_acs(
&mut self.menu,
ctx,
ui,
"show agent delay",
"hide agent delay",
@ -53,7 +52,7 @@ impl GameplayState for CreateGridlock {
if self.time != ui.primary.sim.time() {
self.time = ui.primary.sim.time();
self.menu.set_info(ctx, gridlock_panel(ui));
self.menu.set_info(gridlock_panel(ui));
}
None

View File

@ -45,7 +45,7 @@ impl GameplayState for FasterTrips {
if self.time != ui.primary.sim.time() {
self.time = ui.primary.sim.time();
self.menu.set_info(ctx, faster_trips_panel(self.mode, ui));
self.menu.set_info(faster_trips_panel(self.mode, ui));
}
None

View File

@ -197,7 +197,6 @@ impl GameplayMode {
// thing.
fn manage_overlays(
menu: &mut ModalMenu,
ctx: &mut EventCtx,
ui: &mut UI,
show: &str,
hide: &str,
@ -205,14 +204,14 @@ fn manage_overlays(
) -> bool {
// Synchronize menus if needed. Player can change these separately.
if active_originally {
menu.maybe_change_action(show, hide, ctx);
menu.maybe_change_action(show, hide);
} else {
menu.maybe_change_action(hide, show, ctx);
menu.maybe_change_action(hide, show);
}
if !active_originally && menu.swap_action(show, hide, ctx) {
if !active_originally && menu.swap_action(show, hide) {
true
} else if active_originally && menu.swap_action(hide, show, ctx) {
} else if active_originally && menu.swap_action(hide, show) {
ui.overlay = Overlays::Inactive;
false
} else {
@ -223,7 +222,6 @@ fn manage_overlays(
// Must call menu.event first.
fn manage_acs(
menu: &mut ModalMenu,
ctx: &mut EventCtx,
ui: &mut UI,
show: &str,
hide: &str,
@ -233,14 +231,14 @@ fn manage_acs(
// Synchronize menus if needed. Player can change these separately.
if active_originally {
menu.maybe_change_action(show, hide, ctx);
menu.maybe_change_action(show, hide);
} else {
menu.maybe_change_action(hide, show, ctx);
menu.maybe_change_action(hide, show);
}
if !active_originally && menu.swap_action(show, hide, ctx) {
if !active_originally && menu.swap_action(show, hide) {
ui.agent_cs = AgentColorScheme::new(acs, &ui.cs);
} else if active_originally && menu.swap_action(hide, show, ctx) {
} else if active_originally && menu.swap_action(hide, show) {
ui.agent_cs = AgentColorScheme::default(&ui.cs);
}
}

View File

@ -59,7 +59,6 @@ impl GameplayState for OptimizeBus {
self.menu.event(ctx);
if manage_overlays(
&mut self.menu,
ctx,
ui,
"show bus route",
"hide bus route",
@ -72,7 +71,6 @@ impl GameplayState for OptimizeBus {
}
if manage_overlays(
&mut self.menu,
ctx,
ui,
"show delays over time",
"hide delays over time",
@ -85,7 +83,6 @@ impl GameplayState for OptimizeBus {
}
if manage_overlays(
&mut self.menu,
ctx,
ui,
"show bus passengers",
"hide bus passengers",
@ -101,7 +98,7 @@ impl GameplayState for OptimizeBus {
if self.time != ui.primary.sim.time() {
self.time = ui.primary.sim.time();
self.menu
.set_info(ctx, bus_route_panel(self.route, self.stat, ui));
.set_info(bus_route_panel(self.route, self.stat, ui));
}
if self.menu.action("change statistic") {