confirm before bailing out of sandbox mode

This commit is contained in:
Dustin Carlino 2019-11-01 20:43:09 -07:00
parent fa99c28d23
commit 432995d8e5
4 changed files with 45 additions and 3 deletions

View File

@ -316,6 +316,7 @@ fn save_edits(wiz: &mut Wizard, ctx: &mut EventCtx, ui: &mut UI) -> Option<Trans
} else {
None
};
// TODO Don't allow naming them no_edits!
// TODO Do it this weird way to avoid saving edits on every event. :P
let save = "save edits";

View File

@ -35,6 +35,7 @@ impl GUI for Game {
let transition = match self.states.last_mut().unwrap().event(ctx, &mut self.ui) {
Transition::Keep => Transition::KeepWithMode(EventLoopMode::InputOnly),
Transition::Pop => Transition::PopWithMode(EventLoopMode::InputOnly),
Transition::PopTwice => Transition::PopTwiceWithMode(EventLoopMode::InputOnly),
Transition::Push(state) => Transition::PushWithMode(state, EventLoopMode::InputOnly),
Transition::Replace(state) => {
Transition::ReplaceWithMode(state, EventLoopMode::InputOnly)
@ -55,6 +56,15 @@ impl GUI for Game {
}
evmode
}
Transition::PopTwiceWithMode(evmode) => {
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
if self.states.is_empty() {
self.before_quit(ctx.canvas);
std::process::exit(0);
}
evmode
}
Transition::PopWithData(cb) => {
self.states.pop().unwrap().on_destroy(ctx, &mut self.ui);
cb(self.states.last_mut().unwrap(), &mut self.ui, ctx);
@ -147,6 +157,7 @@ pub enum Transition {
// These variants imply EventLoopMode::InputOnly.
Keep,
Pop,
PopTwice,
// If a state needs to pass data back to the parent, use this. Sadly, runtime type casting.
PopWithData(Box<dyn FnOnce(&mut Box<dyn State>, &mut UI, &mut EventCtx)>),
Push(Box<dyn State>),
@ -156,6 +167,7 @@ pub enum Transition {
// These don't.
KeepWithMode(EventLoopMode),
PopWithMode(EventLoopMode),
PopTwiceWithMode(EventLoopMode),
PushWithMode(Box<dyn State>, EventLoopMode),
ReplaceWithMode(Box<dyn State>, EventLoopMode),
PopThenReplaceWithMode(Box<dyn State>, EventLoopMode),

View File

@ -145,9 +145,37 @@ impl State for SandboxMode {
}
if self.general_tools.action("back to title screen") {
// TODO Clear edits? Warn about unsaved?
ui.primary.clear_sim();
return Transition::Pop;
// TODO Clear edits?
return Transition::Push(WizardState::new(Box::new(move |wiz, ctx, ui| {
// TODO Open up a dialog if the edits need a name!
let dirty = ui.primary.map.get_edits().dirty
&& ui.primary.map.get_edits().edits_name != "no_edits";
let (resp, _) = wiz.wrap(ctx).choose(
"Sure you want to abandon the current challenge?",
|| {
let mut choices = Vec::new();
choices.push(Choice::new("keep playing", ()));
if dirty {
choices.push(Choice::new("save edits and quit", ()));
}
choices.push(Choice::new("quit challenge", ()));
choices
},
)?;
match resp.as_str() {
"save edits and quit" => {
ui.primary.map.save_edits();
ui.primary.clear_sim();
Some(Transition::PopTwice)
}
"quit challenge" => {
ui.primary.clear_sim();
Some(Transition::PopTwice)
}
"keep playing" => Some(Transition::Pop),
_ => unreachable!(),
}
})));
}
if self.general_tools.action("debug mode") {
return Transition::Push(Box::new(DebugMode::new(ctx, ui)));

View File

@ -47,6 +47,7 @@ impl MapEdits {
// TODO Version these
pub(crate) fn save(&mut self) {
assert!(self.dirty);
assert_ne!(self.edits_name, "no_edits");
abstutil::save_json_object(abstutil::EDITS, &self.map_name, &self.edits_name, self);
self.dirty = false;
}