Share the logo / map changer in the 3 modes too

This commit is contained in:
Dustin Carlino 2021-08-26 09:18:12 -07:00
parent d2afeb05ef
commit 57d1cba40c
3 changed files with 131 additions and 94 deletions

View File

@ -110,26 +110,7 @@ impl State<App> for ExploreMap {
if let Outcome::Clicked(x) = self.top_panel.event(ctx) {
match x.as_ref() {
"about A/B Street" => {
let panel = Panel::new_builder(Widget::col(vec![
Widget::row(vec![
Line("About A/B Street").small_heading().into_widget(ctx),
ctx.style().btn_close_widget(ctx),
]),
Text::from_multiline(vec![
Line("Created by Dustin Carlino, Yuwen Li, & Michael Kirk").small(),
Line("Data from OpenStreetMap, King County GIS, King County LIDAR")
.small(),
])
.into_widget(ctx),
"This is a simplified version. Check out the full version below."
.text_widget(ctx),
ctx.style().btn_outline.text("abstreet.org").build_def(ctx),
]))
.build(ctx);
return Transition::Push(<dyn SimpleState<_>>::new_state(
panel,
Box::new(About),
));
return Transition::Push(About::new_state(ctx));
}
"change map" => {
return Transition::Push(CityPicker::new_state(
@ -144,6 +125,28 @@ impl State<App> for ExploreMap {
}),
));
}
"Create new bike lanes" => {
app.primary.current_selection = None;
return Transition::ConsumeState(Box::new(|state, ctx, app| {
let state = state.downcast::<ExploreMap>().ok().unwrap();
vec![crate::ungap::quick_sketch::QuickSketch::new_state(
ctx,
app,
state.layers,
)]
}));
}
"Plan a route" => {
app.primary.current_selection = None;
return Transition::ConsumeState(Box::new(|state, ctx, app| {
let state = state.downcast::<ExploreMap>().ok().unwrap();
vec![crate::ungap::route::RoutePlanner::new_state(
ctx,
app,
state.layers,
)]
}));
}
"Open a proposal" => {
// Dummy mode, just to allow all edits
// TODO Actually, should we make one to express that only road edits are
@ -168,28 +171,6 @@ impl State<App> for ExploreMap {
"Share proposal" => {
return Transition::Push(share::upload_proposal(ctx, app));
}
"Create new bike lanes" => {
app.primary.current_selection = None;
return Transition::ConsumeState(Box::new(|state, ctx, app| {
let state = state.downcast::<ExploreMap>().ok().unwrap();
vec![crate::ungap::quick_sketch::QuickSketch::new_state(
ctx,
app,
state.layers,
)]
}));
}
"Plan a route" => {
app.primary.current_selection = None;
return Transition::ConsumeState(Box::new(|state, ctx, app| {
let state = state.downcast::<ExploreMap>().ok().unwrap();
vec![crate::ungap::route::RoutePlanner::new_state(
ctx,
app,
state.layers,
)]
}));
}
_ => unreachable!(),
}
}
@ -276,25 +257,7 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
// TODO Should undo/redo, save, share functionality also live here?
Panel::new_builder(Widget::col(vec![
Widget::row(vec![
ctx.style()
.btn_plain
.btn()
.image_path("system/assets/pregame/logo.svg")
.image_dims(70.0)
.build_widget(ctx, "about A/B Street"),
Widget::col(vec![
Line("Ungap the Map").small_heading().into_widget(ctx),
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"),
]),
]),
make_tabs(ctx, Tab::Explore),
make_header(ctx, app, Tab::Explore),
Widget::col(file_management).section(ctx),
]))
.aligned(HorizontalAlignment::Left, VerticalAlignment::Top)
@ -303,6 +266,26 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
struct About;
impl About {
pub fn new_state(ctx: &mut EventCtx) -> Box<dyn State<App>> {
let panel = Panel::new_builder(Widget::col(vec![
Widget::row(vec![
Line("About A/B Street").small_heading().into_widget(ctx),
ctx.style().btn_close_widget(ctx),
]),
Text::from_multiline(vec![
Line("Created by Dustin Carlino, Yuwen Li, & Michael Kirk").small(),
Line("Data from OpenStreetMap, King County GIS, King County LIDAR").small(),
])
.into_widget(ctx),
"This is a simplified version. Check out the full version below.".text_widget(ctx),
ctx.style().btn_outline.text("abstreet.org").build_def(ctx),
]))
.build(ctx);
<dyn SimpleState<_>>::new_state(panel, Box::new(About))
}
}
impl SimpleState<App> for About {
fn on_click(&mut self, _: &mut EventCtx, _: &mut App, x: &str, _: &Panel) -> Transition {
if x == "close" {
@ -326,25 +309,44 @@ pub enum Tab {
Route,
}
pub fn make_tabs(ctx: &mut EventCtx, current_tab: Tab) -> Widget {
Widget::row(vec![
ctx.style()
.btn_tab
.icon_text("system/assets/tools/pan.svg", "Explore")
.hotkey(Key::E)
.disabled(current_tab == Tab::Explore)
.build_def(ctx),
ctx.style()
.btn_tab
.icon_text("system/assets/tools/pencil.svg", "Create new bike lanes")
.hotkey(Key::C)
.disabled(current_tab == Tab::Create)
.build_def(ctx),
ctx.style()
.btn_tab
.icon_text("system/assets/tools/pin.svg", "Plan a route")
.hotkey(Key::R)
.disabled(current_tab == Tab::Route)
.build_def(ctx),
pub fn make_header(ctx: &mut EventCtx, app: &App, current_tab: Tab) -> Widget {
Widget::col(vec![
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"),
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")
.centered_vert()
.align_right(),
]),
Widget::row(vec![
ctx.style()
.btn_tab
.icon_text("system/assets/tools/pan.svg", "Explore")
.hotkey(Key::E)
.disabled(current_tab == Tab::Explore)
.build_def(ctx),
ctx.style()
.btn_tab
.icon_text("system/assets/tools/pencil.svg", "Create new bike lanes")
.hotkey(Key::C)
.disabled(current_tab == Tab::Create)
.build_def(ctx),
ctx.style()
.btn_tab
.icon_text("system/assets/tools/pin.svg", "Plan a route")
.hotkey(Key::R)
.disabled(current_tab == Tab::Route)
.build_def(ctx),
]),
])
}

View File

@ -1,5 +1,5 @@
use abstutil::Tags;
use map_gui::tools::PopupMsg;
use map_gui::tools::{CityPicker, PopupMsg};
use map_model::{BufferType, Direction, EditCmd, EditRoad, LaneSpec, LaneType, RoadID};
use widgetry::{
Choice, EventCtx, GfxCtx, HorizontalAlignment, Key, Outcome, Panel, State, TextExt,
@ -9,7 +9,7 @@ use widgetry::{
use crate::app::{App, Transition};
use crate::common::RouteSketcher;
use crate::edit::apply_map_edits;
use crate::ungap::{make_tabs, Layers, Tab};
use crate::ungap::{make_header, Layers, Tab};
pub struct QuickSketch {
top_panel: Panel,
@ -24,13 +24,13 @@ impl QuickSketch {
layers,
route_sketcher: RouteSketcher::new(ctx, app),
};
qs.update_top_panel(ctx);
qs.update_top_panel(ctx, app);
Box::new(qs)
}
fn update_top_panel(&mut self, ctx: &mut EventCtx) {
fn update_top_panel(&mut self, ctx: &mut EventCtx, app: &App) {
let mut col = vec![
make_tabs(ctx, Tab::Create),
make_header(ctx, app, Tab::Create),
self.route_sketcher.get_widget_to_describe(ctx),
];
@ -80,6 +80,23 @@ impl State<App> for QuickSketch {
fn event(&mut self, ctx: &mut EventCtx, app: &mut App) -> Transition {
if let Outcome::Clicked(x) = self.top_panel.event(ctx) {
match x.as_ref() {
"about A/B Street" => {
return Transition::Push(crate::ungap::About::new_state(ctx));
}
"change map" => {
return Transition::Push(CityPicker::new_state(
ctx,
app,
Box::new(|ctx, app| {
Transition::Multi(vec![
Transition::Pop,
// Since we're totally changing maps, don't reuse the Layers
// TODO Should we keep the current tab or always reset here?
Transition::Replace(crate::ungap::ExploreMap::launch(ctx, app)),
])
}),
));
}
"Explore" => {
return Transition::ConsumeState(Box::new(|state, ctx, app| {
let state = state.downcast::<QuickSketch>().ok().unwrap();
@ -116,7 +133,7 @@ impl State<App> for QuickSketch {
}
if self.route_sketcher.event(ctx, app) {
self.update_top_panel(ctx);
self.update_top_panel(ctx, app);
}
if let Some(t) = self.layers.event(ctx, app) {

View File

@ -5,6 +5,7 @@ use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use geom::{Circle, Distance, Duration, FindClosest, Polygon};
use map_gui::tools::CityPicker;
use map_model::{PathStep, NORMAL_LANE_THICKNESS};
use sim::{TripEndpoint, TripMode};
use widgetry::{
@ -13,7 +14,7 @@ use widgetry::{
};
use crate::app::{App, Transition};
use crate::ungap::{make_tabs, Layers, Tab};
use crate::ungap::{make_header, Layers, Tab};
pub struct RoutePlanner {
layers: Layers,
@ -74,14 +75,14 @@ impl RoutePlanner {
draw_route: Drawable::empty(ctx),
results_panel: Panel::empty(ctx),
};
rp.update_input_panel(ctx);
rp.update_input_panel(ctx, app);
rp.update_waypoints_drawable(ctx);
rp.update_route(ctx, app);
Box::new(rp)
}
fn update_input_panel(&mut self, ctx: &mut EventCtx) {
let mut col = vec![make_tabs(ctx, Tab::Route)];
fn update_input_panel(&mut self, ctx: &mut EventCtx, app: &App) {
let mut col = vec![make_header(ctx, app, Tab::Route)];
for (idx, waypt) in self.waypoints.iter().enumerate() {
col.push(Widget::row(vec![
@ -162,7 +163,7 @@ impl RoutePlanner {
let idx = self.hovering_on_waypt.unwrap();
if self.waypoints[idx].at != at {
self.waypoints[idx] = Waypoint::new(ctx, app, at, idx);
self.update_input_panel(ctx);
self.update_input_panel(ctx, app);
self.update_waypoints_drawable(ctx);
self.update_route(ctx, app);
}
@ -345,6 +346,23 @@ impl State<App> for RoutePlanner {
if let Outcome::Clicked(x) = self.input_panel.event(ctx) {
match x.as_ref() {
"about A/B Street" => {
return Transition::Push(crate::ungap::About::new_state(ctx));
}
"change map" => {
return Transition::Push(CityPicker::new_state(
ctx,
app,
Box::new(|ctx, app| {
Transition::Multi(vec![
Transition::Pop,
// Since we're totally changing maps, don't reuse the Layers
// TODO Should we keep the current tab or always reset here?
Transition::Replace(crate::ungap::ExploreMap::launch(ctx, app)),
])
}),
));
}
"Explore" => {
return Transition::ConsumeState(Box::new(|state, ctx, app| {
let state = state.downcast::<RoutePlanner>().ok().unwrap();
@ -363,7 +381,7 @@ impl State<App> for RoutePlanner {
}
"Add waypoint" => {
self.waypoints.push(self.make_new_waypt(ctx, app));
self.update_input_panel(ctx);
self.update_input_panel(ctx, app);
self.update_waypoints_drawable(ctx);
self.update_route(ctx, app);
self.update_hover(ctx);
@ -377,7 +395,7 @@ impl State<App> for RoutePlanner {
*waypt = Waypoint::new(ctx, app, waypt.at, idx);
}
self.update_input_panel(ctx);
self.update_input_panel(ctx, app);
self.update_waypoints_drawable(ctx);
self.update_route(ctx, app);
} else {