mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 16:36:02 +03:00
storing associated data with menu
This commit is contained in:
parent
de1033ac66
commit
7836df4580
@ -6,7 +6,6 @@ use graphics;
|
|||||||
use objects::SETTINGS;
|
use objects::SETTINGS;
|
||||||
use piston::input::{Key, MouseCursorEvent};
|
use piston::input::{Key, MouseCursorEvent};
|
||||||
use plugins::Colorizer;
|
use plugins::Colorizer;
|
||||||
use std::str::FromStr;
|
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ const TILE_DIMS: u32 = 2;
|
|||||||
// TODO parts of this should be in ezgui
|
// TODO parts of this should be in ezgui
|
||||||
pub enum ColorPicker {
|
pub enum ColorPicker {
|
||||||
Inactive,
|
Inactive,
|
||||||
Choosing(Menu),
|
Choosing(Menu<Colors>),
|
||||||
// Remember the original color, in case we revert
|
// Remember the original color, in case we revert
|
||||||
PickingColor(Colors, graphics::types::Color),
|
PickingColor(Colors, graphics::types::Color),
|
||||||
}
|
}
|
||||||
@ -35,7 +34,7 @@ impl ColorPicker {
|
|||||||
if input.unimportant_key_pressed(Key::D8, SETTINGS, "configure colors") {
|
if input.unimportant_key_pressed(Key::D8, SETTINGS, "configure colors") {
|
||||||
new_state = Some(ColorPicker::Choosing(Menu::new(
|
new_state = Some(ColorPicker::Choosing(Menu::new(
|
||||||
"Pick a color to change",
|
"Pick a color to change",
|
||||||
Colors::iter().map(|c| c.to_string()).collect(),
|
Colors::iter().map(|c| (c.to_string(), c)).collect(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,9 +44,8 @@ impl ColorPicker {
|
|||||||
new_state = Some(ColorPicker::Inactive);
|
new_state = Some(ColorPicker::Inactive);
|
||||||
}
|
}
|
||||||
InputResult::StillActive => {}
|
InputResult::StillActive => {}
|
||||||
InputResult::Done(choice) => {
|
InputResult::Done(_, color) => {
|
||||||
let c = Colors::from_str(&choice).unwrap();
|
new_state = Some(ColorPicker::PickingColor(color, cs.get(color)));
|
||||||
new_state = Some(ColorPicker::PickingColor(c, cs.get(c)));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ use objects::EDIT_MAP;
|
|||||||
use piston::input::{Button, Key, ReleaseEvent};
|
use piston::input::{Button, Key, ReleaseEvent};
|
||||||
use plugins::Colorizer;
|
use plugins::Colorizer;
|
||||||
use polygons;
|
use polygons;
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
const POINT_RADIUS: f64 = 2.0;
|
const POINT_RADIUS: f64 = 2.0;
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ pub enum DrawPolygonState {
|
|||||||
MovingPoint(Vec<Pt2D>, usize, String),
|
MovingPoint(Vec<Pt2D>, usize, String),
|
||||||
NamingPolygon(TextBox, Vec<Pt2D>),
|
NamingPolygon(TextBox, Vec<Pt2D>),
|
||||||
// String name to each choice, pre-loaded
|
// String name to each choice, pre-loaded
|
||||||
ListingPolygons(Menu, BTreeMap<String, polygons::PolygonSelection>),
|
ListingPolygons(Menu<polygons::PolygonSelection>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawPolygonState {
|
impl DrawPolygonState {
|
||||||
@ -53,10 +52,10 @@ impl DrawPolygonState {
|
|||||||
if polygons.is_empty() {
|
if polygons.is_empty() {
|
||||||
warn!("Sorry, no existing polygons");
|
warn!("Sorry, no existing polygons");
|
||||||
} else {
|
} else {
|
||||||
new_state = Some(DrawPolygonState::ListingPolygons(
|
new_state = Some(DrawPolygonState::ListingPolygons(Menu::new(
|
||||||
Menu::new("Load which polygon?", polygons.keys().cloned().collect()),
|
"Load which polygon?",
|
||||||
polygons,
|
polygons,
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
} else if input.key_pressed(Key::Escape, "throw away this neighborhood polygon") {
|
} else if input.key_pressed(Key::Escape, "throw away this neighborhood polygon") {
|
||||||
new_state = Some(DrawPolygonState::Empty);
|
new_state = Some(DrawPolygonState::Empty);
|
||||||
@ -109,7 +108,7 @@ impl DrawPolygonState {
|
|||||||
info!("Never mind!");
|
info!("Never mind!");
|
||||||
new_state = Some(DrawPolygonState::Empty);
|
new_state = Some(DrawPolygonState::Empty);
|
||||||
}
|
}
|
||||||
InputResult::Done(name) => {
|
InputResult::Done(name, _) => {
|
||||||
let path = format!("../data/polygons/{}/{}", map.get_name(), name);
|
let path = format!("../data/polygons/{}/{}", map.get_name(), name);
|
||||||
abstutil::write_json(
|
abstutil::write_json(
|
||||||
&path,
|
&path,
|
||||||
@ -123,17 +122,17 @@ impl DrawPolygonState {
|
|||||||
}
|
}
|
||||||
InputResult::StillActive => {}
|
InputResult::StillActive => {}
|
||||||
},
|
},
|
||||||
DrawPolygonState::ListingPolygons(ref mut menu, polygons) => {
|
DrawPolygonState::ListingPolygons(ref mut menu) => {
|
||||||
match menu.event(input) {
|
match menu.event(input) {
|
||||||
InputResult::Canceled => {
|
InputResult::Canceled => {
|
||||||
new_state = Some(DrawPolygonState::Empty);
|
new_state = Some(DrawPolygonState::Empty);
|
||||||
}
|
}
|
||||||
InputResult::StillActive => {}
|
InputResult::StillActive => {}
|
||||||
InputResult::Done(choice) => {
|
InputResult::Done(name, poly) => {
|
||||||
new_state = Some(DrawPolygonState::DrawingPoints(
|
new_state = Some(DrawPolygonState::DrawingPoints(
|
||||||
polygons[&choice].points.clone(),
|
poly.points.clone(),
|
||||||
None,
|
None,
|
||||||
choice,
|
name,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -166,9 +165,9 @@ impl DrawPolygonState {
|
|||||||
tb.draw(g, canvas);
|
tb.draw(g, canvas);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DrawPolygonState::ListingPolygons(menu, polygons) => {
|
DrawPolygonState::ListingPolygons(menu) => {
|
||||||
menu.draw(g, canvas);
|
menu.draw(g, canvas);
|
||||||
(&polygons[menu.current_choice()].points, None)
|
(&menu.current_choice().points, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ impl SearchState {
|
|||||||
InputResult::Canceled => {
|
InputResult::Canceled => {
|
||||||
new_state = Some(SearchState::Empty);
|
new_state = Some(SearchState::Empty);
|
||||||
}
|
}
|
||||||
InputResult::Done(filter) => {
|
InputResult::Done(filter, _) => {
|
||||||
new_state = Some(SearchState::FilterOSM(filter));
|
new_state = Some(SearchState::FilterOSM(filter));
|
||||||
}
|
}
|
||||||
InputResult::StillActive => {}
|
InputResult::StillActive => {}
|
||||||
|
@ -36,7 +36,7 @@ impl WarpState {
|
|||||||
InputResult::Canceled => {
|
InputResult::Canceled => {
|
||||||
new_state = Some(WarpState::Empty);
|
new_state = Some(WarpState::Empty);
|
||||||
}
|
}
|
||||||
InputResult::Done(to) => {
|
InputResult::Done(to, _) => {
|
||||||
warp(to, map, sim, canvas, selected);
|
warp(to, map, sim, canvas, selected);
|
||||||
new_state = Some(WarpState::Empty);
|
new_state = Some(WarpState::Empty);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ use piston::input::Key;
|
|||||||
use plugins::Colorizer;
|
use plugins::Colorizer;
|
||||||
use polygons;
|
use polygons;
|
||||||
use sim::Tick;
|
use sim::Tick;
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -66,14 +65,15 @@ impl WizardSample {
|
|||||||
|
|
||||||
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
|
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
|
||||||
if let WizardSample::Active(wizard) = self {
|
if let WizardSample::Active(wizard) = self {
|
||||||
if let Some(ref menu) = wizard.menu {
|
if let Some(ref menu) = wizard.string_menu {
|
||||||
menu.draw(g, canvas);
|
menu.draw(g, canvas);
|
||||||
if let Some(ref polygons) = wizard.polygons {
|
}
|
||||||
g.draw_polygon(
|
if let Some(ref menu) = wizard.polygon_menu {
|
||||||
[0.0, 0.0, 1.0, 0.6],
|
menu.draw(g, canvas);
|
||||||
&Polygon::new(&polygons[menu.current_choice()].points),
|
g.draw_polygon(
|
||||||
);
|
[0.0, 0.0, 1.0, 0.6],
|
||||||
}
|
&Polygon::new(&menu.current_choice().points),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if let Some(ref tb) = wizard.tb {
|
if let Some(ref tb) = wizard.tb {
|
||||||
tb.draw(g, canvas);
|
tb.draw(g, canvas);
|
||||||
@ -101,9 +101,8 @@ fn workflow(mut wizard: WrappedWizard) -> Option<SpawnOverTime> {
|
|||||||
pub struct Wizard {
|
pub struct Wizard {
|
||||||
alive: bool,
|
alive: bool,
|
||||||
tb: Option<TextBox>,
|
tb: Option<TextBox>,
|
||||||
menu: Option<Menu>,
|
string_menu: Option<Menu<()>>,
|
||||||
// If this is present, menu also is.
|
polygon_menu: Option<Menu<polygons::PolygonSelection>>,
|
||||||
polygons: Option<BTreeMap<String, polygons::PolygonSelection>>,
|
|
||||||
|
|
||||||
state_usize: Vec<usize>,
|
state_usize: Vec<usize>,
|
||||||
state_tick: Vec<Tick>,
|
state_tick: Vec<Tick>,
|
||||||
@ -116,8 +115,8 @@ impl Wizard {
|
|||||||
Wizard {
|
Wizard {
|
||||||
alive: true,
|
alive: true,
|
||||||
tb: None,
|
tb: None,
|
||||||
menu: None,
|
string_menu: None,
|
||||||
polygons: None,
|
polygon_menu: None,
|
||||||
state_usize: Vec::new(),
|
state_usize: Vec::new(),
|
||||||
state_tick: Vec::new(),
|
state_tick: Vec::new(),
|
||||||
state_percent: Vec::new(),
|
state_percent: Vec::new(),
|
||||||
@ -147,37 +146,6 @@ impl Wizard {
|
|||||||
!self.alive
|
!self.alive
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input_with_menu(
|
|
||||||
&mut self,
|
|
||||||
query: &str,
|
|
||||||
choices: Vec<String>,
|
|
||||||
input: &mut UserInput,
|
|
||||||
) -> Option<String> {
|
|
||||||
assert!(self.alive);
|
|
||||||
|
|
||||||
// Otherwise, we try to use one event for two inputs potentially
|
|
||||||
if input.has_been_consumed() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.menu.is_none() {
|
|
||||||
self.menu = Some(Menu::new(query, choices));
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.menu.as_mut().unwrap().event(input) {
|
|
||||||
InputResult::Canceled => {
|
|
||||||
self.menu = None;
|
|
||||||
self.alive = false;
|
|
||||||
None
|
|
||||||
}
|
|
||||||
InputResult::StillActive => None,
|
|
||||||
InputResult::Done(choice) => {
|
|
||||||
self.menu = None;
|
|
||||||
Some(choice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn input_with_text_box<R>(
|
fn input_with_text_box<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
query: &str,
|
query: &str,
|
||||||
@ -201,7 +169,7 @@ impl Wizard {
|
|||||||
self.alive = false;
|
self.alive = false;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
InputResult::Done(line) => {
|
InputResult::Done(line, _) => {
|
||||||
self.tb = None;
|
self.tb = None;
|
||||||
if let Some(result) = parser(line.clone()) {
|
if let Some(result) = parser(line.clone()) {
|
||||||
Some(result)
|
Some(result)
|
||||||
@ -288,9 +256,17 @@ impl<'a> WrappedWizard<'a> {
|
|||||||
if !self.ready_choices.is_empty() {
|
if !self.ready_choices.is_empty() {
|
||||||
return self.ready_choices.pop_front();
|
return self.ready_choices.pop_front();
|
||||||
}
|
}
|
||||||
if let Some(choice) = self.wizard.input_with_menu(
|
|
||||||
query,
|
if self.wizard.string_menu.is_none() {
|
||||||
choices.iter().map(|s| s.to_string()).collect(),
|
self.wizard.string_menu = Some(Menu::new(
|
||||||
|
query,
|
||||||
|
choices.into_iter().map(|s| (s.to_string(), ())).collect(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((choice, _)) = input_with_menu(
|
||||||
|
&mut self.wizard.string_menu,
|
||||||
|
&mut self.wizard.alive,
|
||||||
self.input,
|
self.input,
|
||||||
) {
|
) {
|
||||||
self.wizard.state_choices.push(choice.clone());
|
self.wizard.state_choices.push(choice.clone());
|
||||||
@ -304,28 +280,51 @@ impl<'a> WrappedWizard<'a> {
|
|||||||
if !self.ready_choices.is_empty() {
|
if !self.ready_choices.is_empty() {
|
||||||
return self.ready_choices.pop_front();
|
return self.ready_choices.pop_front();
|
||||||
}
|
}
|
||||||
if self.wizard.polygons.is_none() {
|
|
||||||
self.wizard.polygons = Some(polygons::load_all_polygons(self.map.get_name()));
|
if self.wizard.polygon_menu.is_none() {
|
||||||
}
|
self.wizard.polygon_menu = Some(Menu::new(
|
||||||
let names = self
|
query,
|
||||||
.wizard
|
polygons::load_all_polygons(self.map.get_name()),
|
||||||
.polygons
|
));
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.keys()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
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 {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
// TODO Very weird to manage this coupled state like this...
|
|
||||||
if self.wizard.menu.is_none() {
|
|
||||||
self.wizard.polygons = None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
if let Some((name, _)) = input_with_menu(
|
||||||
|
&mut self.wizard.polygon_menu,
|
||||||
|
&mut self.wizard.alive,
|
||||||
|
self.input,
|
||||||
|
) {
|
||||||
|
self.wizard.state_choices.push(name.clone());
|
||||||
|
Some(name)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The caller initializes the menu, if needed. Pass in Option that must be Some().
|
||||||
|
// Bit weird to be a free function, but need to borrow a different menu and also the alive bit.
|
||||||
|
fn input_with_menu<T: Clone>(
|
||||||
|
menu: &mut Option<Menu<T>>,
|
||||||
|
alive: &mut bool,
|
||||||
|
input: &mut UserInput,
|
||||||
|
) -> Option<(String, T)> {
|
||||||
|
assert!(*alive);
|
||||||
|
|
||||||
|
// Otherwise, we try to use one event for two inputs potentially
|
||||||
|
if input.has_been_consumed() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
match menu.as_mut().unwrap().event(input) {
|
||||||
|
InputResult::Canceled => {
|
||||||
|
*menu = None;
|
||||||
|
*alive = false;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
InputResult::StillActive => None,
|
||||||
|
InputResult::Done(name, poly) => {
|
||||||
|
*menu = None;
|
||||||
|
Some((name, poly))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,21 +4,19 @@ use std;
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
// Named polygonal regions
|
// Named polygonal regions
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct PolygonSelection {
|
pub struct PolygonSelection {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub points: Vec<Pt2D>,
|
pub points: Vec<Pt2D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_all_polygons(map_name: &str) -> BTreeMap<String, PolygonSelection> {
|
pub fn load_all_polygons(map_name: &str) -> Vec<(String, PolygonSelection)> {
|
||||||
let mut results: BTreeMap<String, PolygonSelection> = BTreeMap::new();
|
let mut tree: BTreeMap<String, PolygonSelection> = BTreeMap::new();
|
||||||
for entry in std::fs::read_dir(format!("../data/polygons/{}/", map_name)).unwrap() {
|
for entry in std::fs::read_dir(format!("../data/polygons/{}/", map_name)).unwrap() {
|
||||||
let name = entry.unwrap().file_name().into_string().unwrap();
|
let name = entry.unwrap().file_name().into_string().unwrap();
|
||||||
let load: PolygonSelection =
|
let load: PolygonSelection =
|
||||||
abstutil::read_json(&format!("../data/polygons/{}/{}", map_name, name)).unwrap();
|
abstutil::read_json(&format!("../data/polygons/{}/{}", map_name, name)).unwrap();
|
||||||
results.insert(name, load);
|
tree.insert(name, load);
|
||||||
}
|
}
|
||||||
results
|
tree.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO maybe a wrapper type for the BTreeMap or a way to hook it up easily to a Menu
|
|
||||||
|
@ -220,8 +220,8 @@ fn line_to_array(l: &geom::Line) -> [f64; 4] {
|
|||||||
[l.pt1().x(), l.pt1().y(), l.pt2().x(), l.pt2().y()]
|
[l.pt1().x(), l.pt1().y(), l.pt2().x(), l.pt2().y()]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum InputResult {
|
pub enum InputResult<T: Clone> {
|
||||||
Canceled,
|
Canceled,
|
||||||
StillActive,
|
StillActive,
|
||||||
Done(String),
|
Done(String, T),
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
use piston::input::{Button, Key, PressEvent};
|
use piston::input::{Button, Key, PressEvent};
|
||||||
use {text, Canvas, GfxCtx, InputResult, TextOSD, UserInput};
|
use {text, Canvas, GfxCtx, InputResult, TextOSD, UserInput};
|
||||||
|
|
||||||
pub struct Menu {
|
// Stores some associated data with each choice
|
||||||
|
pub struct Menu<T: Clone> {
|
||||||
prompt: String,
|
prompt: String,
|
||||||
choices: Vec<String>,
|
choices: Vec<(String, T)>,
|
||||||
current_idx: usize,
|
current_idx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Menu {
|
impl<T: Clone> Menu<T> {
|
||||||
pub fn new(prompt: &str, choices: Vec<String>) -> Menu {
|
pub fn new(prompt: &str, choices: Vec<(String, T)>) -> Menu<T> {
|
||||||
Menu {
|
Menu {
|
||||||
prompt: prompt.to_string(),
|
prompt: prompt.to_string(),
|
||||||
choices,
|
choices,
|
||||||
@ -16,7 +17,7 @@ impl Menu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event(&mut self, input: &mut UserInput) -> InputResult {
|
pub fn event(&mut self, input: &mut UserInput) -> InputResult<T> {
|
||||||
let ev = input.use_event_directly().clone();
|
let ev = input.use_event_directly().clone();
|
||||||
input.consume_event();
|
input.consume_event();
|
||||||
|
|
||||||
@ -25,7 +26,10 @@ impl Menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Button::Keyboard(Key::Return)) = ev.press_args() {
|
if let Some(Button::Keyboard(Key::Return)) = ev.press_args() {
|
||||||
return InputResult::Done(self.choices[self.current_idx].clone());
|
// TODO instead of requiring clone, we could drain choices to take ownership of the
|
||||||
|
// item. but without consuming self here, it's a bit sketchy to do that.
|
||||||
|
let (name, item) = self.choices[self.current_idx].clone();
|
||||||
|
return InputResult::Done(name, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Button::Keyboard(Key::Up)) = ev.press_args() {
|
if let Some(Button::Keyboard(Key::Up)) = ev.press_args() {
|
||||||
@ -79,7 +83,7 @@ impl Menu {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (idx, line) in self.choices.iter().enumerate() {
|
for (idx, (line, _)) in self.choices.iter().enumerate() {
|
||||||
if idx < low_idx || idx > low_idx + can_fit {
|
if idx < low_idx || idx > low_idx + can_fit {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -97,7 +101,7 @@ impl Menu {
|
|||||||
canvas.draw_centered_text(g, osd);
|
canvas.draw_centered_text(g, osd);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_choice(&self) -> &String {
|
pub fn current_choice(&self) -> &T {
|
||||||
&self.choices[self.current_idx]
|
&self.choices[self.current_idx].1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ impl TextBox {
|
|||||||
canvas.draw_centered_text(g, osd);
|
canvas.draw_centered_text(g, osd);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event(&mut self, input: &mut UserInput) -> InputResult {
|
pub fn event(&mut self, input: &mut UserInput) -> InputResult<()> {
|
||||||
let ev = input.use_event_directly().clone();
|
let ev = input.use_event_directly().clone();
|
||||||
input.consume_event();
|
input.consume_event();
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ impl TextBox {
|
|||||||
|
|
||||||
// Done?
|
// Done?
|
||||||
if let Some(Button::Keyboard(Key::Return)) = ev.press_args() {
|
if let Some(Button::Keyboard(Key::Return)) = ev.press_args() {
|
||||||
return InputResult::Done(self.line.clone());
|
return InputResult::Done(self.line.clone(), ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key state tracking
|
// Key state tracking
|
||||||
|
Loading…
Reference in New Issue
Block a user