mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-29 04:35:51 +03:00
prompts on top of menus, too
This commit is contained in:
parent
b66e6891f6
commit
f1f0683026
@ -196,3 +196,5 @@ previous answers. The caller could even build a branching workflow -- as long
|
|||||||
as the calls to the wizard are deterministic.
|
as the calls to the wizard are deterministic.
|
||||||
|
|
||||||
Menus are super awkward -- drawing extra effects, mainly.
|
Menus are super awkward -- drawing extra effects, mainly.
|
||||||
|
|
||||||
|
cursive crate is good inspiration for the API
|
||||||
|
@ -33,6 +33,7 @@ impl ColorPicker {
|
|||||||
ColorPicker::Inactive => {
|
ColorPicker::Inactive => {
|
||||||
if input.unimportant_key_pressed(Key::D8, "configure colors") {
|
if input.unimportant_key_pressed(Key::D8, "configure colors") {
|
||||||
new_state = Some(ColorPicker::Choosing(Menu::new(
|
new_state = Some(ColorPicker::Choosing(Menu::new(
|
||||||
|
"Pick a color to change",
|
||||||
Colors::iter().map(|c| c.to_string()).collect(),
|
Colors::iter().map(|c| c.to_string()).collect(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ impl DrawPolygonState {
|
|||||||
println!("Sorry, no existing polygons");
|
println!("Sorry, no existing polygons");
|
||||||
} else {
|
} else {
|
||||||
new_state = Some(DrawPolygonState::ListingPolygons(
|
new_state = Some(DrawPolygonState::ListingPolygons(
|
||||||
Menu::new(polygons.keys().cloned().collect()),
|
Menu::new("Load which polygon?", polygons.keys().cloned().collect()),
|
||||||
polygons,
|
polygons,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -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 geom::Polygon;
|
||||||
use map_model::Map;
|
use map_model::Map;
|
||||||
use piston::input::Key;
|
use piston::input::Key;
|
||||||
@ -32,7 +32,7 @@ impl WizardSample {
|
|||||||
WizardSample::Inactive
|
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;
|
let mut new_state: Option<WizardSample> = None;
|
||||||
match self {
|
match self {
|
||||||
WizardSample::Inactive => {
|
WizardSample::Inactive => {
|
||||||
@ -41,7 +41,7 @@ impl WizardSample {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
WizardSample::Active(ref mut wizard) => {
|
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);
|
println!("Got answer: {:?}", spec);
|
||||||
new_state = Some(WizardSample::Inactive);
|
new_state = Some(WizardSample::Inactive);
|
||||||
} else if wizard.aborted() {
|
} else if wizard.aborted() {
|
||||||
@ -120,12 +120,7 @@ impl Wizard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap<'a>(
|
fn wrap<'a>(&'a mut self, input: &'a mut UserInput, map: &'a Map) -> WrappedWizard<'a> {
|
||||||
&'a mut self,
|
|
||||||
input: &'a mut UserInput,
|
|
||||||
map: &'a Map,
|
|
||||||
osd: &'a mut TextOSD,
|
|
||||||
) -> WrappedWizard<'a> {
|
|
||||||
assert!(self.alive);
|
assert!(self.alive);
|
||||||
|
|
||||||
let ready_usize = VecDeque::from(self.state_usize.clone());
|
let ready_usize = VecDeque::from(self.state_usize.clone());
|
||||||
@ -136,7 +131,6 @@ impl Wizard {
|
|||||||
wizard: self,
|
wizard: self,
|
||||||
input,
|
input,
|
||||||
map,
|
map,
|
||||||
osd,
|
|
||||||
ready_usize,
|
ready_usize,
|
||||||
ready_tick,
|
ready_tick,
|
||||||
ready_percent,
|
ready_percent,
|
||||||
@ -153,7 +147,6 @@ impl Wizard {
|
|||||||
query: &str,
|
query: &str,
|
||||||
choices: Vec<String>,
|
choices: Vec<String>,
|
||||||
input: &mut UserInput,
|
input: &mut UserInput,
|
||||||
osd: &mut TextOSD,
|
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
assert!(self.alive);
|
assert!(self.alive);
|
||||||
|
|
||||||
@ -163,7 +156,7 @@ impl Wizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.menu.is_none() {
|
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) {
|
match self.menu.as_mut().unwrap().event(input) {
|
||||||
@ -172,13 +165,7 @@ impl Wizard {
|
|||||||
self.alive = false;
|
self.alive = false;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
InputResult::StillActive => {
|
InputResult::StillActive => None,
|
||||||
// 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::Done(choice) => {
|
InputResult::Done(choice) => {
|
||||||
self.menu = None;
|
self.menu = None;
|
||||||
Some(choice)
|
Some(choice)
|
||||||
@ -228,7 +215,6 @@ struct WrappedWizard<'a> {
|
|||||||
wizard: &'a mut Wizard,
|
wizard: &'a mut Wizard,
|
||||||
input: &'a mut UserInput,
|
input: &'a mut UserInput,
|
||||||
map: &'a Map,
|
map: &'a Map,
|
||||||
osd: &'a mut TextOSD,
|
|
||||||
|
|
||||||
ready_usize: VecDeque<usize>,
|
ready_usize: VecDeque<usize>,
|
||||||
ready_tick: VecDeque<Tick>,
|
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> {
|
fn choose(&mut self, query: &str, choices: Vec<&str>) -> Option<String> {
|
||||||
if !self.ready_choices.is_empty() {
|
if !self.ready_choices.is_empty() {
|
||||||
return self.ready_choices.pop_front();
|
return self.ready_choices.pop_front();
|
||||||
@ -300,7 +287,6 @@ impl<'a> WrappedWizard<'a> {
|
|||||||
query,
|
query,
|
||||||
choices.iter().map(|s| s.to_string()).collect(),
|
choices.iter().map(|s| s.to_string()).collect(),
|
||||||
self.input,
|
self.input,
|
||||||
self.osd,
|
|
||||||
) {
|
) {
|
||||||
self.wizard.state_choices.push(choice.clone());
|
self.wizard.state_choices.push(choice.clone());
|
||||||
Some(choice)
|
Some(choice)
|
||||||
@ -324,10 +310,7 @@ impl<'a> WrappedWizard<'a> {
|
|||||||
.keys()
|
.keys()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
let result = if let Some(choice) = self
|
let result = if let Some(choice) = self.wizard.input_with_menu(query, names, self.input) {
|
||||||
.wizard
|
|
||||||
.input_with_menu(query, names, self.input, self.osd)
|
|
||||||
{
|
|
||||||
self.wizard.state_choices.push(choice.clone());
|
self.wizard.state_choices.push(choice.clone());
|
||||||
Some(choice)
|
Some(choice)
|
||||||
} else {
|
} else {
|
||||||
|
@ -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.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.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)),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@ use piston::input::{Button, Key, PressEvent};
|
|||||||
use {InputResult, TextOSD, UserInput};
|
use {InputResult, TextOSD, UserInput};
|
||||||
|
|
||||||
pub struct Menu {
|
pub struct Menu {
|
||||||
|
prompt: String,
|
||||||
choices: Vec<String>,
|
choices: Vec<String>,
|
||||||
current_idx: usize,
|
current_idx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Menu {
|
impl Menu {
|
||||||
pub fn new(choices: Vec<String>) -> Menu {
|
pub fn new(prompt: &str, choices: Vec<String>) -> Menu {
|
||||||
Menu {
|
Menu {
|
||||||
|
prompt: prompt.to_string(),
|
||||||
choices,
|
choices,
|
||||||
current_idx: 0,
|
current_idx: 0,
|
||||||
}
|
}
|
||||||
@ -44,6 +46,8 @@ impl Menu {
|
|||||||
// display one size for the menu, just dont fill everything out
|
// display one size for the menu, just dont fill everything out
|
||||||
pub fn get_osd(&self) -> TextOSD {
|
pub fn get_osd(&self) -> TextOSD {
|
||||||
let mut osd = TextOSD::new();
|
let mut osd = TextOSD::new();
|
||||||
|
// TODO different color
|
||||||
|
osd.add_line(self.prompt.clone());
|
||||||
for (idx, line) in self.choices.iter().enumerate() {
|
for (idx, line) in self.choices.iter().enumerate() {
|
||||||
if self.current_idx == idx {
|
if self.current_idx == idx {
|
||||||
osd.add_highlighted_line(line.clone());
|
osd.add_highlighted_line(line.clone());
|
||||||
|
Loading…
Reference in New Issue
Block a user