Move some misc stuff from game/common to map_gui, so LTN can use it

LTN crate builds, and appears to work!
This commit is contained in:
Dustin Carlino 2022-01-18 16:10:29 +00:00
parent 8dc2c68760
commit a6cd58346f
13 changed files with 132 additions and 120 deletions

View File

@ -1,9 +1,7 @@
use std::cmp::Ordering;
use std::collections::BTreeSet;
use geom::{Distance, Duration, Polygon, Time};
use geom::{Duration, Polygon, Time};
use map_gui::ID;
use map_model::{IntersectionID, Map, RoadID};
use sim::{AgentType, TripMode, TripPhaseType};
use widgetry::{
lctrl, Color, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, Panel, ScreenDims,
@ -13,7 +11,6 @@ use widgetry::{
pub use self::route_sketcher::RouteSketcher;
pub use self::select::RoadSelector;
pub use self::warp::{warp_to_id, Warping};
pub use self::waypoints::{InputWaypoints, WaypointID};
use crate::app::App;
use crate::app::Transition;
use crate::info::{ContextualActions, InfoPanel, Tab};
@ -23,7 +20,6 @@ mod route_sketcher;
mod select;
pub mod share;
mod warp;
mod waypoints;
// TODO This is now just used in two modes...
pub struct CommonState {
@ -370,55 +366,6 @@ pub fn cmp_duration_shorter(app: &App, after: Duration, before: Duration) -> Vec
}
}
/// Shorter is better
pub fn cmp_dist(txt: &mut Text, app: &App, dist: Distance, shorter: &str, longer: &str) {
match dist.cmp(&Distance::ZERO) {
Ordering::Less => {
txt.add_line(
Line(format!(
"{} {}",
(-dist).to_string(&app.opts.units),
shorter
))
.fg(Color::GREEN),
);
}
Ordering::Greater => {
txt.add_line(
Line(format!("{} {}", dist.to_string(&app.opts.units), longer)).fg(Color::RED),
);
}
Ordering::Equal => {}
}
}
/// Shorter is better
pub fn cmp_duration(txt: &mut Text, app: &App, duration: Duration, shorter: &str, longer: &str) {
match duration.cmp(&Duration::ZERO) {
Ordering::Less => {
txt.add_line(
Line(format!(
"{} {}",
(-duration).to_string(&app.opts.units),
shorter
))
.fg(Color::GREEN),
);
}
Ordering::Greater => {
txt.add_line(
Line(format!(
"{} {}",
duration.to_string(&app.opts.units),
longer
))
.fg(Color::RED),
);
}
Ordering::Equal => {}
}
}
pub fn color_for_mode(app: &App, m: TripMode) -> Color {
match m {
TripMode::Walk => app.cs.unzoomed_pedestrian,
@ -451,22 +398,6 @@ pub fn color_for_trip_phase(app: &App, tpt: TripPhaseType) -> Color {
}
}
pub fn intersections_from_roads(roads: &BTreeSet<RoadID>, map: &Map) -> BTreeSet<IntersectionID> {
let mut results = BTreeSet::new();
for r in roads {
let r = map.get_r(*r);
for i in [r.src_i, r.dst_i] {
if results.contains(&i) {
continue;
}
if map.get_i(i).roads.iter().all(|r| roads.contains(r)) {
results.insert(i);
}
}
}
results
}
pub fn checkbox_per_mode(
ctx: &mut EventCtx,
app: &App,
@ -511,28 +442,3 @@ pub fn jump_to_time_upon_startup(
})
})
}
pub fn percentage_bar(ctx: &EventCtx, txt: Text, pct_green: f64) -> Widget {
let bad_color = Color::RED;
let good_color = Color::GREEN;
let total_width = 450.0;
let height = 32.0;
let radius = 4.0;
let mut batch = GeomBatch::new();
// Background
batch.push(
bad_color,
Polygon::rounded_rectangle(total_width, height, radius),
);
// Foreground
if let Some(poly) = Polygon::maybe_rounded_rectangle(pct_green * total_width, height, radius) {
batch.push(good_color, poly);
}
// Text
let label = txt.render_autocropped(ctx);
let dims = label.get_dims();
batch.append(label.translate(10.0, height / 2.0 - dims.height / 2.0));
batch.into_widget(ctx)
}

View File

@ -1,11 +1,12 @@
use std::collections::BTreeSet;
use map_gui::tools::intersections_from_roads;
use map_gui::ID;
use map_model::{IntersectionID, RoadID};
use widgetry::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, Key, RewriteColor, Widget};
use crate::app::App;
use crate::common::{intersections_from_roads, CommonState};
use crate::common::CommonState;
/// A tool for selecting multiple roads.
pub struct RoadSelector {

View File

@ -3,7 +3,7 @@ use std::collections::BTreeSet;
use enumset::EnumSet;
use maplit::btreeset;
use map_gui::tools::ColorDiscrete;
use map_gui::tools::{intersections_from_roads, ColorDiscrete};
use map_model::{AccessRestrictions, CommonEndpoint, PathConstraints, RoadID};
use sim::TripMode;
use widgetry::mapspace::ToggleZoomed;
@ -14,7 +14,7 @@ use widgetry::{
use crate::app::{App, Transition};
use crate::common::RoadSelector;
use crate::common::{checkbox_per_mode, intersections_from_roads, CommonState};
use crate::common::{checkbox_per_mode, CommonState};
use crate::edit::apply_map_edits;
pub struct ZoneEditor {

View File

@ -4,7 +4,7 @@ use abstio::Manifest;
use abstutil::{prettyprint_bytes, prettyprint_usize, Counter, Timer};
use geom::{Distance, Duration, UnitFmt};
use map_gui::load::FileLoader;
use map_gui::tools::{open_browser, ColorNetwork};
use map_gui::tools::{open_browser, percentage_bar, ColorNetwork};
use map_gui::ID;
use map_model::{PathRequest, PathStepV2, RoadID};
use sim::{Scenario, TripEndpoint, TripMode};
@ -12,7 +12,6 @@ use widgetry::mapspace::ToggleZoomed;
use widgetry::{EventCtx, GfxCtx, Line, Outcome, Panel, Spinner, State, Text, TextExt, Widget};
use crate::app::{App, Transition};
use crate::common::percentage_bar;
use crate::ungap::{Layers, Tab, TakeLayers};
pub struct ShowGaps {

View File

@ -1,3 +1,4 @@
use map_gui::tools::{InputWaypoints, WaypointID};
use map_model::RoutingParams;
use widgetry::mapspace::{ObjectID, World, WorldOutcome};
use widgetry::{
@ -6,7 +7,6 @@ use widgetry::{
use self::results::RouteDetails;
use crate::app::{App, Transition};
use crate::common::{InputWaypoints, WaypointID};
use crate::ungap::{Layers, Tab, TakeLayers};
mod files;

View File

@ -1,7 +1,7 @@
use std::cmp::Ordering;
use geom::{Circle, Distance, Duration, FindClosest, PolyLine, Polygon};
use map_gui::tools::PopupMsg;
use map_gui::tools::{cmp_dist, cmp_duration, PopupMsg};
use map_model::{Path, PathStep, NORMAL_LANE_THICKNESS};
use sim::{TripEndpoint, TripMode};
use widgetry::mapspace::{ToggleZoomed, ToggleZoomedBuilder};
@ -12,7 +12,6 @@ use widgetry::{
use super::{before_after_button, RoutingPreferences};
use crate::app::{App, Transition};
use crate::common::{cmp_dist, cmp_duration};
/// A temporary structure that the caller should unpack and use as needed.
pub struct BuiltRoute {

View File

@ -174,7 +174,7 @@ fn make_world(
);
}
for i in
crate::common::intersections_from_roads(&cell.roads.keys().cloned().collect(), map)
map_gui::tools::intersections_from_roads(&cell.roads.keys().cloned().collect(), map)
{
draw.push(color, map.get_i(i).polygon.clone());
}

View File

@ -72,7 +72,7 @@ pub fn run_wasm(root_dom_id: String, assets_base_url: String, assets_are_gzipped
run(settings);
}
struct Session {
pub struct Session {
pub partitioning: Partitioning,
pub modal_filters: ModalFilters,
}

View File

@ -1,4 +1,5 @@
use geom::{Distance, Duration};
use map_gui::tools::{cmp_dist, cmp_duration, InputWaypoints, WaypointID};
use map_model::NORMAL_LANE_THICKNESS;
use sim::{TripEndpoint, TripMode};
use widgetry::mapspace::{ObjectID, ToggleZoomed, World};
@ -8,7 +9,6 @@ use widgetry::{
use super::per_neighborhood::{FilterableObj, Tab};
use super::{Neighborhood, NeighborhoodID};
use crate::common::{cmp_dist, cmp_duration, InputWaypoints, WaypointID};
use crate::{App, Transition};
pub struct RoutePlanner {

View File

@ -1,5 +1,5 @@
use geom::ArrowCap;
use map_gui::tools::ColorNetwork;
use map_gui::tools::{percentage_bar, ColorNetwork};
use map_model::NORMAL_LANE_THICKNESS;
use widgetry::mapspace::{ToggleZoomed, World};
use widgetry::{
@ -9,7 +9,6 @@ use widgetry::{
use super::per_neighborhood::{FilterableObj, Tab};
use super::rat_runs::{find_rat_runs, RatRuns};
use super::{Neighborhood, NeighborhoodID};
use crate::common::percentage_bar;
use crate::{App, Transition};
pub struct BrowseRatRuns {

View File

@ -1,7 +1,10 @@
//! Assorted tools and UI states that're useful for applications built to display maps.
use std::collections::BTreeSet;
use abstio::MapName;
use geom::Polygon;
use map_model::{IntersectionID, Map, RoadID};
use widgetry::{lctrl, EventCtx, GfxCtx, Key, Line, Text, Widget};
pub use self::camera::{CameraState, DefaultMap};
@ -14,8 +17,11 @@ pub use self::minimap::{Minimap, MinimapControls};
pub use self::navigate::Navigator;
pub use self::title_screen::{Executable, TitleScreen};
pub use self::turn_explorer::TurnExplorer;
pub use self::ui::{ChooseSomething, FilePicker, PopupMsg, PromptInput};
pub use self::ui::{
cmp_dist, cmp_duration, percentage_bar, ChooseSomething, FilePicker, PopupMsg, PromptInput,
};
pub use self::url::URLManager;
pub use self::waypoints::{InputWaypoints, WaypointID};
use crate::AppLike;
#[cfg(not(target_arch = "wasm32"))]
@ -41,6 +47,7 @@ mod ui;
#[cfg(not(target_arch = "wasm32"))]
mod updater;
mod url;
mod waypoints;
// Update this ___before___ pushing the commit with "[rebuild] [release]".
const NEXT_RELEASE: &str = "0.3.8";
@ -374,3 +381,19 @@ pub fn app_header(ctx: &EventCtx, app: &dyn AppLike, title: &str) -> Widget {
change_map_btn(ctx, app),
])
}
pub fn intersections_from_roads(roads: &BTreeSet<RoadID>, map: &Map) -> BTreeSet<IntersectionID> {
let mut results = BTreeSet::new();
for r in roads {
let r = map.get_r(*r);
for i in [r.src_i, r.dst_i] {
if results.contains(&i) {
continue;
}
if map.get_i(i).roads.iter().all(|r| roads.contains(r)) {
results.insert(i);
}
}
}
results
}

View File

@ -1,11 +1,13 @@
//! Generic UI tools. Some of this should perhaps be lifted to widgetry.
use std::cmp::Ordering;
use anyhow::Result;
use geom::Polygon;
use geom::{Distance, Duration, Polygon};
use widgetry::{
hotkeys, Choice, Color, DrawBaselayer, EventCtx, GfxCtx, Key, Line, Menu, Outcome, Panel,
State, Text, TextBox, Transition, Widget,
hotkeys, Choice, Color, DrawBaselayer, EventCtx, GeomBatch, GfxCtx, Key, Line, Menu, Outcome,
Panel, State, Text, TextBox, Transition, Widget,
};
use crate::load::FutureLoader;
@ -234,3 +236,83 @@ impl FilePicker {
)
}
}
pub fn percentage_bar(ctx: &EventCtx, txt: Text, pct_green: f64) -> Widget {
let bad_color = Color::RED;
let good_color = Color::GREEN;
let total_width = 450.0;
let height = 32.0;
let radius = 4.0;
let mut batch = GeomBatch::new();
// Background
batch.push(
bad_color,
Polygon::rounded_rectangle(total_width, height, radius),
);
// Foreground
if let Some(poly) = Polygon::maybe_rounded_rectangle(pct_green * total_width, height, radius) {
batch.push(good_color, poly);
}
// Text
let label = txt.render_autocropped(ctx);
let dims = label.get_dims();
batch.append(label.translate(10.0, height / 2.0 - dims.height / 2.0));
batch.into_widget(ctx)
}
/// Shorter is better
pub fn cmp_dist(txt: &mut Text, app: &dyn AppLike, dist: Distance, shorter: &str, longer: &str) {
match dist.cmp(&Distance::ZERO) {
Ordering::Less => {
txt.add_line(
Line(format!(
"{} {}",
(-dist).to_string(&app.opts().units),
shorter
))
.fg(Color::GREEN),
);
}
Ordering::Greater => {
txt.add_line(
Line(format!("{} {}", dist.to_string(&app.opts().units), longer)).fg(Color::RED),
);
}
Ordering::Equal => {}
}
}
/// Shorter is better
pub fn cmp_duration(
txt: &mut Text,
app: &dyn AppLike,
duration: Duration,
shorter: &str,
longer: &str,
) {
match duration.cmp(&Duration::ZERO) {
Ordering::Less => {
txt.add_line(
Line(format!(
"{} {}",
(-duration).to_string(&app.opts().units),
shorter
))
.fg(Color::GREEN),
);
}
Ordering::Greater => {
txt.add_line(
Line(format!(
"{} {}",
duration.to_string(&app.opts().units),
longer
))
.fg(Color::RED),
);
}
Ordering::Equal => {}
}
}

View File

@ -6,7 +6,7 @@ use widgetry::{
RewriteColor, StackAxis, Text, Widget,
};
use crate::app::App;
use crate::AppLike;
/// Click to add waypoints, drag them, see the list on a panel and delete them. The caller owns the
/// Panel and the World, since there's probably more stuff there too.
@ -26,8 +26,8 @@ struct Waypoint {
}
impl InputWaypoints {
pub fn new(app: &App) -> InputWaypoints {
let map = &app.primary.map;
pub fn new(app: &dyn AppLike) -> InputWaypoints {
let map = app.map();
let mut snap_to_endpts = FindClosest::new(map.get_bounds());
for i in map.all_intersections() {
if i.is_border() {
@ -45,7 +45,7 @@ impl InputWaypoints {
}
/// The caller should call `rebuild_world` after this
pub fn overwrite(&mut self, app: &App, waypoints: Vec<TripEndpoint>) {
pub fn overwrite(&mut self, app: &dyn AppLike, waypoints: Vec<TripEndpoint>) {
self.waypoints.clear();
for at in waypoints {
self.waypoints.push(Waypoint::new(app, at));
@ -139,7 +139,7 @@ impl InputWaypoints {
/// route and call `get_panel_widget` and `rebuild_world` again.
pub fn event(
&mut self,
app: &mut App,
app: &dyn AppLike,
panel_outcome: Outcome,
world_outcome: WorldOutcome<WaypointID>,
) -> bool {
@ -239,8 +239,8 @@ impl InputWaypoints {
}
impl Waypoint {
fn new(app: &App, at: TripEndpoint) -> Waypoint {
let map = &app.primary.map;
fn new(app: &dyn AppLike, at: TripEndpoint) -> Waypoint {
let map = app.map();
let (center, label) = match at {
TripEndpoint::Bldg(b) => {
let b = map.get_b(b);
@ -248,7 +248,10 @@ impl Waypoint {
}
TripEndpoint::Border(i) => {
let i = map.get_i(i);
(i.polygon.center(), i.name(app.opts.language.as_ref(), map))
(
i.polygon.center(),
i.name(app.opts().language.as_ref(), map),
)
}
TripEndpoint::SuddenlyAppear(pos) => (pos.pt(map), pos.to_string()),
};