mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 16:02:23 +03:00
hotkeys on the wizard splash screen
This commit is contained in:
parent
8e20e0fa89
commit
01628624c0
@ -319,17 +319,18 @@ fn choose_preset(
|
||||
) -> Option<ControlTrafficSignal> {
|
||||
// TODO I wanted to do all of this work just once per wizard, but we can't touch map inside a
|
||||
// closure. Grr.
|
||||
let mut choices: Vec<(String, ControlTrafficSignal)> = Vec::new();
|
||||
let mut choices: Vec<(Option<Key>, String, ControlTrafficSignal)> = Vec::new();
|
||||
if let Some(ts) = ControlTrafficSignal::four_way_four_phase(map, id) {
|
||||
choices.push(("four-phase".to_string(), ts));
|
||||
choices.push((None, "four-phase".to_string(), ts));
|
||||
}
|
||||
if let Some(ts) = ControlTrafficSignal::four_way_two_phase(map, id) {
|
||||
choices.push(("two-phase".to_string(), ts));
|
||||
choices.push((None, "two-phase".to_string(), ts));
|
||||
}
|
||||
if let Some(ts) = ControlTrafficSignal::three_way(map, id) {
|
||||
choices.push(("three-phase".to_string(), ts));
|
||||
choices.push((None, "three-phase".to_string(), ts));
|
||||
}
|
||||
choices.push((
|
||||
None,
|
||||
"arbitrary assignment".to_string(),
|
||||
ControlTrafficSignal::greedy_assignment(map, id).unwrap(),
|
||||
));
|
||||
|
@ -8,8 +8,8 @@ use crate::tutorial::TutorialMode;
|
||||
use crate::ui::UI;
|
||||
use abstutil::elapsed_seconds;
|
||||
use ezgui::{
|
||||
Canvas, EventCtx, EventLoopMode, GfxCtx, LogScroller, ModalMenu, Prerender, TopMenu, UserInput,
|
||||
Wizard, GUI,
|
||||
Canvas, EventCtx, EventLoopMode, GfxCtx, Key, LogScroller, ModalMenu, Prerender, TopMenu,
|
||||
UserInput, Wizard, GUI,
|
||||
};
|
||||
use geom::{Duration, Line, Pt2D, Speed};
|
||||
use map_model::Map;
|
||||
@ -193,11 +193,21 @@ fn splash_screen(
|
||||
|
||||
// Loop because we might go from About -> top-level menu repeatedly, and recursion is scary.
|
||||
loop {
|
||||
// TODO No hotkey for quit because it's just the normal menu escape?
|
||||
match wizard
|
||||
.choose_string(
|
||||
.choose_string_hotkeys(
|
||||
"Welcome to A/B Street!",
|
||||
vec![
|
||||
sandbox, load_map, edit, tutorial, debug, mission, abtest, legacy, about, quit,
|
||||
(Some(Key::S), sandbox),
|
||||
(Some(Key::L), load_map),
|
||||
(Some(Key::E), edit),
|
||||
(Some(Key::T), tutorial),
|
||||
(Some(Key::D), debug),
|
||||
(Some(Key::M), mission),
|
||||
(Some(Key::A), abtest),
|
||||
(None, legacy),
|
||||
(Some(Key::A), about),
|
||||
(None, quit),
|
||||
],
|
||||
)?
|
||||
.as_str()
|
||||
@ -205,7 +215,7 @@ fn splash_screen(
|
||||
x if x == sandbox => break Some(Mode::Sandbox(SandboxMode::new())),
|
||||
x if x == load_map => {
|
||||
let current_map = ui.state.primary.map.get_name().to_string();
|
||||
if let Some((name, _)) = wizard.choose_something::<String>(
|
||||
if let Some((name, _)) = wizard.choose_something_no_keys::<String>(
|
||||
"Load which map?",
|
||||
Box::new(move || {
|
||||
abstutil::list_all_objects("maps", "")
|
||||
|
@ -77,7 +77,7 @@ pub fn choose_neighborhood(map: &Map, wizard: &mut WrappedWizard, query: &str) -
|
||||
let gps_bounds = map.get_gps_bounds().clone();
|
||||
// Load the full object, since various plugins visualize the neighborhood when menuing over it
|
||||
wizard
|
||||
.choose_something::<Neighborhood>(
|
||||
.choose_something_no_keys::<Neighborhood>(
|
||||
query,
|
||||
Box::new(move || Neighborhood::load_all(&map_name, &gps_bounds)),
|
||||
)
|
||||
@ -91,7 +91,7 @@ pub fn load_neighborhood_builder(
|
||||
) -> Option<NeighborhoodBuilder> {
|
||||
let map_name = map.get_name().to_string();
|
||||
wizard
|
||||
.choose_something::<NeighborhoodBuilder>(
|
||||
.choose_something_no_keys::<NeighborhoodBuilder>(
|
||||
query,
|
||||
Box::new(move || abstutil::load_all_objects("neighborhoods", &map_name)),
|
||||
)
|
||||
@ -101,7 +101,7 @@ pub fn load_neighborhood_builder(
|
||||
pub fn load_scenario(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Option<Scenario> {
|
||||
let map_name = map.get_name().to_string();
|
||||
wizard
|
||||
.choose_something::<Scenario>(
|
||||
.choose_something_no_keys::<Scenario>(
|
||||
query,
|
||||
Box::new(move || abstutil::load_all_objects("scenarios", &map_name)),
|
||||
)
|
||||
@ -111,7 +111,7 @@ pub fn load_scenario(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Opti
|
||||
pub fn choose_scenario(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Option<String> {
|
||||
let map_name = map.get_name().to_string();
|
||||
wizard
|
||||
.choose_something::<String>(
|
||||
.choose_something_no_keys::<String>(
|
||||
query,
|
||||
Box::new(move || abstutil::list_all_objects("scenarios", &map_name)),
|
||||
)
|
||||
@ -121,7 +121,7 @@ pub fn choose_scenario(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Op
|
||||
pub fn choose_edits(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Option<String> {
|
||||
let map_name = map.get_name().to_string();
|
||||
wizard
|
||||
.choose_something::<String>(
|
||||
.choose_something_no_keys::<String>(
|
||||
query,
|
||||
Box::new(move || {
|
||||
let mut list = abstutil::list_all_objects("edits", &map_name);
|
||||
@ -136,7 +136,7 @@ pub fn load_edits(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Option<
|
||||
// TODO Exclude current?
|
||||
let map_name = map.get_name().to_string();
|
||||
wizard
|
||||
.choose_something::<MapEdits>(
|
||||
.choose_something_no_keys::<MapEdits>(
|
||||
query,
|
||||
Box::new(move || {
|
||||
let mut list = abstutil::load_all_objects("edits", &map_name);
|
||||
@ -150,7 +150,7 @@ pub fn load_edits(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Option<
|
||||
pub fn load_ab_test(map: &Map, wizard: &mut WrappedWizard, query: &str) -> Option<ABTest> {
|
||||
let map_name = map.get_name().to_string();
|
||||
wizard
|
||||
.choose_something::<ABTest>(
|
||||
.choose_something_no_keys::<ABTest>(
|
||||
query,
|
||||
Box::new(move || abstutil::load_all_objects("ab_tests", &map_name)),
|
||||
)
|
||||
|
@ -175,7 +175,7 @@ impl<'a> WrappedWizard<'a> {
|
||||
pub fn choose_something<R: 'static + Clone + Cloneable>(
|
||||
&mut self,
|
||||
query: &str,
|
||||
choices_generator: Box<Fn() -> Vec<(String, R)>>,
|
||||
choices_generator: Box<Fn() -> Vec<(Option<Key>, String, R)>>,
|
||||
) -> Option<(String, R)> {
|
||||
if !self.ready_results.is_empty() {
|
||||
let first = self.ready_results.pop_front().unwrap();
|
||||
@ -199,7 +199,7 @@ impl<'a> WrappedWizard<'a> {
|
||||
}
|
||||
|
||||
if self.wizard.menu.is_none() {
|
||||
let choices: Vec<(String, R)> = choices_generator();
|
||||
let choices: Vec<(Option<Key>, String, R)> = choices_generator();
|
||||
if choices.is_empty() {
|
||||
self.wizard.log_scroller = Some(LogScroller::new(
|
||||
"Wizard".to_string(),
|
||||
@ -208,8 +208,8 @@ impl<'a> WrappedWizard<'a> {
|
||||
return None;
|
||||
}
|
||||
let boxed_choices: Vec<(Option<Key>, String, Box<Cloneable>)> = choices
|
||||
.iter()
|
||||
.map(|(s, item)| (None, s.to_string(), item.clone_box()))
|
||||
.into_iter()
|
||||
.map(|(key, s, item)| (key, s, item.clone_box()))
|
||||
.collect();
|
||||
self.wizard.menu = Some(Menu::new(
|
||||
Some(Text::from_styled_line(
|
||||
@ -251,11 +251,42 @@ impl<'a> WrappedWizard<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn choose_something_no_keys<R: 'static + Clone + Cloneable>(
|
||||
&mut self,
|
||||
query: &str,
|
||||
choices_generator: Box<Fn() -> Vec<(String, R)>>,
|
||||
) -> Option<(String, R)> {
|
||||
let wrapped_generator = Box::new(move || {
|
||||
choices_generator()
|
||||
.into_iter()
|
||||
.map(|(name, data)| (None, name, data))
|
||||
.collect()
|
||||
});
|
||||
self.choose_something(query, wrapped_generator)
|
||||
}
|
||||
|
||||
pub fn choose_string(&mut self, query: &str, choices: Vec<&str>) -> Option<String> {
|
||||
// Clone the choices outside of the closure to get around the fact that choices_generator's
|
||||
// lifetime isn't correctly specified.
|
||||
let copied_choices: Vec<(String, ())> =
|
||||
choices.into_iter().map(|s| (s.to_string(), ())).collect();
|
||||
let copied_choices: Vec<(Option<Key>, String, ())> = choices
|
||||
.into_iter()
|
||||
.map(|s| (None, s.to_string(), ()))
|
||||
.collect();
|
||||
self.choose_something(query, Box::new(move || copied_choices.clone()))
|
||||
.map(|(s, _)| s)
|
||||
}
|
||||
|
||||
pub fn choose_string_hotkeys(
|
||||
&mut self,
|
||||
query: &str,
|
||||
choices: Vec<(Option<Key>, &str)>,
|
||||
) -> Option<String> {
|
||||
// Clone the choices outside of the closure to get around the fact that choices_generator's
|
||||
// lifetime isn't correctly specified.
|
||||
let copied_choices: Vec<(Option<Key>, String, ())> = choices
|
||||
.into_iter()
|
||||
.map(|(key, s)| (key, s.to_string(), ()))
|
||||
.collect();
|
||||
self.choose_something(query, Box::new(move || copied_choices.clone()))
|
||||
.map(|(s, _)| s)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user