prompts on top of menus, too

This commit is contained in:
Dustin Carlino 2018-09-20 19:49:31 -07:00
parent b66e6891f6
commit f1f0683026
6 changed files with 18 additions and 28 deletions

View File

@ -196,3 +196,5 @@ previous answers. The caller could even build a branching workflow -- as long
as the calls to the wizard are deterministic.
Menus are super awkward -- drawing extra effects, mainly.
cursive crate is good inspiration for the API

View File

@ -33,6 +33,7 @@ impl ColorPicker {
ColorPicker::Inactive => {
if input.unimportant_key_pressed(Key::D8, "configure colors") {
new_state = Some(ColorPicker::Choosing(Menu::new(
"Pick a color to change",
Colors::iter().map(|c| c.to_string()).collect(),
)));
}

View File

@ -53,7 +53,7 @@ impl DrawPolygonState {
println!("Sorry, no existing polygons");
} else {
new_state = Some(DrawPolygonState::ListingPolygons(
Menu::new(polygons.keys().cloned().collect()),
Menu::new("Load which polygon?", polygons.keys().cloned().collect()),
polygons,
));
}

View File

@ -1,4 +1,4 @@
use ezgui::{Canvas, GfxCtx, InputResult, Menu, TextBox, TextOSD, UserInput};
use ezgui::{Canvas, GfxCtx, InputResult, Menu, TextBox, UserInput};
use geom::Polygon;
use map_model::Map;
use piston::input::Key;
@ -32,7 +32,7 @@ impl WizardSample {
WizardSample::Inactive
}
pub fn event(&mut self, input: &mut UserInput, map: &Map, osd: &mut TextOSD) -> bool {
pub fn event(&mut self, input: &mut UserInput, map: &Map) -> bool {
let mut new_state: Option<WizardSample> = None;
match self {
WizardSample::Inactive => {
@ -41,7 +41,7 @@ impl WizardSample {
}
}
WizardSample::Active(ref mut wizard) => {
if let Some(spec) = workflow(wizard.wrap(input, map, osd)) {
if let Some(spec) = workflow(wizard.wrap(input, map)) {
println!("Got answer: {:?}", spec);
new_state = Some(WizardSample::Inactive);
} else if wizard.aborted() {
@ -120,12 +120,7 @@ impl Wizard {
}
}
fn wrap<'a>(
&'a mut self,
input: &'a mut UserInput,
map: &'a Map,
osd: &'a mut TextOSD,
) -> WrappedWizard<'a> {
fn wrap<'a>(&'a mut self, input: &'a mut UserInput, map: &'a Map) -> WrappedWizard<'a> {
assert!(self.alive);
let ready_usize = VecDeque::from(self.state_usize.clone());
@ -136,7 +131,6 @@ impl Wizard {
wizard: self,
input,
map,
osd,
ready_usize,
ready_tick,
ready_percent,
@ -153,7 +147,6 @@ impl Wizard {
query: &str,
choices: Vec<String>,
input: &mut UserInput,
osd: &mut TextOSD,
) -> Option<String> {
assert!(self.alive);
@ -163,7 +156,7 @@ impl Wizard {
}
if self.menu.is_none() {
self.menu = Some(Menu::new(choices));
self.menu = Some(Menu::new(query, choices));
}
match self.menu.as_mut().unwrap().event(input) {
@ -172,13 +165,7 @@ impl Wizard {
self.alive = false;
None
}
InputResult::StillActive => {
// TODO We want to draw this at the top of the menu with choices. Menu should
// probably itself have an optional header line?
osd.pad_if_nonempty();
osd.add_line(query.to_string());
None
}
InputResult::StillActive => None,
InputResult::Done(choice) => {
self.menu = None;
Some(choice)
@ -228,7 +215,6 @@ struct WrappedWizard<'a> {
wizard: &'a mut Wizard,
input: &'a mut UserInput,
map: &'a Map,
osd: &'a mut TextOSD,
ready_usize: VecDeque<usize>,
ready_tick: VecDeque<Tick>,
@ -292,6 +278,7 @@ impl<'a> WrappedWizard<'a> {
}
}
#[allow(dead_code)]
fn choose(&mut self, query: &str, choices: Vec<&str>) -> Option<String> {
if !self.ready_choices.is_empty() {
return self.ready_choices.pop_front();
@ -300,7 +287,6 @@ impl<'a> WrappedWizard<'a> {
query,
choices.iter().map(|s| s.to_string()).collect(),
self.input,
self.osd,
) {
self.wizard.state_choices.push(choice.clone());
Some(choice)
@ -324,10 +310,7 @@ impl<'a> WrappedWizard<'a> {
.keys()
.cloned()
.collect();
let result = if let Some(choice) = self
.wizard
.input_with_menu(query, names, self.input, self.osd)
{
let result = if let Some(choice) = self.wizard.input_with_menu(query, names, self.input) {
self.wizard.state_choices.push(choice.clone());
Some(choice)
} else {

View File

@ -245,7 +245,7 @@ impl UIWrapper {
}),
Box::new(|ui, input, _osd| ui.turn_cycler.event(input, ui.current_selection)),
Box::new(|ui, input, osd| ui.draw_polygon.event(input, &ui.canvas, &ui.map, osd)),
Box::new(|ui, input, osd| ui.wizard_sample.event(input, &ui.map, osd)),
Box::new(|ui, input, _osd| ui.wizard_sample.event(input, &ui.map)),
],
}
}

View File

@ -2,13 +2,15 @@ use piston::input::{Button, Key, PressEvent};
use {InputResult, TextOSD, UserInput};
pub struct Menu {
prompt: String,
choices: Vec<String>,
current_idx: usize,
}
impl Menu {
pub fn new(choices: Vec<String>) -> Menu {
pub fn new(prompt: &str, choices: Vec<String>) -> Menu {
Menu {
prompt: prompt.to_string(),
choices,
current_idx: 0,
}
@ -44,6 +46,8 @@ impl Menu {
// display one size for the menu, just dont fill everything out
pub fn get_osd(&self) -> TextOSD {
let mut osd = TextOSD::new();
// TODO different color
osd.add_line(self.prompt.clone());
for (idx, line) in self.choices.iter().enumerate() {
if self.current_idx == idx {
osd.add_highlighted_line(line.clone());