mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
A skeleton emerges, from whatever sort of place skeletons lurk
This commit is contained in:
parent
58f9c912cc
commit
c019304ee3
@ -30,6 +30,7 @@ mod info;
|
||||
mod layer;
|
||||
mod pregame;
|
||||
mod sandbox;
|
||||
mod ungap;
|
||||
|
||||
pub fn main() {
|
||||
let settings = Settings::new("A/B Street");
|
||||
@ -46,6 +47,7 @@ struct Setup {
|
||||
start_time: Option<Duration>,
|
||||
load_kml: Option<String>,
|
||||
diff_map: Option<String>,
|
||||
ungap: bool,
|
||||
}
|
||||
|
||||
fn run(mut settings: Settings) {
|
||||
@ -76,6 +78,7 @@ fn run(mut settings: Settings) {
|
||||
start_time: args.optional_parse("--time", |t| Duration::parse(t)),
|
||||
load_kml: args.optional("--kml"),
|
||||
diff_map: args.optional("--diff"),
|
||||
ungap: args.enabled("--ungap"),
|
||||
};
|
||||
|
||||
settings = settings.canvas_settings(setup.opts.canvas_settings.clone());
|
||||
@ -153,7 +156,8 @@ fn setup_app(ctx: &mut EventCtx, mut setup: Setup) -> (App, Vec<Box<dyn State<Ap
|
||||
let title = !setup.opts.dev
|
||||
&& !setup.flags.sim_flags.load.contains("player/save")
|
||||
&& !setup.flags.sim_flags.load.contains("/scenarios/")
|
||||
&& setup.maybe_mode.is_none();
|
||||
&& setup.maybe_mode.is_none()
|
||||
&& !setup.ungap;
|
||||
|
||||
// Load the map used previously if we're starting on the title screen without any overrides.
|
||||
if title && setup.flags.sim_flags.load == MapName::seattle("montlake").path() {
|
||||
@ -353,6 +357,8 @@ fn finish_app_setup(
|
||||
} else {
|
||||
vec![SandboxMode::simple_new(app, mode)]
|
||||
}
|
||||
} else if setup.ungap {
|
||||
vec![ungap::ExploreMap::new_state(ctx, app)]
|
||||
} else {
|
||||
// Not attempting to keep the primary and secondary simulations synchronized at the same
|
||||
// time yet. Just handle this one startup case, so we can switch maps without constantly
|
||||
|
150
game/src/ungap/mod.rs
Normal file
150
game/src/ungap/mod.rs
Normal file
@ -0,0 +1,150 @@
|
||||
use geom::{Circle, Distance, Pt2D};
|
||||
use map_gui::tools::{nice_map_name, CityPicker, PopupMsg};
|
||||
use widgetry::{
|
||||
lctrl, Color, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel,
|
||||
State, VerticalAlignment, Widget,
|
||||
};
|
||||
|
||||
use crate::app::{App, Transition};
|
||||
|
||||
pub struct ExploreMap {
|
||||
top_panel: Panel,
|
||||
legend: Panel,
|
||||
}
|
||||
|
||||
impl ExploreMap {
|
||||
pub fn new_state(ctx: &mut EventCtx, app: &App) -> Box<dyn State<App>> {
|
||||
Box::new(ExploreMap {
|
||||
top_panel: make_top_panel(ctx),
|
||||
legend: make_legend(ctx, app),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl State<App> for ExploreMap {
|
||||
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
ctx.canvas_movement();
|
||||
|
||||
if let Outcome::Clicked(x) = self.top_panel.event(ctx) {
|
||||
match x.as_ref() {
|
||||
"about A/B Street" => {
|
||||
return Transition::Push(PopupMsg::new_state(ctx, "TODO", vec!["TODO"]));
|
||||
}
|
||||
"Bike Master Plan" => {
|
||||
return Transition::Push(PopupMsg::new_state(ctx, "TODO", vec!["TODO"]));
|
||||
}
|
||||
"Edit network" => {
|
||||
return Transition::Push(PopupMsg::new_state(ctx, "TODO", vec!["TODO"]));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
if let Outcome::Clicked(x) = self.legend.event(ctx) {
|
||||
return Transition::Push(match x.as_ref() {
|
||||
"change map" => CityPicker::new_state(
|
||||
ctx,
|
||||
app,
|
||||
Box::new(|ctx, app| {
|
||||
Transition::Multi(vec![Transition::Pop, Transition::Replace(ExploreMap::new_state(ctx, app))])
|
||||
}),
|
||||
),
|
||||
// TODO Add physical picture examples
|
||||
"highway" => PopupMsg::new_state(ctx, "Highways", vec!["Unless there's a separate trail (like on the 520 or I90 bridge), highways aren't accessible to biking"]),
|
||||
"major street" => PopupMsg::new_state(ctx, "Major streets", vec!["Arterials have more traffic, but are often where businesses are located"]),
|
||||
"minor street" => PopupMsg::new_state(ctx, "Minor streets", vec!["Local streets have a low volume of traffic and are usually comfortable for biking, even without dedicated infrastructure"]),
|
||||
"trail" => PopupMsg::new_state(ctx, "Trails", vec!["Trails like the Burke Gilman are usually well-separated from vehicle traffic. The space is usually shared between people walking, cycling, and rolling."]),
|
||||
"protected bike lane" => PopupMsg::new_state(ctx, "Protected bike lanes", vec!["Bike lanes separated from vehicle traffic by physical barriers or a few feet of striping"]),
|
||||
"painted bike lane" => PopupMsg::new_state(ctx, "Painted bike lanes", vec!["Bike lanes without any separation from vehicle traffic. Often uncomfortably close to the \"door zone\" of parked cars."]),
|
||||
"Stay Healthy Street / greenway" => PopupMsg::new_state(ctx, "Stay Healthy Streets and neighborhood greenways", vec!["Residential streets with additional signage and light barriers. These are intended to be low traffic, dedicated for people walking and biking."]),
|
||||
_ => unreachable!(),
|
||||
});
|
||||
}
|
||||
|
||||
Transition::Keep
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &App) {
|
||||
self.top_panel.draw(g);
|
||||
self.legend.draw(g);
|
||||
}
|
||||
}
|
||||
|
||||
fn make_top_panel(ctx: &mut EventCtx) -> Panel {
|
||||
Panel::new_builder(Widget::row(vec![
|
||||
ctx.style()
|
||||
.btn_plain
|
||||
.btn()
|
||||
.image_path("system/assets/pregame/logo.svg")
|
||||
.image_dims(50.0)
|
||||
.build_widget(ctx, "about A/B Street"),
|
||||
// TODO Tab style?
|
||||
ctx.style()
|
||||
.btn_solid_primary
|
||||
.text("Today")
|
||||
.disabled(true)
|
||||
.build_def(ctx)
|
||||
.centered_vert(),
|
||||
ctx.style()
|
||||
.btn_solid_primary
|
||||
.text("Bike Master Plan")
|
||||
.build_def(ctx)
|
||||
.centered_vert(),
|
||||
ctx.style()
|
||||
.btn_solid_primary
|
||||
.icon_text("system/assets/tools/pencil.svg", "Edit network")
|
||||
.build_def(ctx)
|
||||
.centered_vert(),
|
||||
]))
|
||||
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
|
||||
.build(ctx)
|
||||
}
|
||||
|
||||
fn make_legend(ctx: &mut EventCtx, app: &App) -> Panel {
|
||||
Panel::new_builder(Widget::col(vec![
|
||||
Widget::custom_row(vec![
|
||||
Line("Bike Network")
|
||||
.small_heading()
|
||||
.into_widget(ctx)
|
||||
.margin_right(18),
|
||||
ctx.style()
|
||||
.btn_popup_icon_text(
|
||||
"system/assets/tools/map.svg",
|
||||
nice_map_name(app.primary.map.get_name()),
|
||||
)
|
||||
.hotkey(lctrl(Key::L))
|
||||
.build_widget(ctx, "change map")
|
||||
.margin_right(8),
|
||||
]),
|
||||
legend(ctx, app.cs.unzoomed_highway, "highway"),
|
||||
legend(ctx, app.cs.unzoomed_arterial, "major street"),
|
||||
legend(ctx, app.cs.unzoomed_residential, "minor street"),
|
||||
legend(ctx, app.cs.unzoomed_trail, "trail"),
|
||||
// TODO Untuned colors
|
||||
legend(ctx, Color::hex("#74B0FC"), "protected bike lane"),
|
||||
legend(ctx, Color::GREEN, "painted bike lane"),
|
||||
legend(ctx, Color::BLUE, "Stay Healthy Street / greenway"),
|
||||
// TODO Distinguish door-zone bike lanes?
|
||||
// TODO Call out bike turning boxes?
|
||||
// TODO Call out bike signals?
|
||||
]))
|
||||
.aligned(HorizontalAlignment::Right, VerticalAlignment::Bottom)
|
||||
.build(ctx)
|
||||
}
|
||||
|
||||
fn legend(ctx: &mut EventCtx, color: Color, label: &str) -> Widget {
|
||||
let radius = 15.0;
|
||||
Widget::row(vec![
|
||||
GeomBatch::from(vec![(
|
||||
color,
|
||||
Circle::new(Pt2D::new(radius, radius), Distance::meters(radius)).to_polygon(),
|
||||
)])
|
||||
.into_widget(ctx)
|
||||
.centered_vert(),
|
||||
ctx.style()
|
||||
.btn_plain
|
||||
.text(label)
|
||||
.build_def(ctx)
|
||||
.centered_vert(),
|
||||
])
|
||||
}
|
@ -78,9 +78,9 @@ pub struct ColorScheme {
|
||||
pub road_center_line: Color,
|
||||
pub light_rail_track: Color,
|
||||
pub private_road: Color,
|
||||
unzoomed_highway: Color,
|
||||
unzoomed_arterial: Color,
|
||||
unzoomed_residential: Color,
|
||||
pub unzoomed_highway: Color,
|
||||
pub unzoomed_arterial: Color,
|
||||
pub unzoomed_residential: Color,
|
||||
pub unzoomed_trail: Color,
|
||||
|
||||
// Intersections
|
||||
|
@ -205,15 +205,12 @@ pub fn collapse_intersection(raw: &mut RawMap, i: NodeID) {
|
||||
// When we concatenate the points, the common point will be duplicated
|
||||
new_road.center_points.dedup();
|
||||
|
||||
let new_r1 =
|
||||
OriginalRoad {
|
||||
let new_r1 = OriginalRoad {
|
||||
osm_way_id: r1.osm_way_id,
|
||||
i1: new_i1,
|
||||
i2: new_i2,
|
||||
};
|
||||
raw.roads.insert(new_r1,
|
||||
new_road,
|
||||
);
|
||||
raw.roads.insert(new_r1, new_road);
|
||||
|
||||
// We may need to fix up turn restrictions. r1 and r2 both become new_r1.
|
||||
let rewrite = |x: &OriginalRoad| *x == r1 || *x == r2;
|
||||
|
Loading…
Reference in New Issue
Block a user