mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 02:33:54 +03:00
convert the last caller away from wizard...
This commit is contained in:
parent
f61881f6fa
commit
b881fa605b
@ -1,6 +1,6 @@
|
||||
use crate::app::{App, PerMap};
|
||||
use crate::common::Tab;
|
||||
use crate::game::{msg, State, Transition};
|
||||
use crate::game::{PopupMsg, State, Transition};
|
||||
use crate::helpers::ID;
|
||||
use crate::info::OpenTrip;
|
||||
use crate::sandbox::SandboxMode;
|
||||
@ -133,7 +133,8 @@ impl State for DebugWarp {
|
||||
if let Some(t) = warp_to_id(ctx, app, &input) {
|
||||
t
|
||||
} else {
|
||||
Transition::Replace(msg(
|
||||
Transition::Replace(PopupMsg::new(
|
||||
ctx,
|
||||
"Bad warp ID",
|
||||
vec![format!("{} isn't a valid ID", input)],
|
||||
))
|
||||
|
@ -5,7 +5,7 @@ pub mod shared_row;
|
||||
|
||||
use crate::app::{App, ShowLayers, ShowObject};
|
||||
use crate::common::{tool_panel, CommonState, ContextualActions};
|
||||
use crate::game::{msg, ChooseSomething, DrawBaselayer, PromptInput, State, Transition};
|
||||
use crate::game::{ChooseSomething, DrawBaselayer, PopupMsg, PromptInput, State, Transition};
|
||||
use crate::helpers::ID;
|
||||
use crate::options::OptionsPanel;
|
||||
use crate::render::{calculate_corners, DrawOptions};
|
||||
@ -145,7 +145,8 @@ impl State for DebugMode {
|
||||
app.recalculate_current_selection(ctx);
|
||||
None
|
||||
}
|
||||
None => Some(Transition::Push(msg(
|
||||
None => Some(Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec![format!(
|
||||
"Couldn't load previous savestate {:?}",
|
||||
@ -170,7 +171,8 @@ impl State for DebugMode {
|
||||
app.recalculate_current_selection(ctx);
|
||||
None
|
||||
}
|
||||
None => Some(Transition::Push(msg(
|
||||
None => Some(Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec![format!("Couldn't load next savestate {:?}", next_state)],
|
||||
))),
|
||||
@ -507,7 +509,8 @@ impl ContextualActions for Actions {
|
||||
app.primary.current_selection = None;
|
||||
Transition::Keep
|
||||
}
|
||||
(ID::Car(c), "find front of blockage") => Transition::Push(msg(
|
||||
(ID::Car(c), "find front of blockage") => Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Blockage results",
|
||||
vec![format!(
|
||||
"{} is ultimately blocked by {}",
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::app::{App, ShowEverything};
|
||||
use crate::common::{CityPicker, ColorLegend};
|
||||
use crate::game::{msg, State, Transition};
|
||||
use crate::game::{PopupMsg, State, Transition};
|
||||
use crate::helpers::{nice_map_name, open_browser, ID};
|
||||
use abstutil::{prettyprint_usize, Tags, Timer};
|
||||
use ezgui::{
|
||||
@ -324,7 +324,8 @@ impl State for ParkingMapper {
|
||||
}
|
||||
"Generate OsmChange file" => {
|
||||
if self.data.is_empty() {
|
||||
return Transition::Push(msg(
|
||||
return Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"No changes yet",
|
||||
vec!["Map some parking first"],
|
||||
));
|
||||
@ -337,11 +338,14 @@ impl State for ParkingMapper {
|
||||
timer,
|
||||
)
|
||||
}) {
|
||||
Ok(()) => Transition::Push(msg(
|
||||
Ok(()) => Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Diff generated",
|
||||
vec!["diff.osc created. Load it in JOSM, verify, and upload!"],
|
||||
)),
|
||||
Err(err) => Transition::Push(msg("Error", vec![format!("{}", err)])),
|
||||
Err(err) => {
|
||||
Transition::Push(PopupMsg::new(ctx, "Error", vec![format!("{}", err)]))
|
||||
}
|
||||
};
|
||||
}
|
||||
"change map" => {
|
||||
@ -469,7 +473,8 @@ impl State for ChangeWay {
|
||||
.current_choice()
|
||||
.clone();
|
||||
if value == Value::Complicated {
|
||||
Transition::Replace(msg(
|
||||
Transition::Replace(PopupMsg::new(
|
||||
ctx,
|
||||
"Complicated road",
|
||||
vec![
|
||||
"You'll have to manually split the way in ID or JOSM and apply \
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::app::App;
|
||||
use crate::edit::select::RoadSelector;
|
||||
use crate::edit::{apply_map_edits, change_speed_limit, try_change_lt};
|
||||
use crate::game::{msg, State, Transition};
|
||||
use crate::game::{PopupMsg, State, Transition};
|
||||
use ezgui::{
|
||||
hotkey, Btn, Choice, Composite, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Key, Line,
|
||||
Outcome, TextExt, VerticalAlignment, Widget,
|
||||
@ -219,7 +219,7 @@ fn change_lane_types(
|
||||
timer.next();
|
||||
for l in app.primary.map.get_r(*r).all_lanes() {
|
||||
if app.primary.map.get_l(l).lane_type == from {
|
||||
match try_change_lt(&mut app.primary.map, l, to) {
|
||||
match try_change_lt(ctx, &mut app.primary.map, l, to) {
|
||||
Ok(cmd) => {
|
||||
let mut edits = app.primary.map.get_edits().clone();
|
||||
edits.commands.push(cmd);
|
||||
@ -239,7 +239,8 @@ fn change_lane_types(
|
||||
|
||||
// TODO Need to express the errors in some form that we can union here.
|
||||
|
||||
msg(
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"Changed lane types",
|
||||
vec![format!(
|
||||
"Changed {} {:?} lanes to {:?} lanes. {} errors",
|
||||
|
@ -157,24 +157,26 @@ impl State for LaneEditor {
|
||||
"Revert" => {
|
||||
// TODO It's hard to revert both changes at once.
|
||||
if let Some(lt) = map.get_edits().original_lts.get(&self.l).cloned() {
|
||||
try_change_lt(map, self.l, lt)
|
||||
try_change_lt(ctx, map, self.l, lt)
|
||||
} else {
|
||||
try_reverse(map, self.l)
|
||||
try_reverse(ctx, map, self.l)
|
||||
}
|
||||
}
|
||||
"reverse lane direction" => try_reverse(map, self.l),
|
||||
"reverse lane direction" => try_reverse(ctx, map, self.l),
|
||||
"convert to a driving lane" => {
|
||||
try_change_lt(map, self.l, LaneType::Driving)
|
||||
try_change_lt(ctx, map, self.l, LaneType::Driving)
|
||||
}
|
||||
"convert to a protected bike lane" => {
|
||||
try_change_lt(map, self.l, LaneType::Biking)
|
||||
try_change_lt(ctx, map, self.l, LaneType::Biking)
|
||||
}
|
||||
"convert to a bus-only lane" => {
|
||||
try_change_lt(ctx, map, self.l, LaneType::Bus)
|
||||
}
|
||||
"convert to a bus-only lane" => try_change_lt(map, self.l, LaneType::Bus),
|
||||
"convert to an on-street parking lane" => {
|
||||
try_change_lt(map, self.l, LaneType::Parking)
|
||||
try_change_lt(ctx, map, self.l, LaneType::Parking)
|
||||
}
|
||||
"close for construction" => {
|
||||
try_change_lt(map, self.l, LaneType::Construction)
|
||||
try_change_lt(ctx, map, self.l, LaneType::Construction)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ pub use self::validate::{
|
||||
use crate::app::{App, ShowEverything};
|
||||
use crate::common::{tool_panel, CommonState, Warping};
|
||||
use crate::debug::DebugMode;
|
||||
use crate::game::{msg, State, Transition};
|
||||
use crate::game::{PopupMsg, State, Transition};
|
||||
use crate::helpers::ID;
|
||||
use crate::options::OptionsPanel;
|
||||
use crate::render::{DrawIntersection, DrawMap, DrawRoad};
|
||||
@ -489,7 +489,11 @@ impl State for LoadEdits {
|
||||
LoadEdits::new(ctx, app, self.mode.clone()),
|
||||
// TODO Menu draws at a weird Z-order to deal with tooltips, so now the
|
||||
// menu underneath bleeds through
|
||||
msg("Error", vec![format!("Can't load {}", path), err.clone()]),
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec![format!("Can't load {}", path), err.clone()],
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::app::{App, ShowEverything};
|
||||
use crate::common::CommonState;
|
||||
use crate::edit::{apply_map_edits, check_sidewalk_connectivity, StopSignEditor};
|
||||
use crate::game::{msg, ChooseSomething, DrawBaselayer, State, Transition};
|
||||
use crate::game::{ChooseSomething, DrawBaselayer, PopupMsg, State, Transition};
|
||||
use crate::render::{
|
||||
draw_signal_phase, make_signal_diagram, DrawOptions, DrawTurnGroup, BIG_ARROW_THICKNESS,
|
||||
};
|
||||
@ -767,7 +767,8 @@ fn check_for_missing_groups(
|
||||
app.primary.map.incremental_edit_traffic_signal(new_signal);
|
||||
*composite = make_signal_diagram(ctx, app, id, 0, true);
|
||||
|
||||
Transition::Push(msg(
|
||||
Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error: missing turns",
|
||||
vec![
|
||||
format!("{} turns are missing from this traffic signal", num_missing),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::app::App;
|
||||
use crate::common::ColorDiscrete;
|
||||
use crate::game::{msg, State, WizardState};
|
||||
use crate::game::{PopupMsg, State};
|
||||
use abstutil::Timer;
|
||||
use ezgui::{Color, EventCtx};
|
||||
use map_model::{connectivity, EditCmd, LaneID, LaneType, Map, PathConstraints};
|
||||
@ -38,22 +38,23 @@ pub fn check_sidewalk_connectivity(
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut err_state = msg(
|
||||
"Error",
|
||||
vec![format!(
|
||||
"Can't close this intersection; {} sidewalks disconnected",
|
||||
newly_disconnected.len()
|
||||
)],
|
||||
);
|
||||
|
||||
let mut c = ColorDiscrete::new(app, vec![("disconnected", Color::RED)]);
|
||||
let num = newly_disconnected.len();
|
||||
for l in newly_disconnected {
|
||||
c.add_l(*l, "disconnected");
|
||||
}
|
||||
|
||||
let (unzoomed, zoomed, _) = c.build(ctx);
|
||||
err_state.downcast_mut::<WizardState>().unwrap().also_draw = Some((unzoomed, zoomed));
|
||||
Some(err_state)
|
||||
|
||||
Some(PopupMsg::also_draw(
|
||||
ctx,
|
||||
"Error",
|
||||
vec![format!(
|
||||
"Can't close this intersection; {} sidewalks disconnected",
|
||||
num
|
||||
)],
|
||||
unzoomed,
|
||||
zoomed,
|
||||
))
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
@ -96,25 +97,24 @@ pub fn check_blackholes(ctx: &mut EventCtx, app: &mut App, cmd: EditCmd) -> Opti
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut err_state = msg(
|
||||
"Error",
|
||||
vec![format!(
|
||||
"{} lanes have been disconnected",
|
||||
newly_disconnected.len()
|
||||
)],
|
||||
);
|
||||
|
||||
let mut c = ColorDiscrete::new(app, vec![("disconnected", Color::RED)]);
|
||||
let num = newly_disconnected.len();
|
||||
for l in newly_disconnected {
|
||||
c.add_l(l, "disconnected");
|
||||
}
|
||||
|
||||
let (unzoomed, zoomed, _) = c.build(ctx);
|
||||
err_state.downcast_mut::<WizardState>().unwrap().also_draw = Some((unzoomed, zoomed));
|
||||
Some(err_state)
|
||||
|
||||
Some(PopupMsg::also_draw(
|
||||
ctx,
|
||||
"Error",
|
||||
vec![format!("{} lanes have been disconnected", num)],
|
||||
unzoomed,
|
||||
zoomed,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn try_change_lt(
|
||||
ctx: &mut EventCtx,
|
||||
map: &mut Map,
|
||||
l: LaneID,
|
||||
new_lt: LaneType,
|
||||
@ -158,14 +158,15 @@ pub fn try_change_lt(
|
||||
if errors.is_empty() {
|
||||
Ok(cmd)
|
||||
} else {
|
||||
Err(msg("Error", errors))
|
||||
Err(PopupMsg::new(ctx, "Error", errors))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_reverse(map: &Map, l: LaneID) -> Result<EditCmd, Box<dyn State>> {
|
||||
pub fn try_reverse(ctx: &mut EventCtx, map: &Map, l: LaneID) -> Result<EditCmd, Box<dyn State>> {
|
||||
let lane = map.get_l(l);
|
||||
if map.get_r(lane.parent).dir_and_offset(l).1 != 0 {
|
||||
Err(msg(
|
||||
Err(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec!["You can only reverse the lanes next to the road's yellow center line"],
|
||||
))
|
||||
|
@ -4,8 +4,9 @@ use crate::pregame::TitleScreen;
|
||||
use crate::render::DrawOptions;
|
||||
use crate::sandbox::{GameplayMode, SandboxMode};
|
||||
use ezgui::{
|
||||
hotkey, Btn, Canvas, Choice, Composite, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Key,
|
||||
Line, Menu, Outcome, ScreenRectangle, VerticalAlignment, Widget, Wizard, GUI,
|
||||
hotkey, hotkeys, Btn, Canvas, Choice, Composite, Drawable, EventCtx, GeomBatch, GfxCtx,
|
||||
HorizontalAlignment, Key, Line, Menu, Outcome, ScreenRectangle, Text, VerticalAlignment,
|
||||
Widget, Wizard, GUI,
|
||||
};
|
||||
use geom::Polygon;
|
||||
use map_model::PermanentMapEdits;
|
||||
@ -352,15 +353,6 @@ impl State for WizardState {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Word wrap
|
||||
pub fn msg<S: Into<String>>(title: &'static str, lines: Vec<S>) -> Box<dyn State> {
|
||||
let str_lines: Vec<String> = lines.into_iter().map(|l| l.into()).collect();
|
||||
WizardState::new(Box::new(move |wiz, ctx, _| {
|
||||
wiz.wrap(ctx).acknowledge(title, || str_lines.clone())?;
|
||||
Some(Transition::Pop)
|
||||
}))
|
||||
}
|
||||
|
||||
pub struct ChooseSomething<T> {
|
||||
composite: Composite,
|
||||
cb: Box<dyn Fn(T, &mut EventCtx, &mut App) -> Transition>,
|
||||
@ -497,3 +489,75 @@ impl State for PromptInput {
|
||||
self.composite.draw(g);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PopupMsg {
|
||||
composite: Composite,
|
||||
unzoomed: Drawable,
|
||||
zoomed: Drawable,
|
||||
}
|
||||
|
||||
impl PopupMsg {
|
||||
pub fn new<I: Into<String>>(ctx: &mut EventCtx, title: &str, lines: Vec<I>) -> Box<dyn State> {
|
||||
PopupMsg::also_draw(
|
||||
ctx,
|
||||
title,
|
||||
lines,
|
||||
ctx.upload(GeomBatch::new()),
|
||||
ctx.upload(GeomBatch::new()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn also_draw<I: Into<String>>(
|
||||
ctx: &mut EventCtx,
|
||||
title: &str,
|
||||
lines: Vec<I>,
|
||||
unzoomed: Drawable,
|
||||
zoomed: Drawable,
|
||||
) -> Box<dyn State> {
|
||||
let mut txt = Text::new();
|
||||
txt.add(Line(title).small_heading());
|
||||
for l in lines {
|
||||
txt.add(Line(l));
|
||||
}
|
||||
Box::new(PopupMsg {
|
||||
composite: Composite::new(Widget::col(vec![
|
||||
txt.draw(ctx),
|
||||
Btn::text_bg2("OK").build_def(ctx, hotkeys(vec![Key::Enter, Key::Escape])),
|
||||
]))
|
||||
.build(ctx),
|
||||
unzoomed,
|
||||
zoomed,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl State for PopupMsg {
|
||||
fn event(&mut self, ctx: &mut EventCtx, _: &mut App) -> Transition {
|
||||
match self.composite.event(ctx) {
|
||||
Outcome::Clicked(x) => match x.as_ref() {
|
||||
"OK" => Transition::Pop,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => {
|
||||
if ctx.normal_left_click() && ctx.canvas.get_cursor_in_screen_space().is_none() {
|
||||
return Transition::Pop;
|
||||
}
|
||||
Transition::Keep
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_baselayer(&self) -> DrawBaselayer {
|
||||
DrawBaselayer::PreviousState
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, app: &App) {
|
||||
State::grey_out_map(g, app);
|
||||
self.composite.draw(g);
|
||||
if g.canvas.cam_zoom < app.opts.min_zoom_for_detail {
|
||||
g.redraw(&self.unzoomed);
|
||||
} else {
|
||||
g.redraw(&self.zoomed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::app::App;
|
||||
use crate::challenges::ChallengesPicker;
|
||||
use crate::devtools::DevToolsMode;
|
||||
use crate::edit::apply_map_edits;
|
||||
use crate::game::{msg, DrawBaselayer, State, Transition};
|
||||
use crate::game::{DrawBaselayer, PopupMsg, State, Transition};
|
||||
use crate::helpers::open_browser;
|
||||
use crate::sandbox::gameplay::Tutorial;
|
||||
use crate::sandbox::{GameplayMode, SandboxMode};
|
||||
@ -428,7 +428,11 @@ impl State for Proposals {
|
||||
}
|
||||
});
|
||||
if let Some(err) = maybe_err {
|
||||
return Transition::Push(msg("Can't load proposal", vec![err]));
|
||||
return Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Can't load proposal",
|
||||
vec![err],
|
||||
));
|
||||
} else {
|
||||
app.layer = Some(Box::new(crate::layer::map::Static::edits(ctx, app)));
|
||||
return Transition::Push(Box::new(SandboxMode::new(
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::app::App;
|
||||
use crate::common::CityPicker;
|
||||
use crate::edit::EditMode;
|
||||
use crate::game::{msg, State, Transition};
|
||||
use crate::game::{PopupMsg, State, Transition};
|
||||
use crate::helpers::{checkbox_per_mode, nice_map_name};
|
||||
use crate::sandbox::gameplay::freeform::make_change_traffic;
|
||||
use crate::sandbox::gameplay::{GameplayMode, GameplayState};
|
||||
@ -370,13 +370,15 @@ impl State for ChangeMode {
|
||||
from_modes.remove(&to_mode);
|
||||
|
||||
if from_modes.is_empty() {
|
||||
return Transition::Push(msg(
|
||||
return Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec!["You have to select at least one mode to convert from"],
|
||||
));
|
||||
}
|
||||
if p1 >= p2 {
|
||||
return Transition::Push(msg(
|
||||
return Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec!["Your time range is backwards"],
|
||||
));
|
||||
|
@ -2,7 +2,7 @@ use crate::app::App;
|
||||
use crate::common::{tool_panel, Minimap, Warping};
|
||||
use crate::cutscene::CutsceneBuilder;
|
||||
use crate::edit::EditMode;
|
||||
use crate::game::{msg, State, Transition};
|
||||
use crate::game::{PopupMsg, State, Transition};
|
||||
use crate::helpers::ID;
|
||||
use crate::sandbox::gameplay::{GameplayMode, GameplayState};
|
||||
use crate::sandbox::{
|
||||
@ -265,7 +265,8 @@ impl Tutorial {
|
||||
if !tut.score_delivered {
|
||||
tut.score_delivered = true;
|
||||
if before == after {
|
||||
return Some(Transition::Push(msg(
|
||||
return Some(Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"All trips completed",
|
||||
vec![
|
||||
"Your changes didn't affect anything!",
|
||||
@ -274,7 +275,8 @@ impl Tutorial {
|
||||
)));
|
||||
}
|
||||
if after > before {
|
||||
return Some(Transition::Push(msg(
|
||||
return Some(Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"All trips completed",
|
||||
vec![
|
||||
"Your changes made things worse!".to_string(),
|
||||
@ -288,7 +290,8 @@ impl Tutorial {
|
||||
)));
|
||||
}
|
||||
if before - after < CAR_BIKE_CONTENTION_GOAL {
|
||||
return Some(Transition::Push(msg(
|
||||
return Some(Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"All trips completed",
|
||||
vec![
|
||||
"Nice, you helped things a bit!".to_string(),
|
||||
@ -301,7 +304,8 @@ impl Tutorial {
|
||||
],
|
||||
)));
|
||||
}
|
||||
return Some(Transition::Push(msg(
|
||||
return Some(Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"All trips completed",
|
||||
vec![format!(
|
||||
"Awesome! All trips originally took {}, but now they only took {}",
|
||||
@ -1329,7 +1333,7 @@ pub fn actions(app: &App, id: ID) -> Vec<(Key, String)> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Transition {
|
||||
pub fn execute(ctx: &mut EventCtx, app: &mut App, id: ID, action: String) -> Transition {
|
||||
let mut tut = app.session.tutorial.as_mut().unwrap();
|
||||
let response = match (id, action.as_ref()) {
|
||||
(ID::Car(c), "draw WASH ME") => {
|
||||
@ -1341,12 +1345,14 @@ pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Trans
|
||||
if c == ESCORT {
|
||||
if is_parked {
|
||||
tut.prank_done = true;
|
||||
msg(
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"Prank in progress",
|
||||
vec!["You quickly scribble on the window..."],
|
||||
)
|
||||
} else {
|
||||
msg(
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"Not yet!",
|
||||
vec![
|
||||
"You're going to run up to an occupied car and draw on their windows?",
|
||||
@ -1356,7 +1362,8 @@ pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Trans
|
||||
)
|
||||
}
|
||||
} else if c.1 == VehicleType::Bike {
|
||||
msg(
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"That's a bike",
|
||||
vec![
|
||||
"Achievement unlocked: You attempted to draw WASH ME on a cyclist.",
|
||||
@ -1366,7 +1373,8 @@ pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Trans
|
||||
],
|
||||
)
|
||||
} else {
|
||||
msg(
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"Wrong car",
|
||||
vec![
|
||||
"You're looking at the wrong car.",
|
||||
@ -1382,7 +1390,8 @@ pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Trans
|
||||
let percent = (app.primary.sim.get_free_onstreet_spots(l).len() as f64)
|
||||
/ (lane.number_parking_spots() as f64);
|
||||
if percent > 0.1 {
|
||||
msg(
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"Not quite",
|
||||
vec![
|
||||
format!("This lane has {:.0}% spots free", percent * 100.0),
|
||||
@ -1392,10 +1401,14 @@ pub fn execute(_: &mut EventCtx, app: &mut App, id: ID, action: String) -> Trans
|
||||
)
|
||||
} else {
|
||||
tut.parking_found = true;
|
||||
msg("Noice", vec!["Yup, parallel parking would be tough here!"])
|
||||
PopupMsg::new(
|
||||
ctx,
|
||||
"Noice",
|
||||
vec!["Yup, parallel parking would be tough here!"],
|
||||
)
|
||||
}
|
||||
} else {
|
||||
msg("Uhh..", vec!["That's not even a parking lane"])
|
||||
PopupMsg::new(ctx, "Uhh..", vec!["That's not even a parking lane"])
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::app::{App, FindDelayedIntersections, ShowEverything};
|
||||
use crate::common::Warping;
|
||||
use crate::game::{msg, DrawBaselayer, State, Transition};
|
||||
use crate::game::{DrawBaselayer, PopupMsg, State, Transition};
|
||||
use crate::helpers::ID;
|
||||
use crate::render::DrawOptions;
|
||||
use crate::sandbox::{GameplayMode, SandboxMode};
|
||||
@ -181,7 +181,8 @@ impl SpeedControls {
|
||||
mode.clone(),
|
||||
))));
|
||||
} else {
|
||||
return Some(Transition::Push(msg(
|
||||
return Some(Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec!["Sorry, you can't go rewind time from this mode."],
|
||||
)));
|
||||
@ -284,7 +285,11 @@ impl SpeedControls {
|
||||
// TODO Need to do this anywhere that steps the sim, like TimeWarpScreen.
|
||||
let alerts = app.primary.sim.clear_alerts();
|
||||
if !alerts.is_empty() {
|
||||
let popup = msg("Alerts", alerts.iter().map(|(_, _, msg)| msg).collect());
|
||||
let popup = PopupMsg::new(
|
||||
ctx,
|
||||
"Alerts",
|
||||
alerts.iter().map(|(_, _, msg)| msg).collect(),
|
||||
);
|
||||
let maybe_id = match alerts[0].1 {
|
||||
AlertLocation::Nil => None,
|
||||
AlertLocation::Intersection(i) => Some(ID::Intersection(i)),
|
||||
@ -432,7 +437,8 @@ impl State for JumpToTime {
|
||||
TimeWarpScreen::new(ctx, app, self.target, false),
|
||||
);
|
||||
} else {
|
||||
return Transition::Replace(msg(
|
||||
return Transition::Replace(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec!["Sorry, you can't go rewind time from this mode."],
|
||||
));
|
||||
@ -541,7 +547,8 @@ impl State for TimeWarpScreen {
|
||||
);
|
||||
for (t, maybe_i, alert) in app.primary.sim.clear_alerts() {
|
||||
// TODO Just the first :(
|
||||
return Transition::Replace(msg(
|
||||
return Transition::Replace(PopupMsg::new(
|
||||
ctx,
|
||||
"Alert",
|
||||
vec![format!("At {}, near {:?}, {}", t, maybe_i, alert)],
|
||||
));
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::app::{App, ShowEverything};
|
||||
use crate::common::CommonState;
|
||||
use crate::edit::ClusterTrafficSignalEditor;
|
||||
use crate::game::{msg, DrawBaselayer, State, Transition};
|
||||
use crate::game::{DrawBaselayer, PopupMsg, State, Transition};
|
||||
use crate::helpers::ID;
|
||||
use crate::render::{DrawOptions, BIG_ARROW_THICKNESS};
|
||||
use ezgui::{
|
||||
@ -71,7 +71,8 @@ impl State for UberTurnPicker {
|
||||
}
|
||||
"View uber-turns" => {
|
||||
if self.members.len() < 2 {
|
||||
return Transition::Push(msg(
|
||||
return Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec!["Select at least two intersections"],
|
||||
));
|
||||
@ -86,7 +87,8 @@ impl State for UberTurnPicker {
|
||||
}
|
||||
"Edit" => {
|
||||
if self.members.len() < 2 {
|
||||
return Transition::Push(msg(
|
||||
return Transition::Push(PopupMsg::new(
|
||||
ctx,
|
||||
"Error",
|
||||
vec!["Select at least two intersections"],
|
||||
));
|
||||
|
Loading…
Reference in New Issue
Block a user